summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 18:30:39 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 18:30:39 +0000
commit3171a5f58cc8ddc33eeef2d597fc80a8b214d3cc (patch)
tree1b07fa92b5540f56c1e8a98f7be7882f10e4deef
parent94d2135c70fc622226a72fd970ed1d3dd0428b6d (diff)
downloadchromium_src-3171a5f58cc8ddc33eeef2d597fc80a8b214d3cc.zip
chromium_src-3171a5f58cc8ddc33eeef2d597fc80a8b214d3cc.tar.gz
chromium_src-3171a5f58cc8ddc33eeef2d597fc80a8b214d3cc.tar.bz2
GTK: more signal handler foolproofing.
BUG=40735 TEST=manual clicking about, trybots Review URL: http://codereview.chromium.org/1783010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45966 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.cc47
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.h2
-rw-r--r--chrome/browser/gtk/fullscreen_exit_bubble_gtk.cc33
-rw-r--r--chrome/browser/gtk/fullscreen_exit_bubble_gtk.h12
-rw-r--r--chrome/browser/gtk/gtk_theme_provider.cc13
-rw-r--r--chrome/browser/gtk/gtk_theme_provider.h3
-rw-r--r--chrome/browser/gtk/menu_bar_helper.cc27
-rw-r--r--chrome/browser/gtk/menu_bar_helper.h30
-rw-r--r--chrome/browser/gtk/options/content_page_gtk.cc4
-rw-r--r--chrome/browser/gtk/rounded_window.cc19
10 files changed, 80 insertions, 110 deletions
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
index 3eb7e98..0ea880c 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
@@ -100,13 +100,13 @@ class BrowserActionButton : public NotificationObserver,
ImageLoadingTracker::DONT_CACHE);
}
- g_signal_connect(button_.get(), "button-press-event",
+ signals_.Connect(button_.get(), "button-press-event",
G_CALLBACK(OnButtonPress), this);
- g_signal_connect(button_.get(), "clicked",
+ signals_.Connect(button_.get(), "clicked",
G_CALLBACK(OnClicked), this);
- g_signal_connect_after(button_.get(), "expose-event",
- G_CALLBACK(OnExposeEvent), this);
- g_signal_connect(button_.get(), "drag-begin",
+ signals_.ConnectAfter(button_.get(), "expose-event",
+ G_CALLBACK(OnExposeEvent), this);
+ signals_.Connect(button_.get(), "drag-begin",
G_CALLBACK(&OnDragBegin), this);
registrar_.Add(this, NotificationType::EXTENSION_BROWSER_ACTION_UPDATED,
@@ -318,6 +318,7 @@ class BrowserActionButton : public NotificationObserver,
// Same as |default_icon_|, but stored as SkBitmap.
SkBitmap default_skbitmap_;
+ GtkSignalRegistrar signals_;
NotificationRegistrar registrar_;
// The context menu view and model for this extension action.
@@ -352,19 +353,19 @@ BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser)
GtkWidget* gripper = gtk_button_new();
GTK_WIDGET_UNSET_FLAGS(gripper, GTK_CAN_FOCUS);
gtk_widget_add_events(gripper, GDK_POINTER_MOTION_MASK);
- g_signal_connect(gripper, "motion-notify-event",
+ signals_.Connect(gripper, "motion-notify-event",
G_CALLBACK(OnGripperMotionNotifyThunk), this);
- g_signal_connect(gripper, "expose-event",
+ signals_.Connect(gripper, "expose-event",
G_CALLBACK(OnGripperExposeThunk), this);
- g_signal_connect(gripper, "enter-notify-event",
+ signals_.Connect(gripper, "enter-notify-event",
G_CALLBACK(OnGripperEnterNotifyThunk), this);
- g_signal_connect(gripper, "leave-notify-event",
+ signals_.Connect(gripper, "leave-notify-event",
G_CALLBACK(OnGripperLeaveNotifyThunk), this);
- g_signal_connect(gripper, "button-release-event",
+ signals_.Connect(gripper, "button-release-event",
G_CALLBACK(OnGripperButtonReleaseThunk), this);
- g_signal_connect(gripper, "button-press-event",
+ signals_.Connect(gripper, "button-press-event",
G_CALLBACK(OnGripperButtonPressThunk), this);
- g_signal_connect(overflow_button_.widget(), "button-press-event",
+ signals_.Connect(overflow_button_.widget(), "button-press-event",
G_CALLBACK(OnOverflowButtonPressThunk), this);
gtk_box_pack_start(GTK_BOX(hbox_.get()), gripper, FALSE, FALSE, 0);
@@ -384,19 +385,13 @@ BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser)
// We want to connect to "set-focus" on the toplevel window; we have to wait
// until we are added to a toplevel window to do so.
- g_signal_connect(widget(), "hierarchy-changed",
+ signals_.Connect(widget(), "hierarchy-changed",
G_CALLBACK(OnHierarchyChangedThunk), this);
ViewIDUtil::SetID(button_hbox_.get(), VIEW_ID_BROWSER_ACTION_TOOLBAR);
}
BrowserActionsToolbarGtk::~BrowserActionsToolbarGtk() {
- GtkWidget* toplevel = gtk_widget_get_toplevel(widget());
- if (toplevel) {
- g_signal_handlers_disconnect_by_func(
- toplevel, reinterpret_cast<gpointer>(OnSetFocusThunk), this);
- }
-
if (model_)
model_->RemoveObserver(this);
button_hbox_.Destroy();
@@ -423,7 +418,7 @@ void BrowserActionsToolbarGtk::SetupDrags() {
gtk_drag_dest_set(button_hbox_.get(), GTK_DEST_DEFAULT_DROP, &drag_target, 1,
GDK_ACTION_MOVE);
- g_signal_connect(button_hbox_.get(), "drag-motion",
+ signals_.Connect(button_hbox_.get(), "drag-motion",
G_CALLBACK(OnDragMotionThunk), this);
}
@@ -463,16 +458,16 @@ void BrowserActionsToolbarGtk::CreateButtonForExtension(Extension* extension,
gtk_drag_source_set(button->widget(), GDK_BUTTON1_MASK, &drag_target, 1,
GDK_ACTION_MOVE);
// We ignore whether the drag was a "success" or "failure" in Gtk's opinion.
- g_signal_connect(button->widget(), "drag-end",
+ signals_.Connect(button->widget(), "drag-end",
G_CALLBACK(&OnDragEndThunk), this);
- g_signal_connect(button->widget(), "drag-failed",
+ signals_.Connect(button->widget(), "drag-failed",
G_CALLBACK(&OnDragFailedThunk), this);
// Any time a browser action button is shown or hidden we have to update
// the chevron state.
- g_signal_connect(button->widget(), "show",
+ signals_.Connect(button->widget(), "show",
G_CALLBACK(&OnButtonShowOrHideThunk), this);
- g_signal_connect(button->widget(), "hide",
+ signals_.Connect(button->widget(), "hide",
G_CALLBACK(&OnButtonShowOrHideThunk), this);
gtk_widget_show(button->widget());
@@ -712,7 +707,7 @@ void BrowserActionsToolbarGtk::OnHierarchyChanged(
if (!GTK_WIDGET_TOPLEVEL(toplevel))
return;
- g_signal_connect(toplevel, "set-focus", G_CALLBACK(OnSetFocusThunk), this);
+ signals_.Connect(toplevel, "set-focus", G_CALLBACK(OnSetFocusThunk), this);
}
void BrowserActionsToolbarGtk::OnSetFocus(GtkWidget* widget,
@@ -826,7 +821,7 @@ gboolean BrowserActionsToolbarGtk::OnOverflowButtonPress(
// TODO(estade): set the menu item's tooltip.
}
- g_signal_connect(overflow_menu_->widget(), "button-press-event",
+ signals_.Connect(overflow_menu_->widget(), "button-press-event",
G_CALLBACK(OnOverflowMenuButtonPressThunk), this);
gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(overflow),
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.h b/chrome/browser/gtk/browser_actions_toolbar_gtk.h
index 88faba7..5de4ffb 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.h
@@ -184,6 +184,8 @@ class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer,
// This is the width we were at when we started animating.
int start_width_;
+ GtkSignalRegistrar signals_;
+
ScopedRunnableMethodFactory<BrowserActionsToolbarGtk> method_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserActionsToolbarGtk);
diff --git a/chrome/browser/gtk/fullscreen_exit_bubble_gtk.cc b/chrome/browser/gtk/fullscreen_exit_bubble_gtk.cc
index fb93241..848cb59 100644
--- a/chrome/browser/gtk/fullscreen_exit_bubble_gtk.cc
+++ b/chrome/browser/gtk/fullscreen_exit_bubble_gtk.cc
@@ -35,15 +35,6 @@ FullscreenExitBubbleGtk::FullscreenExitBubbleGtk(
}
FullscreenExitBubbleGtk::~FullscreenExitBubbleGtk() {
- // If the user exits the browser while in fullscreen mode, we may already
- // have been removed from the widget hierarchy.
- GtkWidget* parent = gtk_widget_get_parent(widget());
- if (parent) {
- DCHECK_EQ(GTK_WIDGET(container_), parent);
- g_signal_handlers_disconnect_by_func(parent,
- reinterpret_cast<gpointer>(OnSetFloatingPosition), this);
- gtk_container_remove(GTK_CONTAINER(parent), widget());
- }
}
void FullscreenExitBubbleGtk::InitWidgets() {
@@ -61,7 +52,7 @@ void FullscreenExitBubbleGtk::InitWidgets() {
exit_text_utf8.c_str());
gtk_chrome_link_button_set_use_gtk_theme(GTK_CHROME_LINK_BUTTON(link),
FALSE);
- g_signal_connect(link, "clicked", G_CALLBACK(OnLinkClicked), this);
+ signals_.Connect(link, "clicked", G_CALLBACK(OnLinkClickedThunk), this);
GtkWidget* container = gtk_util::CreateGtkBorderBin(link, &gfx::kGdkBlack,
kPaddingPixels, kPaddingPixels, kPaddingPixels, kPaddingPixels);
@@ -83,38 +74,34 @@ void FullscreenExitBubbleGtk::InitWidgets() {
gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(container_),
widget());
- g_signal_connect(container_, "set-floating-position",
- G_CALLBACK(OnSetFloatingPosition), this);
+ signals_.Connect(container_, "set-floating-position",
+ G_CALLBACK(OnSetFloatingPositionThunk), this);
}
void FullscreenExitBubbleGtk::Hide() {
slide_widget_->Close();
}
-// static
void FullscreenExitBubbleGtk::OnSetFloatingPosition(
- GtkFloatingContainer* floating_container, GtkAllocation* allocation,
- FullscreenExitBubbleGtk* bubble) {
+ GtkWidget* floating_container,
+ GtkAllocation* allocation) {
GtkRequisition bubble_size;
- gtk_widget_size_request(bubble->widget(), &bubble_size);
+ gtk_widget_size_request(widget(), &bubble_size);
// Position the bubble at the top center of the screen.
GValue value = { 0, };
g_value_init(&value, G_TYPE_INT);
g_value_set_int(&value, (allocation->width - bubble_size.width) / 2);
gtk_container_child_set_property(GTK_CONTAINER(floating_container),
- bubble->widget(), "x", &value);
+ widget(), "x", &value);
g_value_set_int(&value, 0);
gtk_container_child_set_property(GTK_CONTAINER(floating_container),
- bubble->widget(), "y", &value);
+ widget(), "y", &value);
g_value_unset(&value);
}
-// static
-void FullscreenExitBubbleGtk::OnLinkClicked(GtkWidget* link,
- FullscreenExitBubbleGtk* bubble) {
- GtkWindow* window = GTK_WINDOW(gtk_widget_get_toplevel(
- bubble->widget()));
+void FullscreenExitBubbleGtk::OnLinkClicked(GtkWidget* link) {
+ GtkWindow* window = GTK_WINDOW(gtk_widget_get_toplevel(widget()));
gtk_window_unfullscreen(window);
}
diff --git a/chrome/browser/gtk/fullscreen_exit_bubble_gtk.h b/chrome/browser/gtk/fullscreen_exit_bubble_gtk.h
index 44b3ac0..0b9c90e 100644
--- a/chrome/browser/gtk/fullscreen_exit_bubble_gtk.h
+++ b/chrome/browser/gtk/fullscreen_exit_bubble_gtk.h
@@ -7,6 +7,7 @@
#include <gtk/gtk.h>
+#include "app/gtk_signal.h"
#include "base/timer.h"
#include "chrome/browser/gtk/slide_animator_gtk.h"
@@ -30,12 +31,9 @@ class FullscreenExitBubbleGtk {
// Hide the exit bubble.
void Hide();
- static void OnSetFloatingPosition(GtkFloatingContainer* floating_container,
- GtkAllocation* allocation,
- FullscreenExitBubbleGtk* bubble);
-
- static void OnLinkClicked(GtkWidget* link,
- FullscreenExitBubbleGtk* bubble);
+ CHROMEGTK_CALLBACK_1(FullscreenExitBubbleGtk, void, OnSetFloatingPosition,
+ GtkAllocation*);
+ CHROMEGTK_CALLBACK_0(FullscreenExitBubbleGtk, void, OnLinkClicked);
// A pointer to the floating container that is our parent.
GtkFloatingContainer* container_;
@@ -45,6 +43,8 @@ class FullscreenExitBubbleGtk {
// The timer that does the initial hiding of the exit bubble.
base::OneShotTimer<FullscreenExitBubbleGtk> initial_delay_;
+
+ GtkSignalRegistrar signals_;
};
#endif // CHROME_BROWSER_GTK_FULLSCREEN_EXIT_BUBBLE_GTK_H_
diff --git a/chrome/browser/gtk/gtk_theme_provider.cc b/chrome/browser/gtk/gtk_theme_provider.cc
index be3c358c..66fa0e5 100644
--- a/chrome/browser/gtk/gtk_theme_provider.cc
+++ b/chrome/browser/gtk/gtk_theme_provider.cc
@@ -145,7 +145,7 @@ GtkThemeProvider::GtkThemeProvider()
// Only realized widgets receive style-set notifications, which we need to
// broadcast new theme images and colors.
gtk_widget_realize(fake_frame_);
- g_signal_connect(fake_frame_, "style-set", G_CALLBACK(&OnStyleSet), this);
+ signals_.Connect(fake_frame_, "style-set", G_CALLBACK(&OnStyleSet), this);
}
GtkThemeProvider::~GtkThemeProvider() {
@@ -158,13 +158,6 @@ GtkThemeProvider::~GtkThemeProvider() {
// We have to call this because FreePlatformCached() in ~BrowserThemeProvider
// doesn't call the right virutal FreePlatformCaches.
FreePlatformCaches();
-
- // Disconnect from the destroy signal of any redisual widgets in
- // |chrome_buttons_|.
- for (std::vector<GtkWidget*>::iterator it = chrome_buttons_.begin();
- it != chrome_buttons_.end(); ++it) {
- gtk_signal_disconnect_by_data(GTK_OBJECT(*it), this);
- }
}
void GtkThemeProvider::Init(Profile* profile) {
@@ -249,7 +242,7 @@ GtkWidget* GtkThemeProvider::BuildChromeButton() {
gtk_chrome_button_set_use_gtk_rendering(GTK_CHROME_BUTTON(button), use_gtk_);
chrome_buttons_.push_back(button);
- g_signal_connect(button, "destroy", G_CALLBACK(OnDestroyChromeButtonThunk),
+ signals_.Connect(button, "destroy", G_CALLBACK(OnDestroyChromeButtonThunk),
this);
return button;
}
@@ -261,7 +254,7 @@ GtkWidget* GtkThemeProvider::CreateToolbarSeparator() {
kSeparatorPadding, kSeparatorPadding, kSeparatorPadding, 0);
gtk_container_add(GTK_CONTAINER(alignment), separator);
- g_signal_connect(separator, "expose-event",
+ signals_.Connect(separator, "expose-event",
G_CALLBACK(OnSeparatorExposeThunk), this);
return alignment;
}
diff --git a/chrome/browser/gtk/gtk_theme_provider.h b/chrome/browser/gtk/gtk_theme_provider.h
index 40522b6..3c7b752 100644
--- a/chrome/browser/gtk/gtk_theme_provider.h
+++ b/chrome/browser/gtk/gtk_theme_provider.h
@@ -192,6 +192,9 @@ class GtkThemeProvider : public BrowserThemeProvider,
// them of theme changes.
std::vector<GtkWidget*> chrome_buttons_;
+ // Tracks all the signals we have connected to on various widgets.
+ GtkSignalRegistrar signals_;
+
// Tints and colors calculated by LoadGtkValues() that are given to the
// caller while |use_gtk_| is true.
ColorMap colors_;
diff --git a/chrome/browser/gtk/menu_bar_helper.cc b/chrome/browser/gtk/menu_bar_helper.cc
index 54fa555..d5d42ae 100644
--- a/chrome/browser/gtk/menu_bar_helper.cc
+++ b/chrome/browser/gtk/menu_bar_helper.cc
@@ -79,16 +79,19 @@ void MenuBarHelper::MenuStartedShowing(GtkWidget* button, GtkWidget* menu) {
DCHECK(GTK_IS_MENU(menu));
button_showing_menu_ = button;
showing_menu_ = menu;
- g_signal_connect(menu, "motion-notify-event",
- G_CALLBACK(OnMenuMotionNotifyThunk), this);
- g_signal_connect(menu, "hide",
- G_CALLBACK(OnMenuHiddenThunk), this);
- g_signal_connect(menu, "move-current",
- G_CALLBACK(OnMenuMoveCurrentThunk), this);
+
+ signal_handlers_.reset(new GtkSignalRegistrar());
+ signal_handlers_->Connect(menu, "motion-notify-event",
+ G_CALLBACK(OnMenuMotionNotifyThunk), this);
+ signal_handlers_->Connect(menu, "hide",
+ G_CALLBACK(OnMenuHiddenThunk), this);
+ signal_handlers_->Connect(menu, "move-current",
+ G_CALLBACK(OnMenuMoveCurrentThunk), this);
gtk_container_foreach(GTK_CONTAINER(menu), PopulateSubmenus, &submenus_);
+
for (size_t i = 0; i < submenus_.size(); ++i) {
- g_signal_connect(submenus_[i], "motion-notify-event",
- G_CALLBACK(OnMenuMotionNotifyThunk), this);
+ signal_handlers_->Connect(submenus_[i], "motion-notify-event",
+ G_CALLBACK(OnMenuMotionNotifyThunk), this);
}
}
@@ -138,14 +141,8 @@ gboolean MenuBarHelper::OnMenuMotionNotify(GtkWidget* menu,
void MenuBarHelper::OnMenuHidden(GtkWidget* menu) {
DCHECK_EQ(showing_menu_, menu);
- int matched = g_signal_handlers_disconnect_matched(showing_menu_,
- G_SIGNAL_MATCH_DATA, 0, NULL, NULL, NULL, this);
- DCHECK_EQ(3, matched);
- for (size_t i = 0; i < submenus_.size(); ++i) {
- g_signal_handlers_disconnect_by_func(submenus_[i],
- reinterpret_cast<gpointer>(OnMenuMotionNotifyThunk), this);
- }
+ signal_handlers_.reset();
showing_menu_ = NULL;
button_showing_menu_ = NULL;
submenus_.clear();
diff --git a/chrome/browser/gtk/menu_bar_helper.h b/chrome/browser/gtk/menu_bar_helper.h
index 9b6448c..05d6819 100644
--- a/chrome/browser/gtk/menu_bar_helper.h
+++ b/chrome/browser/gtk/menu_bar_helper.h
@@ -13,6 +13,9 @@
#include <vector>
+#include "app/gtk_signal.h"
+#include "base/scoped_ptr.h"
+
class MenuBarHelper {
public:
class Delegate {
@@ -43,24 +46,11 @@ class MenuBarHelper {
void Clear();
private:
- static gboolean OnMenuMotionNotifyThunk(GtkWidget* menu,
- GdkEventMotion* motion,
- MenuBarHelper* helper) {
- return helper->OnMenuMotionNotify(menu, motion);
- }
- gboolean OnMenuMotionNotify(GtkWidget* menu, GdkEventMotion* motion);
-
- static void OnMenuHiddenThunk(GtkWidget* menu, MenuBarHelper* helper) {
- helper->OnMenuHidden(menu);
- }
- void OnMenuHidden(GtkWidget* menu);
-
- static void OnMenuMoveCurrentThunk(GtkWidget* menu,
- GtkMenuDirectionType dir,
- MenuBarHelper* helper) {
- helper->OnMenuMoveCurrent(menu, dir);
- }
- void OnMenuMoveCurrent(GtkWidget* menu, GtkMenuDirectionType dir);
+ CHROMEGTK_CALLBACK_1(MenuBarHelper, gboolean, OnMenuMotionNotify,
+ GdkEventMotion*);
+ CHROMEGTK_CALLBACK_0(MenuBarHelper, void, OnMenuHidden);
+ CHROMEGTK_CALLBACK_1(MenuBarHelper, void, OnMenuMoveCurrent,
+ GtkMenuDirectionType);
// The buttons for which we pop up menus. We do not own these, or even add
// refs to them.
@@ -76,6 +66,10 @@ class MenuBarHelper {
// of them.
std::vector<GtkWidget*> submenus_;
+ // Signal handlers that are attached only between the "show" and "hide" events
+ // for the menu.
+ scoped_ptr<GtkSignalRegistrar> signal_handlers_;
+
Delegate* delegate_;
};
diff --git a/chrome/browser/gtk/options/content_page_gtk.cc b/chrome/browser/gtk/options/content_page_gtk.cc
index 22a635e..3b92201 100644
--- a/chrome/browser/gtk/options/content_page_gtk.cc
+++ b/chrome/browser/gtk/options/content_page_gtk.cc
@@ -45,8 +45,8 @@ void OnLabelAllocate(GtkWidget* label, GtkAllocation* allocation) {
// Disconnect ourselves. Repeatedly resizing based on allocation causes
// the dialog to become unshrinkable.
- g_signal_handlers_disconnect_by_func(label, (void*)OnLabelAllocate,
- NULL);
+ g_signal_handlers_disconnect_by_func(
+ label, reinterpret_cast<gpointer>(OnLabelAllocate), NULL);
}
// Set the label to use a request size equal to its initial allocation
diff --git a/chrome/browser/gtk/rounded_window.cc b/chrome/browser/gtk/rounded_window.cc
index 52bedc9..c223425 100644
--- a/chrome/browser/gtk/rounded_window.cc
+++ b/chrome/browser/gtk/rounded_window.cc
@@ -7,6 +7,7 @@
#include <gtk/gtk.h>
#include <math.h>
+#include "app/gtk_signal.h"
#include "base/i18n/rtl.h"
#include "chrome/browser/gtk/gtk_util.h"
@@ -36,6 +37,9 @@ struct RoundedWindowData {
// Which sides of the window should have an internal border?
int drawn_borders;
+
+ // Keeps track of attached signal handlers.
+ GtkSignalRegistrar signals;
};
// Callback from GTK to release allocated memory.
@@ -256,11 +260,12 @@ void ActAsRoundedWindow(
DCHECK(!g_object_get_data(G_OBJECT(widget), kRoundedData));
gtk_widget_set_app_paintable(widget, TRUE);
- g_signal_connect(widget, "expose-event",
- G_CALLBACK(OnRoundedWindowExpose), NULL);
- g_signal_connect(widget, "style-set", G_CALLBACK(OnStyleSet), NULL);
RoundedWindowData* data = new RoundedWindowData;
+ data->signals.Connect(widget, "expose-event",
+ G_CALLBACK(OnRoundedWindowExpose), NULL);
+ data->signals.Connect(widget, "style-set", G_CALLBACK(OnStyleSet), NULL);
+
data->expected_width = -1;
data->expected_height = -1;
@@ -275,13 +280,7 @@ void ActAsRoundedWindow(
}
void StopActingAsRoundedWindow(GtkWidget* widget) {
- g_signal_handlers_disconnect_by_func(widget,
- reinterpret_cast<gpointer>(OnRoundedWindowExpose), NULL);
- g_signal_handlers_disconnect_by_func(widget,
- reinterpret_cast<gpointer>(OnStyleSet), NULL);
-
- delete static_cast<RoundedWindowData*>(
- g_object_steal_data(G_OBJECT(widget), kRoundedData));
+ g_object_set_data(G_OBJECT(widget), kRoundedData, NULL);
if (GTK_WIDGET_REALIZED(widget))
gdk_window_shape_combine_mask(widget->window, NULL, 0, 0);