+// Workaround for Ubuntu overlay scrollbar, which adds our GtkWindow to a
+// private window group in a GtkScrollbar realize handler. This breaks the grab
+// done by gtk_window_set_modal(), and allows menus and toolbars in the parent
+// frame to remain active. So, we install an emission hook on the "realize"
+// signal while showing a modal dialog. For any realize on a GtkScrollbar,
+// we check the top level parent to see if it has an explicitly set window
+// group that is not the same as its transient parent. If we find this, we
+// put the top level back in the same window group as its transient parent, and
+// re-add the grab.
+// Ubuntu 12.04 and 12.10 are known to have this problem.
+
+// need 2.10 for gtk_window_get_group()
+#if GTK_CHECK_VERSION(2,10,0)
+extern "C" {
+static gboolean
+realize_hook(GSignalInvocationHint*, unsigned, const GValue* param_values, void*)
+{
+ void* p = g_value_peek_pointer(param_values);
+ if (GTK_IS_SCROLLBAR(p))
+ {
+ GtkWindow* toplevel = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(p)));
+ GtkWindow* transient_parent = gtk_window_get_transient_for(toplevel);
+ if (transient_parent && gtk_window_has_group(toplevel))
+ {
+ GtkWindowGroup* group = gtk_window_get_group(toplevel);
+ GtkWindowGroup* group_parent = gtk_window_get_group(transient_parent);
+ if (group != group_parent)
+ {
+ gtk_window_group_add_window(group_parent, toplevel);
+ gtk_grab_add(GTK_WIDGET(toplevel));
+ }
+ }
+ }
+ return true;
+}
+}
+#endif // GTK 2.10
+