[gtkmm-documentation] Keyboard Events chapter: Clarify keyboard event propagation.
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm-documentation] Keyboard Events chapter: Clarify keyboard event propagation.
- Date: Mon, 30 Jan 2012 17:53:09 +0000 (UTC)
commit d0816681199ea195da2f899f7eb714367937a503
Author: Pedro Ferreira <darkiiiiii gmail com>
Date: Mon Jan 30 18:45:31 2012 +0100
Keyboard Events chapter: Clarify keyboard event propagation.
* docs/tutorial/C/gtkmm-tutorial-in.xml: Mention that keyboard events are
first tested for keyboard shortcut keys.
* examples/book/keyboard_events/simple/keyboard_events.[h|cc]:
on_key_press_event() is an overridden default handler. Don't call connect().
* examples/book/keyboard_events/propagation/event_propagation.[h|cc]:
Add on_key_release_event() and windowKeyReleaseBefore().
Bug #661857, comment 22.
ChangeLog | 12 +++++++
docs/tutorial/C/gtkmm-tutorial-in.xml | 32 ++++++++++++++++++--
.../keyboard_events/propagation/examplewindow.cc | 26 +++++++++++++++-
.../keyboard_events/propagation/examplewindow.h | 12 ++++----
.../book/keyboard_events/simple/examplewindow.cc | 16 +++++----
.../book/keyboard_events/simple/examplewindow.h | 5 +--
6 files changed, 82 insertions(+), 21 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8ee63c5..02b24e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2012-01-30 Pedro Ferreira <darkiiiiii gmail com>
+ Keyboard Events chapter: Clarify keyboard event propagation.
+
+ * docs/tutorial/C/gtkmm-tutorial-in.xml: Mention that keyboard events are
+ first tested for keyboard shortcut keys.
+ * examples/book/keyboard_events/simple/keyboard_events.[h|cc]:
+ on_key_press_event() is an overridden default handler. Don't call connect().
+ * examples/book/keyboard_events/propagation/event_propagation.[h|cc]:
+ Add on_key_release_event() and windowKeyReleaseBefore().
+ Bug #661857, comment 22.
+
+2012-01-30 Pedro Ferreira <darkiiiiii gmail com>
+
New example programs in the DrawingArea chapter.
* docs/tutorial/C/gtkmm-tutorial-in.xml: Add a section on drawing thin lines.
diff --git a/docs/tutorial/C/gtkmm-tutorial-in.xml b/docs/tutorial/C/gtkmm-tutorial-in.xml
index 30490bf..ee281fd 100644
--- a/docs/tutorial/C/gtkmm-tutorial-in.xml
+++ b/docs/tutorial/C/gtkmm-tutorial-in.xml
@@ -5737,6 +5737,9 @@ m_entry.add_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);
<keycap>Alt</keycap>+<keycap>1</keycap> selects the first radio button,
<keycap>Alt</keycap>+<keycap>2</keycap> selects the second one, and the
<keycap>Esc</keycap> key hides (closes) the window.
+ The default event signal handler is overridden, as described in the
+ <link linkend="sec-overriding-default-signal-handlers">Overriding default signal handlers</link>
+ section in the appendix.
</para>
<figure id="figure-keyboardevents-simple">
@@ -5759,6 +5762,14 @@ m_entry.add_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);
that handler will be called.
</para>
<para>
+ Contrary to other events, keyboard events are first sent to the toplevel window
+ (<classname>Gtk::Window</classname>), where it will be checked
+ for any keyboard shortcuts that may be set (accelerator keys and mnemonics,
+ used for selecting menu items from the keyboard). After this (and assuming
+ the event wasn't handled), it is sent to the widget which has focus,
+ and the propagation begins from there.
+ </para>
+ <para>
The event will propagate until it reaches the top-level widget, or until
you stop the propagation by returning <literal>true</literal> from an
event handler.
@@ -5771,13 +5782,28 @@ m_entry.add_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);
<sect2 id="keyboardevents-propagation-example">
<title>Example</title>
<para>
- In this example there are three event handlers, one in the
+ In this example there are three event handlers that are called after
+ <classname>Gtk::Window</classname>'s default event handler, one in the
<classname>Gtk::Entry</classname>, one in the <classname>Gtk::Grid</classname>
and one in the <classname>Gtk::Window</classname>.
</para>
<para>
- When you write in the entry, a key release event will be emitted first
- in the <classname>Entry</classname> and, depending on whether we let
+ In the <classname>Gtk::Window</classname>, we have also the default handler
+ overridden (<methodname>on_key_release_event()</methodname>), and
+ another handler being called before the default handler
+ (<methodname>windowKeyReleaseBefore()</methodname>).
+ </para>
+ <para>
+ The purpose of this example is to show the steps the event takes when it is emitted.
+ </para>
+ <para>
+ When you write in the entry, a key release event will be emitted,
+ which will go first to the toplevel window (<classname>Gtk::Window</classname>),
+ since we have one event handler set to be called before, that's what is
+ called first (<methodname>windowKeyReleaseBefore()</methodname>).
+ Then the default handler is called (which we have overridden), and after
+ that the event is sent to the widget that has focus,
+ the <classname>Entry</classname> in our example and, depending on whether we let
it propagate, it can reach the <classname>Grid</classname>'s and the
<classname>Window</classname>'s event handlers. If it propagates,
the text you're writing will appear in the <classname>Label</classname>
diff --git a/examples/book/keyboard_events/propagation/examplewindow.cc b/examples/book/keyboard_events/propagation/examplewindow.cc
index 8e7d201..3ea7745 100644
--- a/examples/book/keyboard_events/propagation/examplewindow.cc
+++ b/examples/book/keyboard_events/propagation/examplewindow.cc
@@ -15,6 +15,7 @@
*/
#include "examplewindow.h"
+#include <iostream>
ExampleWindow::ExampleWindow()
{
@@ -41,6 +42,11 @@ ExampleWindow::ExampleWindow()
m_container.signal_key_release_event().connect(
sigc::mem_fun(*this, &ExampleWindow::gridKeyRelease));
+ // Called before the default event signal handler.
+ signal_key_release_event().connect(
+ sigc::mem_fun(*this, &ExampleWindow::windowKeyReleaseBefore), false);
+
+ // Called after the default event signal handler.
signal_key_release_event().connect(
sigc::mem_fun(*this, &ExampleWindow::windowKeyRelease));
@@ -68,17 +74,33 @@ bool ExampleWindow::gridKeyRelease(GdkEventKey* /* event */ )
return false;
}
+bool ExampleWindow::windowKeyReleaseBefore(GdkEventKey* /* event */ )
+{
+ std::cout << "Window before" << std::endl;
+ return false;
+}
+
+bool ExampleWindow::on_key_release_event(GdkEventKey* event)
+{
+ std::cout << "Window overridden" << std::endl;
+
+ // call base class function (to get the normal behaviour)
+ return Gtk::Window::on_key_release_event(event);
+}
+
// This will set the entry's text in the label, every time a key is pressed.
bool ExampleWindow::windowKeyRelease(GdkEventKey* /* event */ )
{
- std::cout << "Window" << std::endl;
+ std::cout << "Window after";
//checking if the entry is on focus, otherwise the label would get changed by pressing keys
- //on the window (when the entry is not on focus), even if canPropagate wasn't active
+ //on the window (when the entry is not on focus), even if m_checkbutton_can_propagate wasn't active
if(m_entry.has_focus())
{
m_label.set_text(m_entry.get_text());
+ std::cout << ", " << m_entry.get_text();
}
+ std::cout << std::endl;
return true;
}
diff --git a/examples/book/keyboard_events/propagation/examplewindow.h b/examples/book/keyboard_events/propagation/examplewindow.h
index 7fe0cde..1e617cc 100644
--- a/examples/book/keyboard_events/propagation/examplewindow.h
+++ b/examples/book/keyboard_events/propagation/examplewindow.h
@@ -18,7 +18,6 @@
#define GTKMM_EVENT_PROPAGATION_H
#include <gtkmm.h>
-#include <iostream>
class ExampleWindow : public Gtk::Window
{
@@ -27,12 +26,14 @@ public:
ExampleWindow();
virtual ~ExampleWindow();
-
private:
+ //Override default signal handler:
+ virtual bool on_key_release_event(GdkEventKey* event);
- bool entryKeyRelease(GdkEventKey *event);
- bool gridKeyRelease(GdkEventKey *event);
- bool windowKeyRelease(GdkEventKey *event);
+ bool entryKeyRelease(GdkEventKey* event);
+ bool gridKeyRelease(GdkEventKey* event);
+ bool windowKeyReleaseBefore(GdkEventKey* event);
+ bool windowKeyRelease(GdkEventKey* event);
Gtk::Grid m_container;
@@ -41,5 +42,4 @@ private:
Gtk::CheckButton m_checkbutton_can_propagate;
};
-
#endif //GTKMM_EVENT_PROPAGATION_H
diff --git a/examples/book/keyboard_events/simple/examplewindow.cc b/examples/book/keyboard_events/simple/examplewindow.cc
index 0b60e69..06748aa 100644
--- a/examples/book/keyboard_events/simple/examplewindow.cc
+++ b/examples/book/keyboard_events/simple/examplewindow.cc
@@ -34,15 +34,14 @@ ExampleWindow::ExampleWindow()
m_container.add(m_first);
m_container.add(m_second);
- // Events
+ // Events.
+ // We override the default event signal handler.
add_events(Gdk::KEY_PRESS_MASK);
- signal_key_press_event().connect(sigc::mem_fun(*this,
- &ExampleWindow::on_key_press_event));
show_all_children();
}
-bool ExampleWindow::on_key_press_event(GdkEventKey *event)
+bool ExampleWindow::on_key_press_event(GdkEventKey* event)
{
//GDK_MOD1_MASK -> the 'alt' key(mask)
//GDK_KEY_1 -> the '1' key
@@ -53,24 +52,27 @@ bool ExampleWindow::on_key_press_event(GdkEventKey *event)
(event->state &(GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == GDK_MOD1_MASK)
{
m_first.set_active();
+ //returning true, cancels the propagation of the event
+ return true;
}
else if((event->keyval == GDK_KEY_2) &&
(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == GDK_MOD1_MASK)
{
//and the second radio button, when we press alt + 2
m_second.set_active();
+ return true;
}
else if(event->keyval == GDK_KEY_Escape)
{
//close the window, when the 'esc' key is pressed
hide();
+ return true;
}
- //returning true, cancels the propagation of the event
- return true;
+ //if the event has not been handled, call the base class
+ return Gtk::Window::on_key_press_event(event);
}
-
ExampleWindow::~ExampleWindow()
{
}
diff --git a/examples/book/keyboard_events/simple/examplewindow.h b/examples/book/keyboard_events/simple/examplewindow.h
index 3a40c79..31ea0e3 100644
--- a/examples/book/keyboard_events/simple/examplewindow.h
+++ b/examples/book/keyboard_events/simple/examplewindow.h
@@ -19,7 +19,6 @@
#include <gtkmm.h>
-
class ExampleWindow : public Gtk::Window
{
public:
@@ -28,12 +27,12 @@ public:
virtual ~ExampleWindow();
private:
- bool on_key_press_event(GdkEventKey *event);
+ //Override default signal handler:
+ virtual bool on_key_press_event(GdkEventKey* event);
Gtk::Grid m_container;
Gtk::RadioButton m_first;
Gtk::RadioButton m_second;
};
-
#endif //GTKMM_EXAMPLEWINDOW_H
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]