[gtkmm-documentation] Replace signal_key_press_event() by Gtk::EventControllerKey



commit dbdbd2aba16ffbdc14986142f474337e3604e199
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Tue May 29 10:04:57 2018 +0200

    Replace signal_key_press_event() by Gtk::EventControllerKey

 .../keyboard_events/propagation/examplewindow.cc   | 69 ++++++++++++++--------
 .../keyboard_events/propagation/examplewindow.h    | 13 ++--
 .../book/keyboard_events/simple/examplewindow.cc   | 21 ++++---
 .../book/keyboard_events/simple/examplewindow.h    |  4 +-
 examples/book/menus/popup/examplewindow.cc         |  3 +-
 examples/book/searchbar/examplewindow.cc           | 16 +++--
 examples/book/searchbar/examplewindow.h            |  2 +-
 .../others/cellrenderercustom/cellrendererlist.cc  |  3 +-
 .../others/cellrenderercustom/cellrendererpopup.cc | 14 +++--
 .../others/cellrenderercustom/cellrendererpopup.h  |  2 +-
 examples/others/cellrenderercustom/popupentry.cc   | 33 +++++++----
 examples/others/cellrenderercustom/popupentry.h    |  4 +-
 12 files changed, 116 insertions(+), 68 deletions(-)
---
diff --git a/examples/book/keyboard_events/propagation/examplewindow.cc 
b/examples/book/keyboard_events/propagation/examplewindow.cc
index d2635ac..1fd0adf 100644
--- a/examples/book/keyboard_events/propagation/examplewindow.cc
+++ b/examples/book/keyboard_events/propagation/examplewindow.cc
@@ -14,6 +14,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+//TODO: This example does not work as intended in gtkmm4. The propagation of
+// event signal works differently in gtk+3 and gtk+4. GtkEntry in gtk+4 marks
+// a key press signal as handled. It's not propagated further up to the Grid
+// and the Window.
+
 #include "examplewindow.h"
 #include <iostream>
 
@@ -34,23 +39,41 @@ ExampleWindow::ExampleWindow()
   m_container.add(m_checkbutton_can_propagate);
 
   // Events
-  m_entry.signal_key_release_event().connect(
-    sigc::mem_fun(*this, &ExampleWindow::entryKeyRelease), true);
-
-  m_container.signal_key_release_event().connect(
-    sigc::mem_fun(*this, &ExampleWindow::gridKeyRelease), true);
-
-  // 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), true);
+  auto controller = Gtk::EventControllerKey::create();
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &ExampleWindow::entry_key_pressed), true);
+  m_entry.add_controller(controller);
+
+  controller = Gtk::EventControllerKey::create();
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &ExampleWindow::grid_key_pressed), true);
+  m_container.add_controller(controller);
+
+  // Called in the capture phase of the event handling.
+  controller = Gtk::EventControllerKey::create();
+  controller->set_propagation_phase(Gtk::PropagationPhase::CAPTURE);
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &ExampleWindow::window_key_pressed_capture), false);
+  add_controller(controller);
+
+  // Called in the target phase of the event handling.
+  controller = Gtk::EventControllerKey::create();
+  controller->set_propagation_phase(Gtk::PropagationPhase::TARGET);
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &ExampleWindow::window_key_pressed_target), false);
+  add_controller(controller);
+
+  // Called in the bubble phase of the event handling.
+  // This is the default, if set_propagation_phase() is not called.
+  controller = Gtk::EventControllerKey::create();
+  controller->set_propagation_phase(Gtk::PropagationPhase::BUBBLE);
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &ExampleWindow::window_key_pressed_bubble), true);
+  add_controller(controller);
 }
 
 //By changing the return value we allow, or don't allow, the event to propagate to other elements.
-bool ExampleWindow::entryKeyRelease(const Glib::RefPtr<Gdk::EventKey>& /* event */ )
+bool ExampleWindow::entry_key_pressed(guint, guint, Gdk::ModifierType)
 {
   std::cout << "Entry" << std::endl;
 
@@ -62,7 +85,7 @@ bool ExampleWindow::entryKeyRelease(const Glib::RefPtr<Gdk::EventKey>& /* event
   return true;
 }
 
-bool ExampleWindow::gridKeyRelease(const Glib::RefPtr<Gdk::EventKey>& /* event */ )
+bool ExampleWindow::grid_key_pressed(guint, guint, Gdk::ModifierType)
 {
   std::cout << "Grid" << std::endl;
 
@@ -70,24 +93,22 @@ bool ExampleWindow::gridKeyRelease(const Glib::RefPtr<Gdk::EventKey>& /* event *
   return false;
 }
 
-bool ExampleWindow::windowKeyReleaseBefore(const Glib::RefPtr<Gdk::EventKey>& /* event */ )
+bool ExampleWindow::window_key_pressed_capture(guint, guint, Gdk::ModifierType)
 {
-  std::cout << "Window before" << std::endl;
+  std::cout << "Window, capture phase" << std::endl;
   return false;
 }
 
-bool ExampleWindow::on_key_release_event(const Glib::RefPtr<Gdk::EventKey>& key_event)
+bool ExampleWindow::window_key_pressed_target(guint, guint, Gdk::ModifierType)
 {
-  std::cout << "Window overridden" << std::endl;
-
-  // call base class function (to get the normal behaviour)
-  return Gtk::Window::on_key_release_event(key_event);
+  std::cout << "Window, target phase" << std::endl;
+  return false;
 }
 
 // This will set the entry's text in the label, every time a key is pressed.
-bool ExampleWindow::windowKeyRelease(const Glib::RefPtr<Gdk::EventKey>& /* event */ )
+bool ExampleWindow::window_key_pressed_bubble(guint, guint, Gdk::ModifierType)
 {
-  std::cout << "Window after";
+  std::cout << "Window, bubble phase";
 
   //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 m_checkbutton_can_propagate wasn't active
diff --git a/examples/book/keyboard_events/propagation/examplewindow.h 
b/examples/book/keyboard_events/propagation/examplewindow.h
index 29f36f5..faee06b 100644
--- a/examples/book/keyboard_events/propagation/examplewindow.h
+++ b/examples/book/keyboard_events/propagation/examplewindow.h
@@ -27,13 +27,12 @@ public:
   virtual ~ExampleWindow();
 
 private:
-  //Override default signal handler:
-  bool on_key_release_event(const Glib::RefPtr<Gdk::EventKey>& event) override;
-
-  bool entryKeyRelease(const Glib::RefPtr<Gdk::EventKey>& event);
-  bool gridKeyRelease(const Glib::RefPtr<Gdk::EventKey>& event);
-  bool windowKeyReleaseBefore(const Glib::RefPtr<Gdk::EventKey>& event);
-  bool windowKeyRelease(const Glib::RefPtr<Gdk::EventKey>& event);
+  // Signal handlers:
+  bool entry_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state);
+  bool grid_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state);
+  bool window_key_pressed_capture(guint keyval, guint keycode, Gdk::ModifierType state);
+  bool window_key_pressed_target(guint keyval, guint keycode, Gdk::ModifierType state);
+  bool window_key_pressed_bubble(guint keyval, guint keycode, Gdk::ModifierType state);
 
   Gtk::Grid m_container;
 
diff --git a/examples/book/keyboard_events/simple/examplewindow.cc 
b/examples/book/keyboard_events/simple/examplewindow.cc
index 06421fb..4819bc4 100644
--- a/examples/book/keyboard_events/simple/examplewindow.cc
+++ b/examples/book/keyboard_events/simple/examplewindow.cc
@@ -34,39 +34,42 @@ ExampleWindow::ExampleWindow()
   m_container.add(m_second);
 
   // Events.
-  // We override the default event signal handler.
+  auto controller = Gtk::EventControllerKey::create();
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &ExampleWindow::on_window_key_pressed), false);
+  add_controller(controller);
 }
 
-bool ExampleWindow::on_key_press_event(const Glib::RefPtr<Gdk::EventKey>& key_event)
+bool ExampleWindow::on_window_key_pressed(guint keyval, guint, Gdk::ModifierType state)
 {
   //Gdk::ModifierType::MOD1_MASK -> the 'Alt' key(mask)
   //GDK_KEY_1 -> the '1' key
   //GDK_KEY_2 -> the '2' key
 
   //select the first radio button, when we press alt + 1
-  if((key_event->get_keyval() == GDK_KEY_1) &&
-    (key_event->get_state() & (Gdk::ModifierType::SHIFT_MASK | Gdk::ModifierType::CONTROL_MASK | 
Gdk::ModifierType::MOD1_MASK)) == Gdk::ModifierType::MOD1_MASK)
+  if((keyval == GDK_KEY_1) &&
+    (state & (Gdk::ModifierType::SHIFT_MASK | Gdk::ModifierType::CONTROL_MASK | 
Gdk::ModifierType::MOD1_MASK)) == Gdk::ModifierType::MOD1_MASK)
   {
     m_first.set_active();
     //returning true, cancels the propagation of the event
     return true;
   }
-  else if((key_event->get_keyval() == GDK_KEY_2) &&
-    (key_event->get_state() & (Gdk::ModifierType::SHIFT_MASK | Gdk::ModifierType::CONTROL_MASK | 
Gdk::ModifierType::MOD1_MASK)) == Gdk::ModifierType::MOD1_MASK)
+  else if((keyval == GDK_KEY_2) &&
+    (state & (Gdk::ModifierType::SHIFT_MASK | Gdk::ModifierType::CONTROL_MASK | 
Gdk::ModifierType::MOD1_MASK)) == Gdk::ModifierType::MOD1_MASK)
   {
     //and the second radio button, when we press alt + 2
     m_second.set_active();
     return true;
   }
-  else if(key_event->get_keyval() == GDK_KEY_Escape)
+  else if(keyval == GDK_KEY_Escape)
   {
     //close the window, when the 'esc' key is pressed
     hide();
     return true;
   }
 
-  //if the event has not been handled, call the base class
-  return Gtk::Window::on_key_press_event(key_event);
+  //the event has not been handled
+  return false;
 }
 
 ExampleWindow::~ExampleWindow()
diff --git a/examples/book/keyboard_events/simple/examplewindow.h 
b/examples/book/keyboard_events/simple/examplewindow.h
index cb62c94..be04fa0 100644
--- a/examples/book/keyboard_events/simple/examplewindow.h
+++ b/examples/book/keyboard_events/simple/examplewindow.h
@@ -27,8 +27,8 @@ public:
   virtual ~ExampleWindow();
 
 private:
-  //Override default signal handler:
-  bool on_key_press_event(const Glib::RefPtr<Gdk::EventKey>& event) override;
+  // Signal handler:
+  bool on_window_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state);
 
   Gtk::Grid m_container;
   Gtk::RadioButton m_first;
diff --git a/examples/book/menus/popup/examplewindow.cc b/examples/book/menus/popup/examplewindow.cc
index cf10294..676e3ff 100644
--- a/examples/book/menus/popup/examplewindow.cc
+++ b/examples/book/menus/popup/examplewindow.cc
@@ -29,10 +29,11 @@ ExampleWindow::ExampleWindow()
 
   // Catch button_press events:
   m_Box.pack_start(m_Label, Gtk::PackOptions::EXPAND_WIDGET);
-  m_refGesture = Gtk::GestureMultiPress::create(m_Label);
+  m_refGesture = Gtk::GestureMultiPress::create();
   m_refGesture->set_button(GDK_BUTTON_SECONDARY);
   m_refGesture->signal_pressed().connect(
     sigc::mem_fun(*this, &ExampleWindow::on_label_pressed));
+  m_Label.add_controller(m_refGesture);
 
   //Create actions:
 
diff --git a/examples/book/searchbar/examplewindow.cc b/examples/book/searchbar/examplewindow.cc
index 3dd970a..721aa88 100644
--- a/examples/book/searchbar/examplewindow.cc
+++ b/examples/book/searchbar/examplewindow.cc
@@ -35,8 +35,12 @@ ExampleWindow::ExampleWindow()
   m_search_bar.connect_entry(m_entry);
 
   // Connect signals
-  signal_key_press_event().connect(sigc::mem_fun(*this, &ExampleWindow::on_window_key_press), true);
-  m_search_bar.property_search_mode_enabled().signal_changed().connect(sigc::mem_fun(*this, 
&ExampleWindow::on_search_bar_reveal_changed));
+  auto controller = Gtk::EventControllerKey::create();
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &ExampleWindow::on_window_key_pressed), true);
+  add_controller(controller);
+  m_search_bar.property_search_mode_enabled().signal_changed().connect(
+    sigc::mem_fun(*this, &ExampleWindow::on_search_bar_reveal_changed));
 
   // Switches
   m_search_mode_switch.set_active(false);
@@ -85,9 +89,13 @@ ExampleWindow::~ExampleWindow()
 {
 }
 
-bool ExampleWindow::on_window_key_press(const Glib::RefPtr<Gdk::EventKey>& key_event)
+bool ExampleWindow::on_window_key_pressed(guint, guint, Gdk::ModifierType)
 {
-  return m_search_bar.handle_event(key_event);
+  Glib::RefPtr<Gdk::Event> current_event = Glib::wrap(gtk_get_current_event());
+  if (current_event->get_event_type() == Gdk::Event::Type::KEY_PRESS)
+    return m_search_bar.handle_event(std::static_pointer_cast<Gdk::EventKey>(current_event));
+  else
+    return false;
 }
 
 void ExampleWindow::on_search_bar_reveal_changed()
diff --git a/examples/book/searchbar/examplewindow.h b/examples/book/searchbar/examplewindow.h
index 4dcb9db..57ab244 100644
--- a/examples/book/searchbar/examplewindow.h
+++ b/examples/book/searchbar/examplewindow.h
@@ -27,7 +27,7 @@ public:
 
 private:
   // Slots
-  bool on_window_key_press(const Glib::RefPtr<Gdk::EventKey>& key_event);
+  bool on_window_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state);
   void on_search_mode_changed();
   void on_show_close_button_changed();
   void on_search_bar_reveal_changed();
diff --git a/examples/others/cellrenderercustom/cellrendererlist.cc 
b/examples/others/cellrenderercustom/cellrendererlist.cc
index 8d025ae..b0d26de 100644
--- a/examples/others/cellrenderercustom/cellrendererlist.cc
+++ b/examples/others/cellrenderercustom/cellrendererlist.cc
@@ -47,10 +47,11 @@ CellRendererList::CellRendererList()
   tree_view_.set_headers_visible(false);
   tree_view_.append_column("", popup_columns().item);
 
-  gesture_ = Gtk::GestureMultiPress::create(tree_view_);
+  gesture_ = Gtk::GestureMultiPress::create();
   gesture_->set_button(GDK_BUTTON_PRIMARY);
   gesture_->signal_released().connect(
     sigc::mem_fun(*this, &Self::on_tree_view_released));
+  tree_view_.add_controller(gesture_);
 
   const auto selection = tree_view_.get_selection();
   selection->set_mode(Gtk::SelectionMode::BROWSE);
diff --git a/examples/others/cellrenderercustom/cellrendererpopup.cc 
b/examples/others/cellrenderercustom/cellrendererpopup.cc
index 71f9db4..7aeff40 100644
--- a/examples/others/cellrenderercustom/cellrendererpopup.cc
+++ b/examples/others/cellrenderercustom/cellrendererpopup.cc
@@ -55,11 +55,17 @@ CellRendererPopup::CellRendererPopup()
   signal_show_popup_.connect(sigc::mem_fun(*this, &Self::on_show_popup));
   signal_hide_popup_.connect(sigc::mem_fun(*this, &Self::on_hide_popup));
 
-  gesture_ = Gtk::GestureMultiPress::create(popup_window_);
+  gesture_ = Gtk::GestureMultiPress::create();
   gesture_->set_button(GDK_BUTTON_PRIMARY);
   gesture_->signal_pressed().connect(
     sigc::mem_fun(*this, &Self::on_popup_window_pressed));
-  popup_window_.signal_key_press_event().connect(sigc::mem_fun(*this, &Self::on_key_press_event), true);
+  popup_window_.add_controller(gesture_);
+
+  auto controller = Gtk::EventControllerKey::create();
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &Self::on_popup_window_key_pressed), true);
+  popup_window_.add_controller(controller);
+
   popup_window_.signal_style_updated().connect(sigc::mem_fun(*this, &Self::on_style_updated));
 }
 
@@ -262,9 +268,9 @@ void CellRendererPopup::on_popup_window_pressed(int /* n_press */, double /* x *
   signal_hide_popup_();
 }
 
-bool CellRendererPopup::on_key_press_event(const Glib::RefPtr<Gdk::EventKey>& event)
+bool CellRendererPopup::on_popup_window_key_pressed(guint keyval, guint, Gdk::ModifierType)
 {
-  switch (event->get_keyval())
+  switch (keyval)
   {
     case GDK_KEY_Escape:
       editing_canceled_ = true; break;
diff --git a/examples/others/cellrenderercustom/cellrendererpopup.h 
b/examples/others/cellrenderercustom/cellrendererpopup.h
index ef914e2..4b1dc63 100644
--- a/examples/others/cellrenderercustom/cellrendererpopup.h
+++ b/examples/others/cellrenderercustom/cellrendererpopup.h
@@ -72,7 +72,7 @@ private:
   Glib::RefPtr<Gtk::GestureMultiPress> gesture_;
 
   void on_popup_window_pressed(int n_press, double x, double y);
-  bool on_key_press_event(const Glib::RefPtr<Gdk::EventKey>& event);
+  bool on_popup_window_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state);
   void on_style_updated();
 
   void on_popup_editing_done();
diff --git a/examples/others/cellrenderercustom/popupentry.cc 
b/examples/others/cellrenderercustom/popupentry.cc
index 53a0c28..800d57e 100644
--- a/examples/others/cellrenderercustom/popupentry.cc
+++ b/examples/others/cellrenderercustom/popupentry.cc
@@ -38,6 +38,11 @@ PopupEntry::PopupEntry(const Glib::ustring& path)
   button_->set_image_from_icon_name("pan-down-symbolic", Gtk::IconSize::INHERIT, true);
 
   set_can_focus();
+
+  auto controller = Gtk::EventControllerKey::create();
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &Self::on_popup_key_pressed), false);
+  add_controller(controller);
 }
 
 PopupEntry::~PopupEntry()
@@ -93,9 +98,9 @@ PopupEntry::type_signal_arrow_clicked& PopupEntry::signal_arrow_clicked()
   return signal_arrow_clicked_;
 }
 
-bool PopupEntry::on_key_press_event(const Glib::RefPtr<Gdk::EventKey>& key_event)
+bool PopupEntry::on_popup_key_pressed(guint keyval, guint, Gdk::ModifierType)
 {
-  if (key_event->get_keyval() == GDK_KEY_Escape)
+  if (keyval == GDK_KEY_Escape)
   {
     editing_canceled_ = true;
 
@@ -112,22 +117,22 @@ bool PopupEntry::on_key_press_event(const Glib::RefPtr<Gdk::EventKey>& key_event
 /*
  * Can't do this now (2017-10-06).
  * GdkEvent and its subclasses are now opaque structures. We can't directly
- * access their data. There is a gdk_event_get_window() to get the window,
- * but there is no gdk_event_set_window() to set a window.
+ * access their data. There is a gdk_event_get_surface() to get the GDK surface,
+ * but there is no gdk_event_set_surface() to set a surface.
 
   Gdk::EventKey synth_event(key_event);
 
   GdkEventKey* const synth_event_gobj = synth_event.gobj();
   if (synth_event_gobj->window)
-    g_object_unref(synth_event_gobj->window);
-  synth_event_gobj->window = Glib::unwrap(entry_->get_window());
-  if (synth_event_gobj->window)
-    g_object_ref(synth_event_gobj->window);
+    g_object_unref(synth_event_gobj->surface);
+  synth_event_gobj->surface = Glib::unwrap(entry_->get_surface());
+  if (synth_event_gobj->surface)
+    g_object_ref(synth_event_gobj->surface);
   synth_event_gobj->send_event = true;
 
   entry_->event(synth_event);
 */
-  return Gtk::Box::on_key_press_event(key_event);
+  return false;
 }
 
 void PopupEntry::start_editing_vfunc(const Glib::RefPtr<const Gdk::Event>&)
@@ -136,7 +141,11 @@ void PopupEntry::start_editing_vfunc(const Glib::RefPtr<const Gdk::Event>&)
 
   // Although this is a key-binding signal, it's acceptable to use it in applications.
   entry_->signal_activate().connect(sigc::mem_fun(*this, &Self::on_entry_activate));
-  entry_->signal_key_press_event().connect(sigc::mem_fun(*this, &Self::on_entry_key_press_event), false);
+
+  auto controller = Gtk::EventControllerKey::create();
+  controller->signal_key_pressed().connect(
+    sigc::mem_fun(*this, &Self::on_entry_key_pressed), false);
+  entry_->add_controller(controller);
 
   //TODO: Doesn't this mean that we have multiple connection, because this is never disconnected?
   button_->signal_clicked().connect(sigc::mem_fun(*this, &Self::on_button_clicked));
@@ -153,9 +162,9 @@ void PopupEntry::on_entry_activate()
   //remove_widget(); // TODO: this line causes the widget to be removed twice -- dunno why
 }
 
-bool PopupEntry::on_entry_key_press_event(const Glib::RefPtr<Gdk::EventKey>& key_event)
+bool PopupEntry::on_entry_key_pressed(guint keyval, guint, Gdk::ModifierType)
 {
-  if (key_event->get_keyval() == GDK_KEY_Escape)
+  if (keyval == GDK_KEY_Escape)
   {
     editing_canceled_ = true;
 
diff --git a/examples/others/cellrenderercustom/popupentry.h b/examples/others/cellrenderercustom/popupentry.h
index db6daa4..3be480e 100644
--- a/examples/others/cellrenderercustom/popupentry.h
+++ b/examples/others/cellrenderercustom/popupentry.h
@@ -42,14 +42,14 @@ public:
   type_signal_arrow_clicked& signal_arrow_clicked();
 
 protected:
-  bool on_key_press_event(const Glib::RefPtr<Gdk::EventKey>& key_event) override;
+  bool on_popup_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state);
   void start_editing_vfunc(const Glib::RefPtr<const Gdk::Event>& event) override;
 
 private:
   typedef PopupEntry Self;
 
   void on_entry_activate();
-  bool on_entry_key_press_event(const Glib::RefPtr<Gdk::EventKey>& event);
+  bool on_entry_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state);
   void on_button_clicked();
 
   Glib::ustring path_;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]