[gnome-software] Support the mouse back button (and Alt+Left)



commit 6e265aff8c2d450a7b2ab1765c41c753fca9edb0
Author: Rafal Luzynski <digitalfreak lingonborough com>
Date:   Tue Aug 25 01:24:28 2015 +0200

    Support the mouse back button (and Alt+Left)
    
    Some mice have a hardware back button which should act as a shortcut
    for the Back button. This patch also adds Alt+Left (Alt+Right for
    RTL locales) keyboard shortcut for the Back button where it has
    been missing, that is in Sources and Updates dialogs. A similar
    feature in gs-shell.c has been pushed as commit b1e180b.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=747227

 src/gs-shell.c          |   21 ++++++++++++++++++++
 src/gs-sources-dialog.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++
 src/gs-update-dialog.c  |   49 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+), 0 deletions(-)
---
diff --git a/src/gs-shell.c b/src/gs-shell.c
index a724e8b..298bb88 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -472,6 +472,24 @@ window_key_press_event (GtkWidget *win, GdkEventKey *event, GsShell *shell)
 }
 
 static gboolean
+window_button_press_event (GtkWidget *win, GdkEventButton *event, GsShell *shell)
+{
+       GsShellPrivate *priv = shell->priv;
+       GtkWidget *button;
+
+       /* Mouse hardware back button is 8 */
+       if (event->button != 8)
+               return GDK_EVENT_PROPAGATE;
+
+       button = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_back"));
+       if (!gtk_widget_is_visible (button) || !gtk_widget_is_sensitive (button))
+               return GDK_EVENT_PROPAGATE;
+
+       gtk_widget_activate (button);
+       return GDK_EVENT_STOP;
+}
+
+static gboolean
 main_window_closed_cb (GtkWidget *dialog, GdkEvent *event, gpointer user_data)
 {
        GsShell *shell = user_data;
@@ -581,6 +599,9 @@ gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *can
        /* global keynav */
        g_signal_connect_after (priv->main_window, "key_press_event",
                                G_CALLBACK (window_key_press_event), shell);
+       /* mouse hardware back button */
+       g_signal_connect_after (priv->main_window, "button_press_event",
+                               G_CALLBACK (window_button_press_event), shell);
 
        /* setup buttons */
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_back"));
diff --git a/src/gs-sources-dialog.c b/src/gs-sources-dialog.c
index acb2f30..1585c24 100644
--- a/src/gs-sources-dialog.c
+++ b/src/gs-sources-dialog.c
@@ -369,6 +369,49 @@ remove_button_cb (GtkWidget *widget, GsSourcesDialog *dialog)
                                           dialog);
 }
 
+static gboolean
+key_press_event (GsSourcesDialog *dialog, GdkEventKey *event)
+{
+       GsSourcesDialogPrivate *priv = gs_sources_dialog_get_instance_private (dialog);
+       GdkKeymap *keymap;
+       GdkModifierType state;
+       gboolean is_rtl;
+
+       if (!gtk_widget_is_visible (priv->button_back) || !gtk_widget_is_sensitive (priv->button_back))
+               return GDK_EVENT_PROPAGATE;
+
+       state = event->state;
+       keymap = gdk_keymap_get_default ();
+       gdk_keymap_add_virtual_modifiers (keymap, &state);
+       state = state & gtk_accelerator_get_default_mod_mask ();
+       is_rtl = gtk_widget_get_direction (priv->button_back) == GTK_TEXT_DIR_RTL;
+
+       if ((!is_rtl && state == GDK_MOD1_MASK && event->keyval == GDK_KEY_Left) ||
+           (is_rtl && state == GDK_MOD1_MASK && event->keyval == GDK_KEY_Right) ||
+           event->keyval == GDK_KEY_Back) {
+               gtk_widget_activate (priv->button_back);
+               return GDK_EVENT_STOP;
+       }
+
+       return GDK_EVENT_PROPAGATE;
+}
+
+static gboolean
+button_press_event (GsSourcesDialog *dialog, GdkEventButton *event)
+{
+       GsSourcesDialogPrivate *priv = gs_sources_dialog_get_instance_private (dialog);
+
+       /* Mouse hardware back button is 8 */
+       if (event->button != 8)
+               return GDK_EVENT_PROPAGATE;
+
+       if (!gtk_widget_is_visible (priv->button_back) || !gtk_widget_is_sensitive (priv->button_back))
+               return GDK_EVENT_PROPAGATE;
+
+       gtk_widget_activate (priv->button_back);
+       return GDK_EVENT_STOP;
+}
+
 static gchar *
 get_os_name (void)
 {
@@ -475,6 +518,12 @@ gs_sources_dialog_init (GsSourcesDialog *dialog)
                          G_CALLBACK (back_button_cb), dialog);
        g_signal_connect (priv->button_remove, "clicked",
                          G_CALLBACK (remove_button_cb), dialog);
+
+       /* global keynav and mouse back button */
+       g_signal_connect (dialog, "key-press-event",
+                         G_CALLBACK (key_press_event), NULL);
+       g_signal_connect (dialog, "button-press-event",
+                         G_CALLBACK (button_press_event), NULL);
 }
 
 static void
diff --git a/src/gs-update-dialog.c b/src/gs-update-dialog.c
index 2265ac5..676ccea 100644
--- a/src/gs-update-dialog.c
+++ b/src/gs-update-dialog.c
@@ -394,6 +394,49 @@ scrollbar_mapped_cb (GtkWidget *sb, GtkScrolledWindow *swin)
        }
 }
 
+static gboolean
+key_press_event (GsUpdateDialog *dialog, GdkEventKey *event)
+{
+       GsUpdateDialogPrivate *priv = gs_update_dialog_get_instance_private (dialog);
+       GdkKeymap *keymap;
+       GdkModifierType state;
+       gboolean is_rtl;
+
+       if (!gtk_widget_is_visible (priv->button_back) || !gtk_widget_is_sensitive (priv->button_back))
+               return GDK_EVENT_PROPAGATE;
+
+       state = event->state;
+       keymap = gdk_keymap_get_default ();
+       gdk_keymap_add_virtual_modifiers (keymap, &state);
+       state = state & gtk_accelerator_get_default_mod_mask ();
+       is_rtl = gtk_widget_get_direction (priv->button_back) == GTK_TEXT_DIR_RTL;
+
+       if ((!is_rtl && state == GDK_MOD1_MASK && event->keyval == GDK_KEY_Left) ||
+           (is_rtl && state == GDK_MOD1_MASK && event->keyval == GDK_KEY_Right) ||
+           event->keyval == GDK_KEY_Back) {
+               gtk_widget_activate (priv->button_back);
+               return GDK_EVENT_STOP;
+       }
+
+       return GDK_EVENT_PROPAGATE;
+}
+
+static gboolean
+button_press_event (GsUpdateDialog *dialog, GdkEventButton *event)
+{
+       GsUpdateDialogPrivate *priv = gs_update_dialog_get_instance_private (dialog);
+
+       /* Mouse hardware back button is 8 */
+       if (event->button != 8)
+               return GDK_EVENT_PROPAGATE;
+
+       if (!gtk_widget_is_visible (priv->button_back) || !gtk_widget_is_sensitive (priv->button_back))
+               return GDK_EVENT_PROPAGATE;
+
+       gtk_widget_activate (priv->button_back);
+       return GDK_EVENT_STOP;
+}
+
 static void
 set_plugin_loader (GsUpdateDialog *dialog, GsPluginLoader *plugin_loader)
 {
@@ -455,6 +498,12 @@ gs_update_dialog_init (GsUpdateDialog *dialog)
        scrollbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (priv->scrolledwindow_details));
        g_signal_connect (scrollbar, "map", G_CALLBACK (scrollbar_mapped_cb), priv->scrolledwindow_details);
        g_signal_connect (scrollbar, "unmap", G_CALLBACK (scrollbar_mapped_cb), priv->scrolledwindow_details);
+
+       /* global keynav and mouse back button */
+       g_signal_connect (dialog, "key-press-event",
+                         G_CALLBACK (key_press_event), NULL);
+       g_signal_connect (dialog, "button-press-event",
+                         G_CALLBACK (button_press_event), NULL);
 }
 
 static void


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