diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-20 18:16:04 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-20 18:16:04 +0000 |
commit | e3f9adeecf13633ff85524cecd429eab671f7506 (patch) | |
tree | 78a721d3fe13c899c54d71f7e25d32ea3192cb20 | |
parent | 6ff93a1aa55765a7adcdb5148b3f7601fc2a28d6 (diff) | |
download | chromium_src-e3f9adeecf13633ff85524cecd429eab671f7506.zip chromium_src-e3f9adeecf13633ff85524cecd429eab671f7506.tar.gz chromium_src-e3f9adeecf13633ff85524cecd429eab671f7506.tar.bz2 |
Hook up ctrl-w for close tab on linux.
Delay the handling of certain accelerators so we don't try to destroy a widget that GTK is reffing as a result of event handling.
Patch based on another by Dean McNamee.
Review URL: http://codereview.chromium.org/42421
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12200 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 27 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 8 |
2 files changed, 31 insertions, 4 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 4ff8a7a..19b12e5 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -84,12 +84,13 @@ const struct AcceleratorMapping { guint keyval; int command_id; } kAcceleratorMap[] = { - { GDK_l, IDC_FOCUS_LOCATION }, { GDK_k, IDC_FOCUS_SEARCH }, + { GDK_l, IDC_FOCUS_LOCATION }, { GDK_o, IDC_OPEN_FILE }, + { GDK_w, IDC_CLOSE_TAB }, }; -static int GetCommandFromKeyval(guint accel_key) { +int GetCommandFromKeyval(guint accel_key) { for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) { if (kAcceleratorMap[i].keyval == accel_key) return kAcceleratorMap[i].command_id; @@ -115,7 +116,8 @@ gboolean OnKeyPress(GtkWindow* window, GdkEventKey* event, gpointer userdata) { BrowserWindowGtk::BrowserWindowGtk(Browser* browser) : browser_(browser), // TODO(port): make this a pref. - custom_frame_(false) { + custom_frame_(false), + method_factory_(this) { window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); gtk_window_set_default_size(window_, 640, 480); g_signal_connect(window_, "destroy", @@ -517,6 +519,23 @@ gboolean BrowserWindowGtk::OnAccelerator(GtkAccelGroup* accel_group, guint keyval, GdkModifierType modifier, BrowserWindowGtk* browser_window) { - browser_window->browser_->ExecuteCommand(GetCommandFromKeyval(keyval)); + 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 + // tab closing.) GTK will hold a reference on the RWHV widget when the + // event came through on that widget but GTK focus was elsewhere. + if (IDC_CLOSE_TAB == command_id) { + MessageLoop::current()->PostTask(FROM_HERE, + browser_window->method_factory_.NewRunnableMethod( + &BrowserWindowGtk::ExecuteBrowserCommand, + command_id)); + } else { + browser_window->ExecuteBrowserCommand(command_id); + } + return TRUE; } + +void BrowserWindowGtk::ExecuteBrowserCommand(int id) { + browser_->ExecuteCommand(id); +} diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index 8811473..50a61ef 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -9,6 +9,7 @@ #include "base/gfx/rect.h" #include "base/scoped_ptr.h" +#include "base/task.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/views/widget/widget_gtk.h" @@ -114,6 +115,9 @@ class BrowserWindowGtk : public BrowserWindow, GdkModifierType modifier, BrowserWindowGtk* browser_window); + // A small shim for browser_->ExecuteCommand. + void ExecuteBrowserCommand(int id); + gfx::Rect bounds_; GdkWindowState state_; @@ -139,6 +143,10 @@ class BrowserWindowGtk : public BrowserWindow, // to move among windows as tabs are dragged around. scoped_ptr<FindBarController> find_bar_controller_; + // When it goes out of scope during our destruction, |method_factory_| will + // cancel its pending tasks (which depend on us still existing). + ScopedRunnableMethodFactory<BrowserWindowGtk> method_factory_; + // Experiment with using views for gtk. scoped_ptr<views::WidgetGtk> experimental_widget_; }; |