| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/gtk/menu_bar_helper.h" | 5 #include "chrome/browser/gtk/menu_bar_helper.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "chrome/browser/gtk/gtk_util.h" | 10 #include "chrome/browser/gtk/gtk_util.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 } | 72 } |
| 73 | 73 |
| 74 void MenuBarHelper::Clear() { | 74 void MenuBarHelper::Clear() { |
| 75 buttons_.clear(); | 75 buttons_.clear(); |
| 76 } | 76 } |
| 77 | 77 |
| 78 void MenuBarHelper::MenuStartedShowing(GtkWidget* button, GtkWidget* menu) { | 78 void MenuBarHelper::MenuStartedShowing(GtkWidget* button, GtkWidget* menu) { |
| 79 DCHECK(GTK_IS_MENU(menu)); | 79 DCHECK(GTK_IS_MENU(menu)); |
| 80 button_showing_menu_ = button; | 80 button_showing_menu_ = button; |
| 81 showing_menu_ = menu; | 81 showing_menu_ = menu; |
| 82 g_signal_connect(menu, "motion-notify-event", | 82 |
| 83 G_CALLBACK(OnMenuMotionNotifyThunk), this); | 83 signal_handlers_.reset(new GtkSignalRegistrar()); |
| 84 g_signal_connect(menu, "hide", | 84 signal_handlers_->Connect(menu, "motion-notify-event", |
| 85 G_CALLBACK(OnMenuHiddenThunk), this); | 85 G_CALLBACK(OnMenuMotionNotifyThunk), this); |
| 86 g_signal_connect(menu, "move-current", | 86 signal_handlers_->Connect(menu, "hide", |
| 87 G_CALLBACK(OnMenuMoveCurrentThunk), this); | 87 G_CALLBACK(OnMenuHiddenThunk), this); |
| 88 signal_handlers_->Connect(menu, "move-current", |
| 89 G_CALLBACK(OnMenuMoveCurrentThunk), this); |
| 88 gtk_container_foreach(GTK_CONTAINER(menu), PopulateSubmenus, &submenus_); | 90 gtk_container_foreach(GTK_CONTAINER(menu), PopulateSubmenus, &submenus_); |
| 91 |
| 89 for (size_t i = 0; i < submenus_.size(); ++i) { | 92 for (size_t i = 0; i < submenus_.size(); ++i) { |
| 90 g_signal_connect(submenus_[i], "motion-notify-event", | 93 signal_handlers_->Connect(submenus_[i], "motion-notify-event", |
| 91 G_CALLBACK(OnMenuMotionNotifyThunk), this); | 94 G_CALLBACK(OnMenuMotionNotifyThunk), this); |
| 92 } | 95 } |
| 93 } | 96 } |
| 94 | 97 |
| 95 gboolean MenuBarHelper::OnMenuMotionNotify(GtkWidget* menu, | 98 gboolean MenuBarHelper::OnMenuMotionNotify(GtkWidget* menu, |
| 96 GdkEventMotion* motion) { | 99 GdkEventMotion* motion) { |
| 97 // Don't do anything if pointer is in the menu. | 100 // Don't do anything if pointer is in the menu. |
| 98 if (MotionIsOverMenu(menu, motion)) | 101 if (MotionIsOverMenu(menu, motion)) |
| 99 return FALSE; | 102 return FALSE; |
| 100 if (buttons_.empty()) | 103 if (buttons_.empty()) |
| 101 return FALSE; | 104 return FALSE; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 131 delegate_->PopupForButton(button); | 134 delegate_->PopupForButton(button); |
| 132 return TRUE; | 135 return TRUE; |
| 133 } | 136 } |
| 134 } | 137 } |
| 135 | 138 |
| 136 return FALSE; | 139 return FALSE; |
| 137 } | 140 } |
| 138 | 141 |
| 139 void MenuBarHelper::OnMenuHidden(GtkWidget* menu) { | 142 void MenuBarHelper::OnMenuHidden(GtkWidget* menu) { |
| 140 DCHECK_EQ(showing_menu_, menu); | 143 DCHECK_EQ(showing_menu_, menu); |
| 141 int matched = g_signal_handlers_disconnect_matched(showing_menu_, | |
| 142 G_SIGNAL_MATCH_DATA, 0, NULL, NULL, NULL, this); | |
| 143 DCHECK_EQ(3, matched); | |
| 144 | 144 |
| 145 for (size_t i = 0; i < submenus_.size(); ++i) { | 145 signal_handlers_.reset(); |
| 146 g_signal_handlers_disconnect_by_func(submenus_[i], | |
| 147 reinterpret_cast<gpointer>(OnMenuMotionNotifyThunk), this); | |
| 148 } | |
| 149 showing_menu_ = NULL; | 146 showing_menu_ = NULL; |
| 150 button_showing_menu_ = NULL; | 147 button_showing_menu_ = NULL; |
| 151 submenus_.clear(); | 148 submenus_.clear(); |
| 152 } | 149 } |
| 153 | 150 |
| 154 void MenuBarHelper::OnMenuMoveCurrent(GtkWidget* menu, | 151 void MenuBarHelper::OnMenuMoveCurrent(GtkWidget* menu, |
| 155 GtkMenuDirectionType dir) { | 152 GtkMenuDirectionType dir) { |
| 156 // The menu directions are triggered by the arrow keys as follows | 153 // The menu directions are triggered by the arrow keys as follows |
| 157 // | 154 // |
| 158 // PARENT left | 155 // PARENT left |
| (...skipping 15 matching lines...) Expand all Loading... |
| 174 break; | 171 break; |
| 175 } | 172 } |
| 176 default: | 173 default: |
| 177 return; | 174 return; |
| 178 } | 175 } |
| 179 | 176 |
| 180 // This signal doesn't have a return value; we have to manually stop its | 177 // This signal doesn't have a return value; we have to manually stop its |
| 181 // propagation. | 178 // propagation. |
| 182 g_signal_stop_emission_by_name(menu, "move-current"); | 179 g_signal_stop_emission_by_name(menu, "move-current"); |
| 183 } | 180 } |
| OLD | NEW |