diff options
author | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-26 18:43:26 +0000 |
---|---|---|
committer | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-26 18:43:26 +0000 |
commit | 1676374870966b50e20d7097881e49c084a7caf5 (patch) | |
tree | d8b0f38dcce4287f1c591510f346e32638db2673 /chrome | |
parent | 1b03426641d2f49d586e940a4366104bb685ff28 (diff) | |
download | chromium_src-1676374870966b50e20d7097881e49c084a7caf5.zip chromium_src-1676374870966b50e20d7097881e49c084a7caf5.tar.gz chromium_src-1676374870966b50e20d7097881e49c084a7caf5.tar.bz2 |
Hook up ctrl+tab and ctrl+shift+tab for switching tabs in linux
We can't just add accelerators for these because GDK_Tab and GDK_ISO_Left_Tab are not valid accelerator keys:
http://www.google.com/codesearch/p?hl=en#ycarM8Ghiog/gtk+-2.4.0/gtk/gtkaccelgroup.c&q=gtk_accel_groups_activate&l=805
Instead, handle these keys in keypress and forward the event on to BrowserWindowGtk::OnAccelerator directly. We stash a pointer to BrowserWindowGtk on the GtkWindow.
Review URL: http://codereview.chromium.org/42611
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12581 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 38 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 13 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents_view_gtk.cc | 10 |
3 files changed, 46 insertions, 15 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index e2960f8..7bf8a69 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -165,6 +165,7 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser) method_factory_(this) { window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); gtk_window_set_default_size(window_, 640, 480); + g_object_set_data(G_OBJECT(window_), "browser_window_gtk", this); g_signal_connect(window_, "delete-event", G_CALLBACK(MainWindowDeleteEvent), this); g_signal_connect(window_, "destroy", @@ -251,6 +252,31 @@ BrowserWindowGtk::~BrowserWindowGtk() { browser_->tabstrip_model()->RemoveObserver(this); } +void BrowserWindowGtk::HandleAccelerator(guint keyval, + GdkModifierType modifier) { + // Filter modifier to only include accelerator modifiers. + modifier = static_cast<GdkModifierType>( + modifier & gtk_accelerator_get_default_mod_mask()); + switch (keyval) { + // Gtk doesn't allow GDK_Tab or GDK_ISO_Left_Tab to be an accelerator (see + // gtk_accelerator_valid), so we need to handle these accelerators + // manually. + case GDK_Tab: + if (GDK_CONTROL_MASK == modifier) + ExecuteBrowserCommand(IDC_SELECT_NEXT_TAB); + break; + + case GDK_ISO_Left_Tab: + if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) + ExecuteBrowserCommand(IDC_SELECT_PREVIOUS_TAB); + break; + + default: + // Pass the accelerator on to GTK. + gtk_accel_groups_activate(G_OBJECT(window_), keyval, modifier); + } +} + gboolean BrowserWindowGtk::OnContentAreaExpose(GtkWidget* widget, GdkEventExpose* e, BrowserWindowGtk* window) { @@ -542,7 +568,7 @@ void BrowserWindowGtk::ConnectAccelerators() { for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) { gtk_accel_group_connect( accel_group, kAcceleratorMap[i].keyval, GDK_CONTROL_MASK, - GtkAccelFlags(0), g_cclosure_new(G_CALLBACK(OnAccelerator), + GtkAccelFlags(0), g_cclosure_new(G_CALLBACK(OnGtkAccelerator), this, NULL)); } } @@ -559,11 +585,11 @@ void BrowserWindowGtk::SetCustomFrame(bool custom_frame) { } // static -gboolean BrowserWindowGtk::OnAccelerator(GtkAccelGroup* accel_group, - GObject* acceleratable, - guint keyval, - GdkModifierType modifier, - BrowserWindowGtk* browser_window) { +gboolean BrowserWindowGtk::OnGtkAccelerator(GtkAccelGroup* accel_group, + GObject* acceleratable, + guint keyval, + GdkModifierType modifier, + BrowserWindowGtk* browser_window) { int command_id = GetCommandFromKeyval(keyval); // We have to delay certain commands that may try to destroy widgets to which // GTK is currently holding a reference. (For now the only such command is diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index 301c5ec..7cf1674 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -32,6 +32,9 @@ class BrowserWindowGtk : public BrowserWindow, explicit BrowserWindowGtk(Browser* browser); virtual ~BrowserWindowGtk(); + // Process a keyboard input and try to find an accelerator for it. + void HandleAccelerator(guint keyval, GdkModifierType modifier); + // Overridden from BrowserWindow virtual void Show(); virtual void SetBounds(const gfx::Rect& bounds); @@ -108,11 +111,11 @@ class BrowserWindowGtk : public BrowserWindow, static gboolean OnContentAreaExpose(GtkWidget* widget, GdkEventExpose* e, BrowserWindowGtk* window); - static gboolean OnAccelerator(GtkAccelGroup* accel_group, - GObject* acceleratable, - guint keyval, - GdkModifierType modifier, - BrowserWindowGtk* browser_window); + static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group, + GObject* acceleratable, + guint keyval, + GdkModifierType modifier, + BrowserWindowGtk* browser_window); // A small shim for browser_->ExecuteCommand. void ExecuteBrowserCommand(int id); diff --git a/chrome/browser/tab_contents/web_contents_view_gtk.cc b/chrome/browser/tab_contents/web_contents_view_gtk.cc index 65ec077..8514d64 100644 --- a/chrome/browser/tab_contents/web_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/web_contents_view_gtk.cc @@ -5,11 +5,11 @@ #include "chrome/browser/tab_contents/web_contents_view_gtk.h" #include <gdk/gdk.h> -#include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> #include "base/gfx/point.h" #include "base/gfx/rect.h" +#include "chrome/browser/gtk/browser_window_gtk.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" #include "chrome/browser/tab_contents/render_view_context_menu_gtk.h" @@ -179,10 +179,12 @@ void WebContentsViewGtk::TakeFocus(bool reverse) { void WebContentsViewGtk::HandleKeyboardEvent( const NativeWebKeyboardEvent& event) { - // This may be an accelerator. Pass it on to GTK. + // This may be an accelerator. Pass it on to our browser window to handle. GtkWindow* window = GetTopLevelNativeWindow(); - gtk_accel_groups_activate(G_OBJECT(window), event.os_event->keyval, - GdkModifierType(event.os_event->state)); + BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>( + g_object_get_data(G_OBJECT(window), "browser_window_gtk")); + browser_window->HandleAccelerator(event.os_event->keyval, + static_cast<GdkModifierType>(event.os_event->state)); } void WebContentsViewGtk::OnFindReply(int request_id, |