Imported Upstream version 5.0.0.42

Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-04-10 11:41:01 +00:00
parent 1190d13a04
commit 6bdd276d05
19939 changed files with 3099680 additions and 93811 deletions

View File

@@ -0,0 +1,104 @@
From fdbef10f94b9e16618b75e7e12184befcd178852 Mon Sep 17 00:00:00 2001
From: Havoc Pennington <hp@pobox.com>
Date: Mon, 20 Dec 2010 12:58:04 -0500
Subject: [PATCH 01/68] Add invariant that a child is unmapped if parent is
unmapped
Requires fixes to GtkContainer and GtkWindow to unmap their
children, rather than just withdrawing or hiding the container
window.
Requires fix to GtkHandleBox to chain up to GtkContainer unmap.
Historically we avoided these unmaps for efficiency reasons,
but these days it's a bigger problem that there's no way
for child widgets to know that one of their ancestors has
become unmapped.
(cherry picked from commit b67c5af55bf611c013b2c43e6878281abd773530)
---
docs/widget_system.txt | 2 +-
gtk/gtkcontainer.c | 15 ++++++++++-----
gtk/gtkhandlebox.c | 2 ++
gtk/gtkwindow.c | 7 ++++++-
4 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/docs/widget_system.txt b/docs/widget_system.txt
index 1c2867c..9463f10 100644
--- a/docs/widget_system.txt
+++ b/docs/widget_system.txt
@@ -255,7 +255,7 @@ In the following
widget->parent && GTK_WIDGET_MAPPED (widget->parent) &&
GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_CHILD_VISIBLE
- => GTK_WIDGET_MAPPED (widget)
+ <=> GTK_WIDGET_MAPPED (widget)
Note:, the definition
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 9aaa7d9..7105724 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -2694,12 +2694,17 @@ gtk_container_unmap (GtkWidget *widget)
{
gtk_widget_set_mapped (widget, FALSE);
+ /* hide our window first so user doesn't see all the child windows
+ * vanishing one by one. (only matters these days if one of the
+ * children has an actual native window instead of client-side
+ * window, e.g. a GtkSocket would)
+ */
if (gtk_widget_get_has_window (widget))
- gdk_window_hide (widget->window);
- else
- gtk_container_forall (GTK_CONTAINER (widget),
- (GtkCallback)gtk_widget_unmap,
- NULL);
+ gdk_window_hide (gtk_widget_get_window (widget));
+
+ gtk_container_forall (GTK_CONTAINER (widget),
+ (GtkCallback)gtk_widget_unmap,
+ NULL);
}
/**
diff --git a/gtk/gtkhandlebox.c b/gtk/gtkhandlebox.c
index 667371f..557d2de 100644
--- a/gtk/gtkhandlebox.c
+++ b/gtk/gtkhandlebox.c
@@ -383,6 +383,8 @@ gtk_handle_box_unmap (GtkWidget *widget)
gdk_window_hide (hb->float_window);
hb->float_window_mapped = FALSE;
}
+
+ GTK_WIDGET_CLASS (gtk_handle_box_parent_class)->unmap (widget);
}
static void
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 4de3215..8f174c6 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -4690,7 +4690,8 @@ gtk_window_unmap (GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
- GtkWindowGeometryInfo *info;
+ GtkWindowGeometryInfo *info;
+ GtkWidget *child;
GdkWindowState state;
gtk_widget_set_mapped (widget, FALSE);
@@ -4721,6 +4722,10 @@ gtk_window_unmap (GtkWidget *widget)
window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
+
+ child = gtk_bin_get_child (&(window->bin));
+ if (child)
+ gtk_widget_unmap (child);
}
static void
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,81 @@
From 4f27e87d62b480a49dcffc232e246295c32113ca Mon Sep 17 00:00:00 2001
From: Kjell Ahlstedt <kjell.ahlstedt@bredband.net>
Date: Wed, 16 Nov 2011 09:03:12 +0100
Subject: [PATCH 02/68] Maintain map/unmap invariants in
GtkRecentChooserDialog
We used to explicitly map and unmap the child GtkRecentChooserWidget when
mapping and unmapping the dialog, respectively. Now that GtkContainer actually
unmaps child widgets (instead of avoiding that), we can assume that the
child GtkRecentChooserWidget will be unmapped when we want it to be.
This fixes a warning from gtk_widget_verify_invariants(), as we were mapping
our child widget before calling our parent class' ::map() handler. Bug #659257.
(cherry picked from commit e8bb2e4545365d83261381a14920b773aba4a678)
---
gtk/gtkrecentchooserdialog.c | 30 ------------------------------
1 file changed, 30 deletions(-)
diff --git a/gtk/gtkrecentchooserdialog.c b/gtk/gtkrecentchooserdialog.c
index 058439a..1c67b7a 100644
--- a/gtk/gtkrecentchooserdialog.c
+++ b/gtk/gtkrecentchooserdialog.c
@@ -55,9 +55,6 @@ static void gtk_recent_chooser_dialog_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
-static void gtk_recent_chooser_dialog_map (GtkWidget *widget);
-static void gtk_recent_chooser_dialog_unmap (GtkWidget *widget);
-
G_DEFINE_TYPE_WITH_CODE (GtkRecentChooserDialog,
gtk_recent_chooser_dialog,
GTK_TYPE_DIALOG,
@@ -68,16 +65,12 @@ static void
gtk_recent_chooser_dialog_class_init (GtkRecentChooserDialogClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gobject_class->set_property = gtk_recent_chooser_dialog_set_property;
gobject_class->get_property = gtk_recent_chooser_dialog_get_property;
gobject_class->constructor = gtk_recent_chooser_dialog_constructor;
gobject_class->finalize = gtk_recent_chooser_dialog_finalize;
- widget_class->map = gtk_recent_chooser_dialog_map;
- widget_class->unmap = gtk_recent_chooser_dialog_unmap;
-
_gtk_recent_chooser_install_properties (gobject_class);
g_type_class_add_private (klass, sizeof (GtkRecentChooserDialogPrivate));
@@ -224,29 +217,6 @@ gtk_recent_chooser_dialog_finalize (GObject *object)
G_OBJECT_CLASS (gtk_recent_chooser_dialog_parent_class)->finalize (object);
}
-static void
-gtk_recent_chooser_dialog_map (GtkWidget *widget)
-{
- GtkRecentChooserDialog *dialog = GTK_RECENT_CHOOSER_DIALOG (widget);
- GtkRecentChooserDialogPrivate *priv = dialog->priv;
-
- if (!gtk_widget_get_mapped (priv->chooser))
- gtk_widget_map (priv->chooser);
-
- GTK_WIDGET_CLASS (gtk_recent_chooser_dialog_parent_class)->map (widget);
-}
-
-static void
-gtk_recent_chooser_dialog_unmap (GtkWidget *widget)
-{
- GtkRecentChooserDialog *dialog = GTK_RECENT_CHOOSER_DIALOG (widget);
- GtkRecentChooserDialogPrivate *priv = dialog->priv;
-
- GTK_WIDGET_CLASS (gtk_recent_chooser_dialog_parent_class)->unmap (widget);
-
- gtk_widget_unmap (priv->chooser);
-}
-
static GtkWidget *
gtk_recent_chooser_dialog_new_valist (const gchar *title,
GtkWindow *parent,
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,57 @@
From 41c694a884284280c8ac766e636dd344493509e4 Mon Sep 17 00:00:00 2001
From: Matthias Clasen <mclasen@redhat.com>
Date: Fri, 2 Sep 2011 21:40:42 -0400
Subject: [PATCH 03/68] GtkPlug: preserve map/unmap invariants (cherry picked
from commit be152f9b6196849c99c54afe5a0f651d08bf4626)
---
gtk/gtkplug.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/gtk/gtkplug.c b/gtk/gtkplug.c
index 99af62a..86dd85e 100644
--- a/gtk/gtkplug.c
+++ b/gtk/gtkplug.c
@@ -708,13 +708,15 @@ gtk_plug_map (GtkWidget *widget)
{
GtkBin *bin = GTK_BIN (widget);
GtkPlug *plug = GTK_PLUG (widget);
-
+ GtkWidget *child;
+
gtk_widget_set_mapped (widget, TRUE);
- if (bin->child &&
- gtk_widget_get_visible (bin->child) &&
- !gtk_widget_get_mapped (bin->child))
- gtk_widget_map (bin->child);
+ child = gtk_bin_get_child (bin);
+ if (child != NULL &&
+ gtk_widget_get_visible (child) &&
+ !gtk_widget_get_mapped (child))
+ gtk_widget_map (child);
_gtk_plug_windowing_map_toplevel (plug);
@@ -732,13 +734,18 @@ gtk_plug_unmap (GtkWidget *widget)
if (gtk_widget_is_toplevel (widget))
{
GtkPlug *plug = GTK_PLUG (widget);
+ GtkWidget *child;
gtk_widget_set_mapped (widget, FALSE);
gdk_window_hide (widget->window);
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child != NULL)
+ gtk_widget_unmap (child);
+
_gtk_plug_windowing_unmap_toplevel (plug);
-
+
gdk_synthesize_window_state (widget->window,
0,
GDK_WINDOW_STATE_WITHDRAWN);
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,368 @@
From 8636b3d980cdef4c12f53779f708cc4a674d1054 Mon Sep 17 00:00:00 2001
From: Michael Natterer <mitch@gimp.org>
Date: Fri, 23 Nov 2012 15:24:36 +0100
Subject: [PATCH 04/68] Add gdk_screen_get_monitor_workarea() and use it all
over the place
---
gdk/gdk.symbols | 1 +
gdk/gdkscreen.h | 3 +++
gdk/quartz/gdkscreen-quartz.c | 30 ++++++++++++++++++++++++++++++
gtk/gtkcombobox.c | 4 ++--
gtk/gtkentry.c | 2 +-
gtk/gtkentrycompletion.c | 2 +-
gtk/gtkfilechooserdefault.c | 2 +-
gtk/gtklinkbutton.c | 2 +-
gtk/gtkmenu.c | 6 +++---
gtk/gtkmenuitem.c | 2 +-
gtk/gtkmenutoolbutton.c | 2 +-
gtk/gtkrecentchooserdefault.c | 4 ++--
gtk/gtkscalebutton.c | 2 +-
gtk/gtkstatusicon.c | 4 ++--
gtk/gtktextview.c | 2 +-
gtk/gtktoolbar.c | 2 +-
gtk/gtktooltip.c | 2 +-
gtk/gtktreeview.c | 2 +-
gtk/gtkwindow.c | 6 +++---
19 files changed, 57 insertions(+), 23 deletions(-)
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index d4f2072..feed787 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -1169,6 +1169,7 @@ gdk_screen_get_default_colormap
gdk_screen_set_default_colormap
gdk_screen_get_n_monitors
gdk_screen_get_monitor_geometry
+gdk_screen_get_monitor_workarea
gdk_screen_get_monitor_width_mm
gdk_screen_get_monitor_height_mm
gdk_screen_get_monitor_plug_name
diff --git a/gdk/gdkscreen.h b/gdk/gdkscreen.h
index 418cecf..d3d4fe9 100644
--- a/gdk/gdkscreen.h
+++ b/gdk/gdkscreen.h
@@ -95,6 +95,9 @@ gint gdk_screen_get_primary_monitor (GdkScreen *screen);
void gdk_screen_get_monitor_geometry (GdkScreen *screen,
gint monitor_num,
GdkRectangle *dest);
+void gdk_screen_get_monitor_workarea (GdkScreen *screen,
+ gint monitor_num,
+ GdkRectangle *dest);
gint gdk_screen_get_monitor_at_point (GdkScreen *screen,
gint x,
gint y);
diff --git a/gdk/quartz/gdkscreen-quartz.c b/gdk/quartz/gdkscreen-quartz.c
index 796fcb5..4bb573b 100644
--- a/gdk/quartz/gdkscreen-quartz.c
+++ b/gdk/quartz/gdkscreen-quartz.c
@@ -464,6 +464,36 @@ gdk_screen_get_monitor_geometry (GdkScreen *screen,
*dest = GDK_SCREEN_QUARTZ (screen)->screen_rects[monitor_num];
}
+void
+gdk_screen_get_monitor_workarea (GdkScreen *screen,
+ gint monitor_num,
+ GdkRectangle *dest)
+{
+ GdkScreenQuartz *quartz_screen;
+ NSArray *array;
+ NSScreen *nsscreen;
+ NSRect rect;
+
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+ g_return_if_fail (monitor_num < gdk_screen_get_n_monitors (screen));
+ g_return_if_fail (monitor_num >= 0);
+
+ quartz_screen = GDK_SCREEN_QUARTZ (screen);
+
+ GDK_QUARTZ_ALLOC_POOL;
+
+ array = [NSScreen screens];
+ nsscreen = [array objectAtIndex:monitor_num];
+ rect = [nsscreen visibleFrame];
+
+ dest->x = rect.origin.x - quartz_screen->min_x;
+ dest->y = quartz_screen->height - (rect.origin.y + rect.size.height) + quartz_screen->min_y;
+ dest->width = rect.size.width;
+ dest->height = rect.size.height;
+
+ GDK_QUARTZ_RELEASE_POOL;
+}
+
gchar *
gdk_screen_make_display_name (GdkScreen *screen)
{
diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c
index dc912a3..d997d0d 100644
--- a/gtk/gtkcombobox.c
+++ b/gtk/gtkcombobox.c
@@ -1667,7 +1667,7 @@ gtk_combo_box_menu_position_below (GtkMenu *menu,
screen = gtk_widget_get_screen (GTK_WIDGET (combo_box));
monitor_num = gdk_screen_get_monitor_at_window (screen,
GTK_WIDGET (combo_box)->window);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
if (*x < monitor.x)
*x = monitor.x;
@@ -1836,7 +1836,7 @@ gtk_combo_box_list_position (GtkComboBox *combo_box,
screen = gtk_widget_get_screen (GTK_WIDGET (combo_box));
monitor_num = gdk_screen_get_monitor_at_window (screen,
GTK_WIDGET (combo_box)->window);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
if (*x < monitor.x)
*x = monitor.x;
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index e2999a3..0d16d71 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -8614,7 +8614,7 @@ popup_position_func (GtkMenu *menu,
monitor_num = 0;
gtk_menu_set_monitor (menu, monitor_num);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
gtk_widget_size_request (entry->popup_menu, &menu_req);
height = gdk_window_get_height (entry->text_area);
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL);
diff --git a/gtk/gtkentrycompletion.c b/gtk/gtkentrycompletion.c
index 2fa7b56..a8deace 100644
--- a/gtk/gtkentrycompletion.c
+++ b/gtk/gtkentrycompletion.c
@@ -1409,7 +1409,7 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
screen = gtk_widget_get_screen (GTK_WIDGET (completion->priv->entry));
monitor_num = gdk_screen_get_monitor_at_window (screen,
GTK_WIDGET (completion->priv->entry)->window);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 2a75365..f94f4d6 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -4100,7 +4100,7 @@ popup_position_func (GtkMenu *menu,
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
gtk_menu_set_monitor (menu, monitor_num);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
*x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
*y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
diff --git a/gtk/gtklinkbutton.c b/gtk/gtklinkbutton.c
index bae8ec3..45d64b2 100644
--- a/gtk/gtklinkbutton.c
+++ b/gtk/gtklinkbutton.c
@@ -374,7 +374,7 @@ popup_position_func (GtkMenu *menu,
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
gtk_menu_set_monitor (menu, monitor_num);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
*x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
*y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index fc25098..44972b2 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -993,7 +993,7 @@ gtk_menu_window_size_request (GtkWidget *window,
GdkScreen *screen = gtk_widget_get_screen (window);
GdkRectangle monitor;
- gdk_screen_get_monitor_geometry (screen, private->monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, private->monitor_num, &monitor);
if (private->y + requisition->height > monitor.y + monitor.height)
requisition->height = monitor.y + monitor.height - private->y;
@@ -4231,7 +4231,7 @@ gtk_menu_position (GtkMenu *menu)
if (private->monitor_num < 0)
private->monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
- gdk_screen_get_monitor_geometry (screen, private->monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, private->monitor_num, &monitor);
}
else
{
@@ -4260,7 +4260,7 @@ gtk_menu_position (GtkMenu *menu)
* Positioning in the vertical direction is similar: first try below
* mouse cursor, then above.
*/
- gdk_screen_get_monitor_geometry (screen, private->monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, private->monitor_num, &monitor);
space_left = x - monitor.x;
space_right = monitor.x + monitor.width - x - 1;
diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c
index 8f23b75..ffc2db6 100644
--- a/gtk/gtkmenuitem.c
+++ b/gtk/gtkmenuitem.c
@@ -1717,7 +1717,7 @@ gtk_menu_item_position_menu (GtkMenu *menu,
monitor_num = gdk_screen_get_monitor_at_window (screen, menu_item->event_window);
if (monitor_num < 0)
monitor_num = 0;
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
if (!gdk_window_get_origin (widget->window, &tx, &ty))
{
diff --git a/gtk/gtkmenutoolbutton.c b/gtk/gtkmenutoolbutton.c
index 0c464e8..e254e1b 100644
--- a/gtk/gtkmenutoolbutton.c
+++ b/gtk/gtkmenutoolbutton.c
@@ -287,7 +287,7 @@ menu_position_func (GtkMenu *menu,
monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
if (monitor_num < 0)
monitor_num = 0;
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
diff --git a/gtk/gtkrecentchooserdefault.c b/gtk/gtkrecentchooserdefault.c
index 1ab48e2..fe2a772 100644
--- a/gtk/gtkrecentchooserdefault.c
+++ b/gtk/gtkrecentchooserdefault.c
@@ -951,7 +951,7 @@ set_default_size (GtkRecentChooserDefault *impl)
screen = gtk_widget_get_screen (widget);
monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
width = MIN (width, monitor.width * 3 / 4);
height = MIN (height, monitor.height * 3 / 4);
@@ -1849,7 +1849,7 @@ popup_position_func (GtkMenu *menu,
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
gtk_menu_set_monitor (menu, monitor_num);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
*x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
*y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
diff --git a/gtk/gtkscalebutton.c b/gtk/gtkscalebutton.c
index df9b574..3c6fc85 100644
--- a/gtk/gtkscalebutton.c
+++ b/gtk/gtkscalebutton.c
@@ -1000,7 +1000,7 @@ gtk_scale_popup (GtkWidget *widget,
monitor = gdk_screen_get_monitor_at_point (screen,
button_event->x_root,
button_event->y_root);
- gdk_screen_get_monitor_geometry (screen, monitor, &rect);
+ gdk_screen_get_monitor_workarea (screen, monitor, &rect);
if (priv->orientation == GTK_ORIENTATION_VERTICAL)
y += button_event->y;
diff --git a/gtk/gtkstatusicon.c b/gtk/gtkstatusicon.c
index 77d93da..c6d3097 100644
--- a/gtk/gtkstatusicon.c
+++ b/gtk/gtkstatusicon.c
@@ -648,7 +648,7 @@ build_button_event (GtkStatusIconPrivate *priv,
GdkRectangle monitor0;
/* We know that gdk/win32 puts the primary monitor at index 0 */
- gdk_screen_get_monitor_geometry (gdk_screen_get_default (), 0, &monitor0);
+ gdk_screen_get_monitor_workarea (gdk_screen_get_default (), 0, &monitor0);
e->window = g_object_ref (gdk_get_default_root_window ());
e->send_event = TRUE;
e->time = GetTickCount ();
@@ -2512,7 +2512,7 @@ gtk_status_icon_position_menu (GtkMenu *menu,
monitor_num = 0;
gtk_menu_set_monitor (menu, monitor_num);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
gdk_window_get_origin (widget->window, x, y);
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 9ddddec..419cced 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -7845,7 +7845,7 @@ popup_position_func (GtkMenu *menu,
monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
gtk_menu_set_monitor (menu, monitor_num);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
*x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
*y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c
index b2c4b15..fc1e588 100644
--- a/gtk/gtktoolbar.c
+++ b/gtk/gtktoolbar.c
@@ -2618,7 +2618,7 @@ menu_position_func (GtkMenu *menu,
monitor_num = gdk_screen_get_monitor_at_window (screen, priv->arrow_button->window);
if (monitor_num < 0)
monitor_num = 0;
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
diff --git a/gtk/gtktooltip.c b/gtk/gtktooltip.c
index 9918165..fb6e869 100644
--- a/gtk/gtktooltip.c
+++ b/gtk/gtktooltip.c
@@ -1139,7 +1139,7 @@ gtk_tooltip_position (GtkTooltip *tooltip,
&requisition);
monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
if (x + requisition.width > monitor.x + monitor.width)
x -= x - (monitor.x + monitor.width) + requisition.width;
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index eccd20c..cca1d3d 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -14251,7 +14251,7 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view,
GdkRectangle monitor;
monitor_num = gdk_screen_get_monitor_at_window (screen, tree_window);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
gtk_widget_realize (search_dialog);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 8f174c6..7094eb6 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -5771,7 +5771,7 @@ center_window_on_monitor (GtkWindow *window,
if (monitor_num == -1)
monitor_num = get_center_monitor_of_window (window);
- gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
+ gdk_screen_get_monitor_workarea (gtk_window_check_screen (window),
monitor_num, &monitor);
*x = (monitor.width - w) / 2 + monitor.x;
@@ -5917,7 +5917,7 @@ gtk_window_compute_configure_request (GtkWindow *window,
*/
if (monitor_num >= 0)
{
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
clamp_window_to_rectangle (&x, &y, w, h, &monitor);
}
}
@@ -5952,7 +5952,7 @@ gtk_window_compute_configure_request (GtkWindow *window,
*/
if (monitor_num >= 0)
{
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
clamp_window_to_rectangle (&x, &y, w, h, &monitor);
}
}
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,61 @@
From df766e7dc27c8bc373dd5eaeaa5bddb7702605fd Mon Sep 17 00:00:00 2001
From: Michael Natterer <mitch@gimp.org>
Date: Fri, 23 Nov 2012 15:28:26 +0100
Subject: [PATCH 05/68] gtk: don't scroll combo box menus if less than 3
itemss are visible
---
gtk/gtkcombobox.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c
index d997d0d..3b58f32 100644
--- a/gtk/gtkcombobox.c
+++ b/gtk/gtkcombobox.c
@@ -1781,6 +1781,44 @@ gtk_combo_box_menu_position (GtkMenu *menu,
menu_item);
gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data);
+
+ if (menu_item)
+ {
+ GdkScreen *screen;
+ GtkWidget *widget = GTK_WIDGET (combo_box);
+ gint monitor_num;
+ GdkRectangle monitor;
+ gint px, py;
+ gint menu_height;
+ gint scroll_offset = 0;
+
+ screen = gtk_widget_get_screen (widget);
+ gdk_display_get_pointer (gdk_screen_get_display (screen),
+ NULL, &px, &py, NULL);
+
+ monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
+
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
+
+ menu_height = GTK_WIDGET (menu)->requisition.height;
+
+ if (*y + menu_height > monitor.y + monitor.height)
+ {
+ scroll_offset -= *y + menu_height - (monitor.y + monitor.height);
+ }
+ else if (*y < monitor.y)
+ {
+ scroll_offset += monitor.y - *y;
+ }
+
+ /* don't scroll the menu if less than 3 items would be visible,
+ * use 4 to roughly take the scroll buttons into account
+ */
+ if (scroll_offset != 0 &&
+ (menu->toplevel->requisition.height - ABS (scroll_offset) <
+ 5 * menu_item->requisition.height))
+ gtk_combo_box_menu_position_below (menu, x, y, push_in, user_data);
+ }
}
if (!gtk_widget_get_visible (GTK_MENU (priv->popup_widget)->toplevel))
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,47 @@
From 37f07504f203aec1345a75abeb07172259bd5973 Mon Sep 17 00:00:00 2001
From: Michael Natterer <mitch@gimp.org>
Date: Sun, 27 May 2012 22:51:33 +0200
Subject: [PATCH 06/68] gtk: paint only the exposed region in
gdk_window_expose()
---
gtk/gtkwindow.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 7094eb6..89c91da 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -6631,13 +6631,28 @@ gtk_window_paint (GtkWidget *widget,
GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
}
+static void
+gtk_window_paint_region (GtkWidget *widget,
+ GdkRegion *region)
+{
+ int i, n_rectangles;
+ GdkRectangle *rectangles = NULL;
+
+ gdk_region_get_rectangles (region, &rectangles, &n_rectangles);
+
+ for (i = 0; i < n_rectangles; i++)
+ gtk_window_paint (widget, &rectangles[i]);
+
+ g_free (rectangles);
+}
+
static gint
gtk_window_expose (GtkWidget *widget,
GdkEventExpose *event)
{
if (!gtk_widget_get_app_paintable (widget))
- gtk_window_paint (widget, &event->area);
-
+ gtk_window_paint_region (widget, event->region);
+
if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,133 @@
From 4c79075b4d396ba009b0f0e70d05c1c253cc3da6 Mon Sep 17 00:00:00 2001
From: Kristian Rietveld <kris@lanedo.com>
Date: Fri, 24 Aug 2012 12:12:04 +0200
Subject: [PATCH 07/68] Implement gtk-enable-overlay-scrollbars GtkSetting
And set this up such that on OS X
NSPreferredScrollerDidChangeNotification is followed.
---
gdk/quartz/gdkevents-quartz.c | 56 ++++++++++++++++++++++++++++++++++++++++-
gtk/gtksettings.c | 20 ++++++++++++++-
2 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
index 53f1962..c99a2c9 100644
--- a/gdk/quartz/gdkevents-quartz.c
+++ b/gdk/quartz/gdkevents-quartz.c
@@ -85,6 +85,10 @@ gdk_quartz_ns_notification_callback (CFNotificationCenterRef center,
CFSTR("AppleNoRedisplayAppearancePreferenceChanged"),
0) == kCFCompareEqualTo)
new_event.setting.name = "gtk-primary-button-warps-slider";
+ else if (CFStringCompare (name,
+ CFSTR("NSPreferredScrollerStyleDidChangeNotification"),
+ 0) == kCFCompareEqualTo)
+ new_event.setting.name = "gtk-enable-overlay-scrollbars";
if (!new_event.setting.name)
return;
@@ -114,6 +118,20 @@ gdk_quartz_events_init_notifications (void)
CFSTR ("AppleNoRedisplayAppearancePreferenceChanged"),
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
+
+ /* The preferred scroller notification and property are only available on Lion
+ * and higher. Also, beware that the notification will only start working after the
+ * property has been queried for the first time!.
+ */
+ if (gdk_quartz_osx_version () >= GDK_OSX_LION)
+ {
+ CFNotificationCenterAddObserver (CFNotificationCenterGetLocalCenter (),
+ NULL,
+ &gdk_quartz_ns_notification_callback,
+ CFSTR ("NSPreferredScrollerStyleDidChangeNotification"),
+ NULL,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
+ }
}
void
@@ -1686,7 +1704,43 @@ gdk_screen_get_setting (GdkScreen *screen,
return TRUE;
}
-
+ else if (strcmp (name, "gtk-enable-overlay-scrollbars") == 0)
+ {
+ gboolean enabled = FALSE;
+
+ GDK_QUARTZ_ALLOC_POOL;
+
+ if (gdk_quartz_osx_version () >= GDK_OSX_LION)
+ {
+ /* Use an integer instead of NSScrollerStyle to allow things to be compiled
+ * on < 10.7 systems.
+ */
+ int setting = (int)[NSScroller preferredScrollerStyle];
+
+ if (setting == 1)
+ /* 1 == NSScrollerStyleOverlay */
+ enabled = TRUE;
+ else
+ enabled = FALSE;
+ }
+ else
+ {
+ /* On systems prior to Lion, default to legacy scrolling. */
+ enabled = FALSE;
+ }
+
+ g_value_set_boolean (value, enabled);
+
+ /* Initialize after quering the property for the first theme,
+ * notifications are otherwise not received!
+ */
+ gdk_quartz_events_init_notifications ();
+
+ GDK_QUARTZ_RELEASE_POOL;
+
+ return TRUE;
+ }
+
/* FIXME: Add more settings */
return FALSE;
diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c
index 3fbbf00..1455db1 100644
--- a/gtk/gtksettings.c
+++ b/gtk/gtksettings.c
@@ -139,7 +139,8 @@ enum {
PROP_LABEL_SELECT_ON_FOCUS,
PROP_COLOR_PALETTE,
PROP_IM_PREEDIT_STYLE,
- PROP_IM_STATUS_STYLE
+ PROP_IM_STATUS_STYLE,
+ PROP_ENABLE_OVERLAY_SCROLLBARS
};
/* --- prototypes --- */
@@ -1205,6 +1206,23 @@ gtk_settings_class_init (GtkSettingsClass *class)
GTK_PARAM_READWRITE),
gtk_rc_property_parse_enum);
g_assert (result == PROP_IM_STATUS_STYLE);
+
+ /**
+ * GtkSettings:gtk-enable-overlay-scrollbars:
+ *
+ * Whether overlay scrollbars should be enabled.
+ *
+ * Since: Xamarin specific API.
+ */
+ result = settings_install_property_parser (class,
+ g_param_spec_boolean ("gtk-enable-overlay-scrollbars",
+ P_("Enable Overlay Scrollbars"),
+ P_("Whether to enable overlay scrollbars."),
+ FALSE,
+ GTK_PARAM_READWRITE),
+ NULL);
+
+ g_assert (result == PROP_ENABLE_OVERLAY_SCROLLBARS);
}
static void
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,418 @@
From ab426801023babba7513d9e27a4dbdd44bdbc318 Mon Sep 17 00:00:00 2001
From: Michael Natterer <mitch@gimp.org>
Date: Tue, 8 May 2012 14:11:50 +0200
Subject: [PATCH 08/68] Smooth scrolling
---
gdk/gdkevents.c | 32 +++++++++++++++++
gdk/gdkevents.h | 6 ++++
gdk/gdkwindow.c | 3 ++
gdk/quartz/gdkevents-quartz.c | 80 +++++++++++++++++++++++++++++++----------
gtk/gtkrange.c | 51 +++++++++++++++++++-------
gtk/gtkrange.h | 4 +--
gtk/gtkscrolledwindow.c | 74 ++++++++++++++++++++++++++++++--------
7 files changed, 203 insertions(+), 47 deletions(-)
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 53833a0..0f8bba2 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -392,6 +392,8 @@ gdk_event_new (GdkEventType type)
new_event->scroll.y = 0.;
new_event->scroll.x_root = 0.;
new_event->scroll.y_root = 0.;
+ new_event->scroll.delta_x = 0.;
+ new_event->scroll.delta_y = 0.;
break;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
@@ -845,6 +847,36 @@ gdk_event_get_root_coords (const GdkEvent *event,
return fetched;
}
+gboolean
+gdk_event_get_scroll_deltas (const GdkEvent *event,
+ gdouble *delta_x,
+ gdouble *delta_y)
+{
+ gboolean fetched = TRUE;
+ gdouble dx = 0.0;
+ gdouble dy = 0.0;
+
+ switch (event->type)
+ {
+ case GDK_SCROLL:
+ fetched = event->scroll.has_deltas;
+ dx = event->scroll.delta_x;
+ dy = event->scroll.delta_y;
+ break;
+ default:
+ fetched = FALSE;
+ break;
+ }
+
+ if (delta_x)
+ *delta_x = dx;
+
+ if (delta_y)
+ *delta_y = dy;
+
+ return fetched;
+}
+
/**
* gdk_event_get_axis:
* @event: a #GdkEvent
diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h
index 0602bd0..f6b4e04 100644
--- a/gdk/gdkevents.h
+++ b/gdk/gdkevents.h
@@ -337,6 +337,9 @@ struct _GdkEventScroll
GdkScrollDirection direction;
GdkDevice *device;
gdouble x_root, y_root;
+ gboolean has_deltas;
+ gdouble delta_x;
+ gdouble delta_y;
};
struct _GdkEventKey
@@ -537,6 +540,9 @@ gboolean gdk_event_get_coords (const GdkEvent *event,
gboolean gdk_event_get_root_coords (const GdkEvent *event,
gdouble *x_root,
gdouble *y_root);
+gboolean gdk_event_get_scroll_deltas (const GdkEvent *event,
+ gdouble *delta_x,
+ gdouble *delta_y);
gboolean gdk_event_get_axis (const GdkEvent *event,
GdkAxisUse axis_use,
gdouble *value);
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index f5f0339..d48751e 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -10800,6 +10800,9 @@ proxy_button_event (GdkEvent *source_event,
event->scroll.y_root = source_event->scroll.y_root;
event->scroll.state = state;
event->scroll.device = source_event->scroll.device;
+ event->scroll.has_deltas = source_event->scroll.has_deltas;
+ event->scroll.delta_x = source_event->scroll.delta_x;
+ event->scroll.delta_y = source_event->scroll.delta_y;
return TRUE;
default:
diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
index c99a2c9..e7d97dc 100644
--- a/gdk/quartz/gdkevents-quartz.c
+++ b/gdk/quartz/gdkevents-quartz.c
@@ -57,6 +57,13 @@ static GdkWindow *find_toplevel_under_pointer (GdkDisplay *display,
gint *x,
gint *y);
+/* Protocol to build cleanly for OSX < 10.7 */
+@protocol PreciseDeltas
+- (BOOL) hasPreciseScrollingDeltas;
+- (CGFloat) scrollingDeltaX;
+- (CGFloat) scrollingDeltaY;
+@end
+
NSEvent *
gdk_quartz_event_get_nsevent (GdkEvent *event)
@@ -980,6 +987,9 @@ fill_scroll_event (GdkWindow *window,
gint y,
gint x_root,
gint y_root,
+ gboolean has_deltas,
+ gdouble delta_x,
+ gdouble delta_y,
GdkScrollDirection direction)
{
GdkWindowObject *private;
@@ -999,6 +1009,9 @@ fill_scroll_event (GdkWindow *window,
event->scroll.state = get_keyboard_modifiers_from_ns_event (nsevent);
event->scroll.direction = direction;
event->scroll.device = _gdk_display->core_pointer;
+ event->scroll.has_deltas = has_deltas;
+ event->scroll.delta_x = delta_x;
+ event->scroll.delta_y = delta_y;
}
static void
@@ -1471,28 +1484,59 @@ gdk_event_translate (GdkEvent *event,
case NSScrollWheel:
{
- float dx = [nsevent deltaX];
- float dy = [nsevent deltaY];
- GdkScrollDirection direction;
-
- if (dy != 0)
- {
- if (dy < 0.0)
- direction = GDK_SCROLL_DOWN;
- else
- direction = GDK_SCROLL_UP;
+ GdkScrollDirection direction;
+ float dx;
+ float dy;
- fill_scroll_event (window, event, nsevent, x, y, x_root, y_root, direction);
- }
+ if (gdk_quartz_osx_version() >= GDK_OSX_LION &&
+ [(id <PreciseDeltas>) nsevent hasPreciseScrollingDeltas])
+ {
+ dx = [(id <PreciseDeltas>) nsevent scrollingDeltaX];
+ dy = [(id <PreciseDeltas>) nsevent scrollingDeltaY];
- if (dx != 0)
- {
- if (dx < 0.0)
- direction = GDK_SCROLL_RIGHT;
+ if (fabs (dy) > fabs (dx))
+ {
+ if (dy < 0.0)
+ direction = GDK_SCROLL_DOWN;
+ else
+ direction = GDK_SCROLL_UP;
+ }
else
- direction = GDK_SCROLL_LEFT;
+ {
+ if (dx < 0.0)
+ direction = GDK_SCROLL_RIGHT;
+ else
+ direction = GDK_SCROLL_LEFT;
+ }
- fill_scroll_event (window, event, nsevent, x, y, x_root, y_root, direction);
+ fill_scroll_event (window, event, nsevent, x, y, x_root, y_root,
+ TRUE, -dx, -dy, direction);
+ }
+ else
+ {
+ dx = [nsevent deltaX];
+ dy = [nsevent deltaY];
+
+ if (dy != 0.0)
+ {
+ if (dy < 0.0)
+ direction = GDK_SCROLL_DOWN;
+ else
+ direction = GDK_SCROLL_UP;
+
+ fill_scroll_event (window, event, nsevent, x, y, x_root, y_root,
+ FALSE, 0.0, fabs (dy), direction);
+ }
+ else if (dx != 0.0)
+ {
+ if (dx < 0.0)
+ direction = GDK_SCROLL_RIGHT;
+ else
+ direction = GDK_SCROLL_LEFT;
+
+ fill_scroll_event (window, event, nsevent, x, y, x_root, y_root,
+ FALSE, fabs (dx), 0.0, direction);
+ }
}
}
break;
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index 245fbf6..d39f045 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -2561,7 +2561,7 @@ gtk_range_button_release (GtkWidget *widget,
/**
* _gtk_range_get_wheel_delta:
* @range: a #GtkRange
- * @direction: A #GdkScrollDirection
+ * @event: A #GdkEventScroll
*
* Returns a good step value for the mouse wheel.
*
@@ -2570,27 +2570,52 @@ gtk_range_button_release (GtkWidget *widget,
* Since: 2.4
**/
gdouble
-_gtk_range_get_wheel_delta (GtkRange *range,
- GdkScrollDirection direction)
+_gtk_range_get_wheel_delta (GtkRange *range,
+ GdkEventScroll *event)
{
GtkAdjustment *adj = range->adjustment;
+ gdouble dx, dy;
gdouble delta;
- if (GTK_IS_SCROLLBAR (range))
- delta = pow (adj->page_size, 2.0 / 3.0);
+ if (gdk_event_get_scroll_deltas ((GdkEvent *) event, &dx, &dy))
+ {
+ GtkAllocation allocation;
+
+ gtk_widget_get_allocation (GTK_WIDGET (range), &allocation);
+
+ if (gtk_orientable_get_orientation (GTK_ORIENTABLE (range)) == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (GTK_IS_SCROLLBAR (range) && adj->page_size > 0)
+ delta = dx * adj->page_size / allocation.width;
+ else
+ delta = dx * (adj->upper - adj->lower) / allocation.width;
+ }
+ else
+ {
+ if (GTK_IS_SCROLLBAR (range) && adj->page_size > 0)
+ delta = dy * adj->page_size / allocation.height;
+ else
+ delta = dy * (adj->upper - adj->lower) / allocation.height;
+ }
+ }
else
- delta = adj->step_increment * 2;
-
- if (direction == GDK_SCROLL_UP ||
- direction == GDK_SCROLL_LEFT)
- delta = - delta;
-
+ {
+ if (GTK_IS_SCROLLBAR (range))
+ delta = pow (adj->page_size, 2.0 / 3.0);
+ else
+ delta = adj->step_increment * 2;
+
+ if (event->direction == GDK_SCROLL_UP ||
+ event->direction == GDK_SCROLL_LEFT)
+ delta = - delta;
+ }
+
if (range->inverted)
delta = - delta;
return delta;
}
-
+
static gboolean
gtk_range_scroll_event (GtkWidget *widget,
GdkEventScroll *event)
@@ -2603,7 +2628,7 @@ gtk_range_scroll_event (GtkWidget *widget,
gdouble delta;
gboolean handled;
- delta = _gtk_range_get_wheel_delta (range, event->direction);
+ delta = _gtk_range_get_wheel_delta (range, event);
g_signal_emit (range, signals[CHANGE_VALUE], 0,
GTK_SCROLL_JUMP, adj->value + delta,
diff --git a/gtk/gtkrange.h b/gtk/gtkrange.h
index 5463140..c672acb 100644
--- a/gtk/gtkrange.h
+++ b/gtk/gtkrange.h
@@ -199,8 +199,8 @@ gint gtk_range_get_round_digits (GtkRange *range
/* internal API */
-gdouble _gtk_range_get_wheel_delta (GtkRange *range,
- GdkScrollDirection direction);
+gdouble _gtk_range_get_wheel_delta (GtkRange *range,
+ GdkEventScroll *event);
void _gtk_range_set_stop_values (GtkRange *range,
gdouble *values,
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 1704d3c..2288b2f 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -1565,31 +1565,77 @@ static gboolean
gtk_scrolled_window_scroll_event (GtkWidget *widget,
GdkEventScroll *event)
{
- GtkWidget *range;
+ GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
+ gboolean handled = FALSE;
+ gdouble delta_x;
+ gdouble delta_y;
g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
- if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_DOWN)
- range = GTK_SCROLLED_WINDOW (widget)->vscrollbar;
- else
- range = GTK_SCROLLED_WINDOW (widget)->hscrollbar;
+ if (gdk_event_get_scroll_deltas ((GdkEvent *) event, &delta_x, &delta_y))
+ {
+ if (delta_x != 0.0 && scrolled_window->hscrollbar &&
+ gtk_widget_get_visible (scrolled_window->hscrollbar))
+ {
+ GtkAdjustment *adj;
+ gdouble new_value;
+
+ adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar));
+
+ new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_x,
+ gtk_adjustment_get_lower (adj),
+ gtk_adjustment_get_upper (adj) -
+ gtk_adjustment_get_page_size (adj));
+
+ gtk_adjustment_set_value (adj, new_value);
+
+ handled = TRUE;
+ }
+
+ if (delta_y != 0.0 && scrolled_window->vscrollbar &&
+ gtk_widget_get_visible (scrolled_window->vscrollbar))
+ {
+ GtkAdjustment *adj;
+ gdouble new_value;
+
+ adj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar));
+
+ new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_y,
+ gtk_adjustment_get_lower (adj),
+ gtk_adjustment_get_upper (adj) -
+ gtk_adjustment_get_page_size (adj));
- if (range && gtk_widget_get_visible (range))
+ gtk_adjustment_set_value (adj, new_value);
+
+ handled = TRUE;
+ }
+ }
+ else
{
- GtkAdjustment *adj = GTK_RANGE (range)->adjustment;
- gdouble delta, new_value;
+ GtkWidget *range;
- delta = _gtk_range_get_wheel_delta (GTK_RANGE (range), event->direction);
+ if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_DOWN)
+ range = scrolled_window->vscrollbar;
+ else
+ range = scrolled_window->hscrollbar;
- new_value = CLAMP (adj->value + delta, adj->lower, adj->upper - adj->page_size);
-
- gtk_adjustment_set_value (adj, new_value);
+ if (range && gtk_widget_get_visible (range))
+ {
+ GtkAdjustment *adj = GTK_RANGE (range)->adjustment;
+ gdouble delta, new_value;
- return TRUE;
+ delta = _gtk_range_get_wheel_delta (GTK_RANGE (range), event);
+
+ new_value = CLAMP (adj->value + delta, adj->lower, adj->upper - adj->page_size);
+
+ gtk_adjustment_set_value (adj, new_value);
+
+ handled = TRUE;
+ }
}
- return FALSE;
+ return handled;
}
static gboolean
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,471 @@
From a484a0af1fc0ab98694c13970a308edeb52f39a6 Mon Sep 17 00:00:00 2001
From: Carlos Garcia Campos <cgarcia@igalia.com>
Date: Tue, 8 Feb 2011 14:49:31 +0100
Subject: [PATCH 09/68] gtk: Add a way to do event capture
This patch adds a capture phase to GTK+'s event propagation
model. Events are first propagated from the toplevel (or the
grab widget, if a grab is in place) down to the target widget
and then back up. The second phase is using the existing
::event signal, the new capture phase is using a private
API instead of a public signal for now.
This mechanism can be used in many places where we currently
have to prevent child widgets from getting events by putting
an input-only window over them. It will also be used to implement
kinetic scrolling in subsequent patches.
http://bugzilla.gnome.org/show_bug.cgi?id=641836
We automatically request more motion events in behalf of
the original widget if it listens to motion hints. So
the capturing widget doesn't need to handle such
implementation details.
We are not making event capture part of the public API for 3.4,
which is why there is no ::captured-event signal.
Conflicts:
gtk/gtkmain.c
gtk/gtkwidget.c
gtk/gtkwidgetprivate.h
---
gtk/gtkmain.c | 268 +++++++++++++++++++++++++++++++++++-------------------
gtk/gtkprivate.h | 14 +++
gtk/gtkwidget.c | 53 +++++++++++
3 files changed, 241 insertions(+), 94 deletions(-)
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 56c92db..21345ed 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1490,7 +1490,8 @@ void
gtk_main_do_event (GdkEvent *event)
{
GtkWidget *event_widget;
- GtkWidget *grab_widget;
+ GtkWidget *grab_widget = NULL;
+ GtkWidget *topmost_widget = NULL;
GtkWindowGroup *window_group;
GdkEvent *rewritten_event = NULL;
GList *tmp_list;
@@ -1552,7 +1553,14 @@ gtk_main_do_event (GdkEvent *event)
if (window_group->grabs)
{
grab_widget = window_group->grabs->data;
-
+
+ /* Find out the topmost widget where captured event propagation
+ * should start, which is the widget holding the GTK+ grab
+ * if any, otherwise it's left NULL and events are emitted
+ * from the toplevel (or topmost parentless parent).
+ */
+ topmost_widget = grab_widget;
+
/* If the grab widget is an ancestor of the event widget
* then we send the event to the original event widget.
* This is the key to implementing modality.
@@ -1636,14 +1644,16 @@ gtk_main_do_event (GdkEvent *event)
case GDK_WINDOW_STATE:
case GDK_GRAB_BROKEN:
case GDK_DAMAGE:
- gtk_widget_event (event_widget, event);
+ if (!_gtk_widget_captured_event (event_widget, event))
+ gtk_widget_event (event_widget, event);
break;
case GDK_SCROLL:
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
- gtk_propagate_event (grab_widget, event);
+ if (!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
+ gtk_propagate_event (grab_widget, event);
break;
case GDK_KEY_PRESS:
@@ -1682,19 +1692,22 @@ gtk_main_do_event (GdkEvent *event)
case GDK_BUTTON_RELEASE:
case GDK_PROXIMITY_IN:
case GDK_PROXIMITY_OUT:
- gtk_propagate_event (grab_widget, event);
+ if (!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
+ gtk_propagate_event (grab_widget, event);
break;
case GDK_ENTER_NOTIFY:
GTK_PRIVATE_SET_FLAG (event_widget, GTK_HAS_POINTER);
_gtk_widget_set_pointer_window (event_widget, event->any.window);
- if (gtk_widget_is_sensitive (grab_widget))
+ if (gtk_widget_is_sensitive (grab_widget) &&
+ !_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
gtk_widget_event (grab_widget, event);
break;
case GDK_LEAVE_NOTIFY:
GTK_PRIVATE_UNSET_FLAG (event_widget, GTK_HAS_POINTER);
- if (gtk_widget_is_sensitive (grab_widget))
+ if (gtk_widget_is_sensitive (grab_widget) &&
+ !_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
gtk_widget_event (grab_widget, event);
break;
@@ -2400,44 +2413,96 @@ gtk_quit_invoke_function (GtkQuitFunction *quitf)
}
}
-/**
- * gtk_propagate_event:
- * @widget: a #GtkWidget
- * @event: an event
- *
- * Sends an event to a widget, propagating the event to parent widgets
- * if the event remains unhandled. Events received by GTK+ from GDK
- * normally begin in gtk_main_do_event(). Depending on the type of
- * event, existence of modal dialogs, grabs, etc., the event may be
- * propagated; if so, this function is used. gtk_propagate_event()
- * calls gtk_widget_event() on each widget it decides to send the
- * event to. So gtk_widget_event() is the lowest-level function; it
- * simply emits the "event" and possibly an event-specific signal on a
- * widget. gtk_propagate_event() is a bit higher-level, and
- * gtk_main_do_event() is the highest level.
- *
- * All that said, you most likely don't want to use any of these
- * functions; synthesizing events is rarely needed. Consider asking on
- * the mailing list for better ways to achieve your goals. For
- * example, use gdk_window_invalidate_rect() or
- * gtk_widget_queue_draw() instead of making up expose events.
- *
- **/
-void
-gtk_propagate_event (GtkWidget *widget,
- GdkEvent *event)
+static gboolean
+propagate_event_up (GtkWidget *widget,
+ GdkEvent *event,
+ GtkWidget *topmost)
{
- gint handled_event;
-
- g_return_if_fail (GTK_IS_WIDGET (widget));
- g_return_if_fail (event != NULL);
-
- handled_event = FALSE;
+ gboolean handled_event = FALSE;
- g_object_ref (widget);
-
- if ((event->type == GDK_KEY_PRESS) ||
- (event->type == GDK_KEY_RELEASE))
+ /* Propagate event up the widget tree so that
+ * parents can see the button and motion
+ * events of the children.
+ */
+ while (TRUE)
+ {
+ GtkWidget *tmp;
+
+ g_object_ref (widget);
+
+ /* Scroll events are special cased here because it
+ * feels wrong when scrolling a GtkViewport, say,
+ * to have children of the viewport eat the scroll
+ * event
+ */
+ if (!gtk_widget_is_sensitive (widget))
+ handled_event = event->type != GDK_SCROLL;
+ else
+ handled_event = gtk_widget_event (widget, event);
+
+ tmp = gtk_widget_get_parent (widget);
+ g_object_unref (widget);
+
+ if (widget == topmost)
+ break;
+
+ widget = tmp;
+
+ if (handled_event || !widget)
+ break;
+ }
+
+ return handled_event;
+}
+
+static gboolean
+propagate_event_down (GtkWidget *widget,
+ GdkEvent *event,
+ GtkWidget *topmost)
+{
+ gint handled_event = FALSE;
+ GList *widgets = NULL;
+ GList *l;
+
+ widgets = g_list_prepend (widgets, g_object_ref (widget));
+ while (widget && widget != topmost)
+ {
+ widget = gtk_widget_get_parent (widget);
+ if (!widget)
+ break;
+
+ widgets = g_list_prepend (widgets, g_object_ref (widget));
+
+ if (widget == topmost)
+ break;
+ }
+
+ for (l = widgets; l && !handled_event; l = g_list_next (l))
+ {
+ widget = (GtkWidget *)l->data;
+
+ if (!gtk_widget_is_sensitive (widget))
+ handled_event = TRUE;
+ else
+ handled_event = _gtk_widget_captured_event (widget, event);
+ }
+ g_list_free_full (widgets, (GDestroyNotify)g_object_unref);
+
+ return handled_event;
+}
+
+static gboolean
+propagate_event (GtkWidget *widget,
+ GdkEvent *event,
+ gboolean captured,
+ GtkWidget *topmost)
+{
+ gboolean handled_event = FALSE;
+ gboolean (* propagate_func) (GtkWidget *widget, GdkEvent *event);
+
+ propagate_func = captured ? _gtk_widget_captured_event : gtk_widget_event;
+
+ if (event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE)
{
/* Only send key events within Window widgets to the Window
* The Window widget will in turn pass the
@@ -2448,60 +2513,75 @@ gtk_propagate_event (GtkWidget *widget,
window = gtk_widget_get_toplevel (widget);
if (GTK_IS_WINDOW (window))
- {
- /* If there is a grab within the window, give the grab widget
- * a first crack at the key event
- */
- if (widget != window && gtk_widget_has_grab (widget))
- handled_event = gtk_widget_event (widget, event);
-
- if (!handled_event)
- {
- window = gtk_widget_get_toplevel (widget);
- if (GTK_IS_WINDOW (window))
- {
- if (gtk_widget_is_sensitive (window))
- gtk_widget_event (window, event);
- }
- }
-
- handled_event = TRUE; /* don't send to widget */
- }
+ {
+ g_object_ref (widget);
+ /* If there is a grab within the window, give the grab widget
+ * a first crack at the key event
+ */
+ if (widget != window && gtk_widget_has_grab (widget))
+ handled_event = propagate_func (widget, event);
+
+ if (!handled_event)
+ {
+ window = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (window))
+ {
+ if (gtk_widget_is_sensitive (window))
+ handled_event = propagate_func (window, event);
+ }
+ }
+
+ g_object_unref (widget);
+ return handled_event;
+ }
}
-
- /* Other events get propagated up the widget tree
- * so that parents can see the button and motion
- * events of the children.
- */
- if (!handled_event)
- {
- while (TRUE)
- {
- GtkWidget *tmp;
- /* Scroll events are special cased here because it
- * feels wrong when scrolling a GtkViewport, say,
- * to have children of the viewport eat the scroll
- * event
- */
- if (!gtk_widget_is_sensitive (widget))
- handled_event = event->type != GDK_SCROLL;
- else
- handled_event = gtk_widget_event (widget, event);
-
- tmp = widget->parent;
- g_object_unref (widget);
+ /* Other events get propagated up/down the widget tree */
+ return captured ?
+ propagate_event_down (widget, event, topmost) :
+ propagate_event_up (widget, event, topmost);
+}
- widget = tmp;
-
- if (!handled_event && widget)
- g_object_ref (widget);
- else
- break;
- }
- }
- else
- g_object_unref (widget);
+/**
+ * gtk_propagate_event:
+ * @widget: a #GtkWidget
+ * @event: an event
+ *
+ * Sends an event to a widget, propagating the event to parent widgets
+ * if the event remains unhandled.
+ *
+ * Events received by GTK+ from GDK normally begin in gtk_main_do_event().
+ * Depending on the type of event, existence of modal dialogs, grabs, etc.,
+ * the event may be propagated; if so, this function is used.
+ *
+ * gtk_propagate_event() calls gtk_widget_event() on each widget it
+ * decides to send the event to. So gtk_widget_event() is the lowest-level
+ * function; it simply emits the #GtkWidget::event and possibly an
+ * event-specific signal on a widget. gtk_propagate_event() is a bit
+ * higher-level, and gtk_main_do_event() is the highest level.
+ *
+ * All that said, you most likely don't want to use any of these
+ * functions; synthesizing events is rarely needed. There are almost
+ * certainly better ways to achieve your goals. For example, use
+ * gdk_window_invalidate_rect() or gtk_widget_queue_draw() instead
+ * of making up expose events.
+ */
+void
+gtk_propagate_event (GtkWidget *widget,
+ GdkEvent *event)
+{
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (event != NULL);
+
+ propagate_event (widget, event, FALSE, NULL);
+}
+
+gboolean
+_gtk_propagate_captured_event (GtkWidget *widget,
+ GdkEvent *event,
+ GtkWidget *topmost)
+{
+ return propagate_event (widget, event, TRUE, topmost);
}
#if 0
diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h
index 6386c32..3865a67 100644
--- a/gtk/gtkprivate.h
+++ b/gtk/gtkprivate.h
@@ -152,6 +152,20 @@ gboolean _gtk_translate_keyboard_accel_state (GdkKeymap *keymap,
GdkModifierType *consumed_modifiers);
+gboolean _gtk_propagate_captured_event (GtkWidget *widget,
+ GdkEvent *event,
+ GtkWidget *topmost);
+
+typedef gboolean (*GtkCapturedEventHandler) (GtkWidget *widget, GdkEvent *event);
+
+void _gtk_widget_set_captured_event_handler (GtkWidget *widget,
+ GtkCapturedEventHandler handler);
+
+gboolean _gtk_widget_captured_event (GtkWidget *widget,
+ GdkEvent *event);
+
+
+
G_END_DECLS
#endif /* __GTK_PRIVATE_H__ */
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 1d1f6bb..8e38ee1 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -351,6 +351,7 @@ static void gtk_widget_set_usize_internal (GtkWidget *widget,
gint height);
static void gtk_widget_get_draw_rectangle (GtkWidget *widget,
GdkRectangle *rect);
+static gboolean event_window_is_still_viewable (GdkEvent *event);
/* --- variables --- */
@@ -4807,6 +4808,58 @@ gtk_widget_event (GtkWidget *widget,
return gtk_widget_event_internal (widget, event);
}
+void
+_gtk_widget_set_captured_event_handler (GtkWidget *widget,
+ GtkCapturedEventHandler callback)
+{
+ g_object_set_data (G_OBJECT (widget), "captured-event-handler", callback);
+}
+
+gboolean
+_gtk_widget_captured_event (GtkWidget *widget,
+ GdkEvent *event)
+{
+ gboolean return_val = FALSE;
+ GtkCapturedEventHandler handler;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
+ g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
+
+ if (event->type == GDK_EXPOSE)
+ {
+ g_warning ("Events of type GDK_EXPOSE cannot be synthesized. To get "
+ "the same effect, call gdk_window_invalidate_rect/region(), "
+ "followed by gdk_window_process_updates().");
+ return TRUE;
+ }
+
+ if (!event_window_is_still_viewable (event))
+ return TRUE;
+
+ handler = g_object_get_data (G_OBJECT (widget), "captured-event-handler");
+ if (!handler)
+ return FALSE;
+
+ g_object_ref (widget);
+
+ return_val = handler (widget, event);
+ return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event);
+
+ /* The widget that was originally to receive the event
+ * handles motion hints, but the capturing widget might
+ * not, so ensure we get further motion events.
+ */
+ if (return_val &&
+ event->type == GDK_MOTION_NOTIFY &&
+ event->motion.is_hint &&
+ (gdk_window_get_events (event->any.window) &
+ GDK_POINTER_MOTION_HINT_MASK) != 0)
+ gdk_event_request_motions (&event->motion);
+
+ g_object_unref (widget);
+
+ return return_val;
+}
/**
* gtk_widget_send_expose:
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,36 @@
From c0447e2741b3f9c966e337e6c7baf34cb66b0591 Mon Sep 17 00:00:00 2001
From: Michael Natterer <mitch@lanedo.com>
Date: Thu, 22 Nov 2012 13:37:58 +0100
Subject: [PATCH 10/68] gtk: don't let insensitive children eat scroll events
when bubbling down
When event capturing is enabled, stop propagating scroll events
at insensitive widgets, but don't handle them (don't return TRUE),
so they can bubble up again and reach their handling widgets.
---
gtk/gtkmain.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 21345ed..5ca0993 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -2482,7 +2482,15 @@ propagate_event_down (GtkWidget *widget,
widget = (GtkWidget *)l->data;
if (!gtk_widget_is_sensitive (widget))
- handled_event = TRUE;
+ {
+ /* stop propagating on SCROLL, but don't handle the event, so it
+ * can propagate up again and reach its handling widget
+ */
+ if (event->type == GDK_SCROLL)
+ break;
+ else
+ handled_event = TRUE;
+ }
else
handled_event = _gtk_widget_captured_event (widget, event);
}
--
1.7.10.2 (Apple Git-33)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
From f8b99185c4fe6a281f2075c5780bc71b35b46de9 Mon Sep 17 00:00:00 2001
From: Michael Natterer <mitch@gimp.org>
Date: Thu, 14 Jun 2012 09:27:09 +0200
Subject: [PATCH 12/68] gtk: paint to the right windows in
gtk_scrolled_window_expose()
so we don't paint everything twice.
---
gtk/gtkscrolledwindow.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 694d20a..821981f 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -1310,11 +1310,14 @@ static gboolean
gtk_scrolled_window_expose (GtkWidget *widget,
GdkEventExpose *event)
{
+ GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (widget);
+
if (gtk_widget_is_drawable (widget))
{
- gtk_scrolled_window_paint (widget, &event->area);
-
- GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->expose_event (widget, event);
+ if (event->window == priv->overshoot_window)
+ GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->expose_event (widget, event);
+ else
+ gtk_scrolled_window_paint (widget, &event->area);
}
return FALSE;
--
1.7.10.2 (Apple Git-33)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,371 @@
From eea6eef69858ff65ff8ccf46bb640bcc0580f592 Mon Sep 17 00:00:00 2001
From: Kristian Rietveld <kris@lanedo.com>
Date: Sun, 29 Jul 2012 16:14:09 +0200
Subject: [PATCH 15/68] Use gtk-enable-overlay-scrollbars in GtkScrolledWindow
And listen for changes to this setting. Move overlay_scrollbars variable
to GtkScrolledWindowPrivate, because we are going to have to monitor for
each scrolled window whether it has transformed itself in response to the
signal.
---
gtk/gtkscrolledwindow.c | 97 +++++++++++++++++++++++++++++++++++------------
1 file changed, 72 insertions(+), 25 deletions(-)
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 70de6ec..3220e91 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -140,6 +140,8 @@ typedef struct {
gint sb_scroll_direction;
guint sb_scroll_timeout_id;
+
+ gboolean overlay_scrollbars;
} GtkScrolledWindowPrivate;
#define GTK_SCROLLED_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_SCROLLED_WINDOW, GtkScrolledWindowPrivate))
@@ -260,12 +262,14 @@ static gboolean gtk_scrolled_window_child_expose (GtkWidget *widget,
static void gtk_scrolled_window_expose_scrollbars (GtkAdjustment *adj,
GtkScrolledWindow *scrolled_window);
+static void gtk_scrolled_window_overlay_scrollbars_changed (GtkSettings *settings,
+ GParamSpec *arg,
+ gpointer user_data);
+
static guint signals[LAST_SIGNAL] = {0};
G_DEFINE_TYPE (GtkScrolledWindow, gtk_scrolled_window, GTK_TYPE_BIN)
-static gboolean overlay_scrollbars = TRUE;
-
static void
add_scroll_binding (GtkBindingSet *binding_set,
guint keyval,
@@ -501,6 +505,7 @@ static void
gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
{
GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
+ GtkSettings *settings;
gtk_widget_set_has_window (GTK_WIDGET (scrolled_window), FALSE);
gtk_widget_set_can_focus (GTK_WIDGET (scrolled_window), TRUE);
@@ -515,13 +520,22 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
scrolled_window->window_placement = GTK_CORNER_TOP_LEFT;
gtk_scrolled_window_update_real_placement (scrolled_window);
+ settings = gtk_widget_get_settings (GTK_WIDGET (scrolled_window));
+ g_object_get (settings,
+ "gtk-enable-overlay-scrollbars",
+ &priv->overlay_scrollbars,
+ NULL);
+ g_signal_connect (settings, "notify::gtk-enable-overlay-scrollbars",
+ G_CALLBACK (gtk_scrolled_window_overlay_scrollbars_changed),
+ scrolled_window);
+
if (g_getenv ("GTK2_KINETIC_SCROLLING"))
{
gtk_scrolled_window_set_kinetic_scrolling (scrolled_window, TRUE);
gtk_scrolled_window_set_capture_button_press (scrolled_window, TRUE);
}
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
{
priv->opacity = g_object_new (GTK_TYPE_ADJUSTMENT,
"lower", 0.0,
@@ -586,6 +600,7 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
GtkAdjustment *hadjustment)
{
GtkBin *bin;
+ GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
g_return_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window));
if (hadjustment)
@@ -618,7 +633,7 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
gtk_scrolled_window_adjustment_changed,
scrolled_window);
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
{
g_signal_handlers_disconnect_by_func (old_adjustment,
gtk_scrolled_window_adjustment_value_changed,
@@ -643,7 +658,7 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
gtk_scrolled_window_adjustment_changed (hadjustment, scrolled_window);
gtk_scrolled_window_adjustment_value_changed (hadjustment, scrolled_window);
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
{
g_signal_connect (hadjustment, "value-changed",
G_CALLBACK (gtk_scrolled_window_adjustment_value_changed),
@@ -677,6 +692,7 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
GtkAdjustment *vadjustment)
{
GtkBin *bin;
+ GtkScrolledWindowPrivate *priv;
g_return_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window));
if (vadjustment)
@@ -685,6 +701,7 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
vadjustment = (GtkAdjustment*) g_object_new (GTK_TYPE_ADJUSTMENT, NULL);
bin = GTK_BIN (scrolled_window);
+ priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
if (!scrolled_window->vscrollbar)
{
@@ -709,7 +726,7 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
gtk_scrolled_window_adjustment_changed,
scrolled_window);
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
{
g_signal_handlers_disconnect_by_func (old_adjustment,
gtk_scrolled_window_adjustment_value_changed,
@@ -734,7 +751,7 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
gtk_scrolled_window_adjustment_changed (vadjustment, scrolled_window);
gtk_scrolled_window_adjustment_value_changed (vadjustment, scrolled_window);
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
{
g_signal_connect (vadjustment,
"value-changed",
@@ -1208,7 +1225,7 @@ gtk_scrolled_window_destroy (GtkObject *object)
gtk_scrolled_window_adjustment_changed,
scrolled_window);
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
{
g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)),
gtk_scrolled_window_adjustment_value_changed,
@@ -1229,7 +1246,7 @@ gtk_scrolled_window_destroy (GtkObject *object)
gtk_scrolled_window_adjustment_changed,
scrolled_window);
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
{
g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)),
gtk_scrolled_window_adjustment_value_changed,
@@ -1245,6 +1262,10 @@ gtk_scrolled_window_destroy (GtkObject *object)
scrolled_window->vscrollbar = NULL;
}
+ g_signal_handlers_disconnect_by_func (gtk_widget_get_settings (GTK_WIDGET (scrolled_window)),
+ G_CALLBACK (gtk_scrolled_window_overlay_scrollbars_changed),
+ scrolled_window);
+
if (priv->release_timeout_id)
{
g_source_remove (priv->release_timeout_id);
@@ -1641,12 +1662,14 @@ gtk_scrolled_window_size_request (GtkWidget *widget,
GtkRequisition hscrollbar_requisition;
GtkRequisition vscrollbar_requisition;
GtkRequisition child_requisition;
+ GtkScrolledWindowPrivate *priv;
g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
g_return_if_fail (requisition != NULL);
scrolled_window = GTK_SCROLLED_WINDOW (widget);
bin = GTK_BIN (scrolled_window);
+ priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window);
@@ -1666,7 +1689,7 @@ gtk_scrolled_window_size_request (GtkWidget *widget,
if (scrolled_window->hscrollbar_policy == GTK_POLICY_NEVER)
requisition->width += child_requisition.width;
- else if (! overlay_scrollbars)
+ else if (! priv->overlay_scrollbars)
{
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (bin->child, FALSE);
@@ -1681,7 +1704,7 @@ gtk_scrolled_window_size_request (GtkWidget *widget,
if (scrolled_window->vscrollbar_policy == GTK_POLICY_NEVER)
requisition->height += child_requisition.height;
- else if (! overlay_scrollbars)
+ else if (! priv->overlay_scrollbars)
{
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (bin->child, FALSE);
@@ -1695,7 +1718,7 @@ gtk_scrolled_window_size_request (GtkWidget *widget,
}
}
- if (! overlay_scrollbars)
+ if (! priv->overlay_scrollbars)
{
if (scrolled_window->hscrollbar_policy == GTK_POLICY_AUTOMATIC ||
scrolled_window->hscrollbar_policy == GTK_POLICY_ALWAYS)
@@ -1752,7 +1775,7 @@ gtk_scrolled_window_relative_allocation (GtkWidget *widget,
allocation->width = MAX (1, (gint)widget->allocation.width - allocation->x * 2);
allocation->height = MAX (1, (gint)widget->allocation.height - allocation->y * 2);
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
return;
if (scrolled_window->vscrollbar_visible)
@@ -1909,16 +1932,15 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
g_return_if_fail (allocation != NULL);
scrolled_window = GTK_SCROLLED_WINDOW (widget);
+ priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
bin = GTK_BIN (scrolled_window);
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
gtk_scrolled_window_expose_scrollbars (NULL, scrolled_window);
scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window);
gtk_widget_style_get (widget, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL);
- priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
-
widget->allocation = *allocation;
if (scrolled_window->hscrollbar_policy == GTK_POLICY_ALWAYS)
@@ -1972,7 +1994,7 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
gtk_scrolled_window_relative_allocation (widget, &relative_allocation);
}
- if (!overlay_scrollbars && scrolled_window->hscrollbar_visible)
+ if (!priv->overlay_scrollbars && scrolled_window->hscrollbar_visible)
{
GtkRequisition hscrollbar_requisition;
gtk_widget_get_child_requisition (scrolled_window->hscrollbar,
@@ -2020,7 +2042,7 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
else if (gtk_widget_get_visible (scrolled_window->hscrollbar))
gtk_widget_hide (scrolled_window->hscrollbar);
- if (!overlay_scrollbars && scrolled_window->vscrollbar_visible)
+ if (!priv->overlay_scrollbars && scrolled_window->vscrollbar_visible)
{
GtkRequisition vscrollbar_requisition;
if (!gtk_widget_get_visible (scrolled_window->vscrollbar))
@@ -2080,6 +2102,7 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget,
GdkEventScroll *event)
{
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
+ GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
gboolean handled = FALSE;
gdouble delta_x;
gdouble delta_y;
@@ -2090,7 +2113,7 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget,
if (gdk_event_get_scroll_deltas ((GdkEvent *) event, &delta_x, &delta_y))
{
if (delta_x != 0.0 && scrolled_window->hscrollbar &&
- (overlay_scrollbars || gtk_widget_get_visible (scrolled_window->hscrollbar)))
+ (priv->overlay_scrollbars || gtk_widget_get_visible (scrolled_window->hscrollbar)))
{
GtkAdjustment *adj;
gdouble new_value;
@@ -2108,7 +2131,7 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget,
}
if (delta_y != 0.0 && scrolled_window->vscrollbar &&
- (overlay_scrollbars || gtk_widget_get_visible (scrolled_window->vscrollbar)))
+ (priv->overlay_scrollbars || gtk_widget_get_visible (scrolled_window->vscrollbar)))
{
GtkAdjustment *adj;
gdouble new_value;
@@ -2134,7 +2157,7 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget,
else
range = scrolled_window->hscrollbar;
- if (range && (overlay_scrollbars || gtk_widget_get_visible (range)))
+ if (range && (priv->overlay_scrollbars || gtk_widget_get_visible (range)))
{
GtkAdjustment *adj = GTK_RANGE (range)->adjustment;
gdouble delta, new_value;
@@ -2994,11 +3017,13 @@ gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjustment,
gpointer data)
{
GtkScrolledWindow *scrolled_win;
+ GtkScrolledWindowPrivate *priv;
g_return_if_fail (adjustment != NULL);
g_return_if_fail (data != NULL);
scrolled_win = GTK_SCROLLED_WINDOW (data);
+ priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (data);
if (scrolled_win->hscrollbar &&
adjustment == gtk_range_get_adjustment (GTK_RANGE (scrolled_win->hscrollbar)))
@@ -3029,7 +3054,7 @@ gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjustment,
}
}
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
gtk_scrolled_window_start_fade_in_animation (scrolled_win);
}
@@ -3052,7 +3077,7 @@ gtk_scrolled_window_adjustment_value_changed (GtkAdjustment *adjustment,
adjustment == gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)))
priv->unclamped_hadj_value = gtk_adjustment_get_value (adjustment);
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
gtk_scrolled_window_start_fade_in_animation (scrolled_window);
}
@@ -3083,7 +3108,7 @@ gtk_scrolled_window_add (GtkContainer *container,
g_warning ("gtk_scrolled_window_add(): cannot add non scrollable widget "
"use gtk_scrolled_window_add_with_viewport() instead");
- if (overlay_scrollbars)
+ if (priv->overlay_scrollbars)
{
g_signal_connect_after (child, "expose-event",
G_CALLBACK (gtk_scrolled_window_child_expose),
@@ -3095,11 +3120,15 @@ static void
gtk_scrolled_window_remove (GtkContainer *container,
GtkWidget *child)
{
+ GtkScrolledWindowPrivate *priv;
+
g_return_if_fail (GTK_IS_SCROLLED_WINDOW (container));
g_return_if_fail (child != NULL);
g_return_if_fail (GTK_BIN (container)->child == child);
- if (overlay_scrollbars)
+ priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (container);
+
+ if (priv->overlay_scrollbars)
{
g_signal_handlers_disconnect_by_func (child,
gtk_scrolled_window_child_expose,
@@ -3764,5 +3793,23 @@ gtk_scrolled_window_expose_scrollbars (GtkAdjustment *adj,
}
}
+static void
+gtk_scrolled_window_overlay_scrollbars_changed (GtkSettings *settings,
+ GParamSpec *arg,
+ gpointer user_data)
+{
+ GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (user_data);
+ GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (user_data);
+
+ /* FIXME: tear down/set up things to make the switch */
+
+ g_object_get (settings,
+ "gtk-enable-overlay-scrollbars",
+ &priv->overlay_scrollbars,
+ NULL);
+
+ g_print ("enable-overlay-scrollbar is now: %d\n", priv->overlay_scrollbars);
+}
+
#define __GTK_SCROLLED_WINDOW_C__
#include "gtkaliasdef.c"
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,386 @@
From 8d10b09aff0bc03c54c2f1899900cc062f36ad4b Mon Sep 17 00:00:00 2001
From: Michael Natterer <mitch@gimp.org>
Date: Thu, 16 Aug 2012 09:35:53 +0200
Subject: [PATCH 16/68] gtk: correctly handle toggling of the scrollbar
visibility setting
By doing most things unconditionally, like connecting to signals
and creating the opacity adjustment. Queue a resize when the
setting changes so things get recalculated properly, and make
sure the scrollbars get expose events if they are visible.
Unrelated: don't leak the priv->opacity adjustment.
---
gtk/gtkscrolledwindow.c | 244 +++++++++++++++++++++++------------------------
1 file changed, 119 insertions(+), 125 deletions(-)
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 3220e91..7680f5d 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -529,29 +529,25 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
G_CALLBACK (gtk_scrolled_window_overlay_scrollbars_changed),
scrolled_window);
- if (g_getenv ("GTK2_KINETIC_SCROLLING"))
- {
- gtk_scrolled_window_set_kinetic_scrolling (scrolled_window, TRUE);
- gtk_scrolled_window_set_capture_button_press (scrolled_window, TRUE);
- }
-
- if (priv->overlay_scrollbars)
- {
- priv->opacity = g_object_new (GTK_TYPE_ADJUSTMENT,
- "lower", 0.0,
- "upper", 0.5,
- "value", 0.0,
- NULL);
- priv->sb_min_height = 20;
- priv->sb_padding = 2;
- priv->sb_radius = 3;
- priv->sb_width = 6;
- priv->sb_fade_out_delay = 1000;
-
- g_signal_connect (priv->opacity, "value-changed",
- G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
- scrolled_window);
- }
+ gtk_scrolled_window_set_kinetic_scrolling (scrolled_window, TRUE);
+ gtk_scrolled_window_set_capture_button_press (scrolled_window, TRUE);
+
+ priv->opacity = g_object_new (GTK_TYPE_ADJUSTMENT,
+ "lower", 0.0,
+ "upper", 0.5,
+ "value", 0.0,
+ NULL);
+ g_object_ref_sink (priv->opacity);
+
+ priv->sb_min_height = 20;
+ priv->sb_padding = 2;
+ priv->sb_radius = 3;
+ priv->sb_width = 6;
+ priv->sb_fade_out_delay = 1000;
+
+ g_signal_connect (priv->opacity, "value-changed",
+ G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
+ scrolled_window);
}
/**
@@ -632,16 +628,12 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
g_signal_handlers_disconnect_by_func (old_adjustment,
gtk_scrolled_window_adjustment_changed,
scrolled_window);
-
- if (priv->overlay_scrollbars)
- {
- g_signal_handlers_disconnect_by_func (old_adjustment,
- gtk_scrolled_window_adjustment_value_changed,
- scrolled_window);
- g_signal_handlers_disconnect_by_func (old_adjustment,
- gtk_scrolled_window_expose_scrollbars,
- scrolled_window);
- }
+ g_signal_handlers_disconnect_by_func (old_adjustment,
+ gtk_scrolled_window_adjustment_value_changed,
+ scrolled_window);
+ g_signal_handlers_disconnect_by_func (old_adjustment,
+ gtk_scrolled_window_expose_scrollbars,
+ scrolled_window);
gtk_range_set_adjustment (GTK_RANGE (scrolled_window->hscrollbar),
hadjustment);
@@ -658,19 +650,18 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
gtk_scrolled_window_adjustment_changed (hadjustment, scrolled_window);
gtk_scrolled_window_adjustment_value_changed (hadjustment, scrolled_window);
- if (priv->overlay_scrollbars)
- {
- g_signal_connect (hadjustment, "value-changed",
- G_CALLBACK (gtk_scrolled_window_adjustment_value_changed),
- scrolled_window);
+#if 0
+ g_signal_connect (hadjustment, "value-changed",
+ G_CALLBACK (gtk_scrolled_window_adjustment_value_changed),
+ scrolled_window);
+#endif
- g_signal_connect (hadjustment, "changed",
- G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
- scrolled_window);
- g_signal_connect (hadjustment, "value-changed",
- G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
- scrolled_window);
- }
+ g_signal_connect (hadjustment, "changed",
+ G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
+ scrolled_window);
+ g_signal_connect (hadjustment, "value-changed",
+ G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
+ scrolled_window);
if (bin->child)
gtk_widget_set_scroll_adjustments (bin->child,
@@ -725,16 +716,12 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
g_signal_handlers_disconnect_by_func (old_adjustment,
gtk_scrolled_window_adjustment_changed,
scrolled_window);
-
- if (priv->overlay_scrollbars)
- {
- g_signal_handlers_disconnect_by_func (old_adjustment,
- gtk_scrolled_window_adjustment_value_changed,
- scrolled_window);
- g_signal_handlers_disconnect_by_func (old_adjustment,
- gtk_scrolled_window_expose_scrollbars,
- scrolled_window);
- }
+ g_signal_handlers_disconnect_by_func (old_adjustment,
+ gtk_scrolled_window_adjustment_value_changed,
+ scrolled_window);
+ g_signal_handlers_disconnect_by_func (old_adjustment,
+ gtk_scrolled_window_expose_scrollbars,
+ scrolled_window);
gtk_range_set_adjustment (GTK_RANGE (scrolled_window->vscrollbar),
vadjustment);
@@ -751,20 +738,19 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
gtk_scrolled_window_adjustment_changed (vadjustment, scrolled_window);
gtk_scrolled_window_adjustment_value_changed (vadjustment, scrolled_window);
- if (priv->overlay_scrollbars)
- {
- g_signal_connect (vadjustment,
- "value-changed",
- G_CALLBACK (gtk_scrolled_window_adjustment_value_changed),
- scrolled_window);
+#if 0
+ g_signal_connect (vadjustment,
+ "value-changed",
+ G_CALLBACK (gtk_scrolled_window_adjustment_value_changed),
+ scrolled_window);
+#endif
- g_signal_connect (vadjustment, "changed",
- G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
- scrolled_window);
- g_signal_connect (vadjustment, "value-changed",
- G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
- scrolled_window);
- }
+ g_signal_connect (vadjustment, "changed",
+ G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
+ scrolled_window);
+ g_signal_connect (vadjustment, "value-changed",
+ G_CALLBACK (gtk_scrolled_window_expose_scrollbars),
+ scrolled_window);
if (bin->child)
gtk_widget_set_scroll_adjustments (bin->child,
@@ -1224,16 +1210,12 @@ gtk_scrolled_window_destroy (GtkObject *object)
g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)),
gtk_scrolled_window_adjustment_changed,
scrolled_window);
-
- if (priv->overlay_scrollbars)
- {
- g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)),
- gtk_scrolled_window_adjustment_value_changed,
- scrolled_window);
- g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)),
- gtk_scrolled_window_expose_scrollbars,
- scrolled_window);
- }
+ g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)),
+ gtk_scrolled_window_adjustment_value_changed,
+ scrolled_window);
+ g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)),
+ gtk_scrolled_window_expose_scrollbars,
+ scrolled_window);
gtk_widget_unparent (scrolled_window->hscrollbar);
gtk_widget_destroy (scrolled_window->hscrollbar);
@@ -1245,16 +1227,12 @@ gtk_scrolled_window_destroy (GtkObject *object)
g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)),
gtk_scrolled_window_adjustment_changed,
scrolled_window);
-
- if (priv->overlay_scrollbars)
- {
- g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)),
- gtk_scrolled_window_adjustment_value_changed,
- scrolled_window);
- g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)),
- gtk_scrolled_window_expose_scrollbars,
- scrolled_window);
- }
+ g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)),
+ gtk_scrolled_window_adjustment_value_changed,
+ scrolled_window);
+ g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)),
+ gtk_scrolled_window_expose_scrollbars,
+ scrolled_window);
gtk_widget_unparent (scrolled_window->vscrollbar);
gtk_widget_destroy (scrolled_window->vscrollbar);
@@ -1283,6 +1261,12 @@ gtk_scrolled_window_destroy (GtkObject *object)
priv->button_press_event = NULL;
}
+ if (priv->opacity)
+ {
+ g_object_unref (priv->opacity);
+ priv->opacity = NULL;
+ }
+
GTK_OBJECT_CLASS (gtk_scrolled_window_parent_class)->destroy (object);
}
@@ -1482,11 +1466,23 @@ static gboolean
gtk_scrolled_window_expose (GtkWidget *widget,
GdkEventExpose *event)
{
+ GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (widget);
if (gtk_widget_is_drawable (widget))
{
- if (event->window == priv->overshoot_window)
+ GdkWindow *hscrollbar_window = NULL;
+ GdkWindow *vscrollbar_window = NULL;
+
+ if (scrolled_window->hscrollbar)
+ hscrollbar_window = gtk_widget_get_window (scrolled_window->hscrollbar);
+
+ if (scrolled_window->vscrollbar)
+ vscrollbar_window = gtk_widget_get_window (scrolled_window->vscrollbar);
+
+ if (event->window == priv->overshoot_window ||
+ event->window == hscrollbar_window ||
+ event->window == vscrollbar_window)
GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->expose_event (widget, event);
else
gtk_scrolled_window_paint (widget, &event->area);
@@ -1935,8 +1931,7 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
bin = GTK_BIN (scrolled_window);
- if (priv->overlay_scrollbars)
- gtk_scrolled_window_expose_scrollbars (NULL, scrolled_window);
+ gtk_scrolled_window_expose_scrollbars (NULL, scrolled_window);
scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window);
gtk_widget_style_get (widget, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL);
@@ -3108,12 +3103,9 @@ gtk_scrolled_window_add (GtkContainer *container,
g_warning ("gtk_scrolled_window_add(): cannot add non scrollable widget "
"use gtk_scrolled_window_add_with_viewport() instead");
- if (priv->overlay_scrollbars)
- {
- g_signal_connect_after (child, "expose-event",
- G_CALLBACK (gtk_scrolled_window_child_expose),
- container);
- }
+ g_signal_connect_after (child, "expose-event",
+ G_CALLBACK (gtk_scrolled_window_child_expose),
+ container);
}
static void
@@ -3128,12 +3120,9 @@ gtk_scrolled_window_remove (GtkContainer *container,
priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (container);
- if (priv->overlay_scrollbars)
- {
- g_signal_handlers_disconnect_by_func (child,
- gtk_scrolled_window_child_expose,
- container);
- }
+ g_signal_handlers_disconnect_by_func (child,
+ gtk_scrolled_window_child_expose,
+ container);
gtk_widget_set_scroll_adjustments (child, NULL, NULL);
@@ -3624,6 +3613,9 @@ gtk_scrolled_window_child_expose (GtkWidget *widget,
GdkRectangle hslider_rect;
cairo_t *cr;
+ if (!priv->overlay_scrollbars)
+ return FALSE;
+
cr = gdk_cairo_create (eevent->window);
gdk_cairo_region (cr, eevent->region);
cairo_clip (cr);
@@ -3769,27 +3761,32 @@ static void
gtk_scrolled_window_expose_scrollbars (GtkAdjustment *adj,
GtkScrolledWindow *scrolled_window)
{
- GtkWidget *child = gtk_bin_get_child (GTK_BIN (scrolled_window));
+ GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
- if (child && gtk_widget_get_visible (child))
+ if (priv->overlay_scrollbars)
{
- GtkAllocation alloc;
-
- gtk_widget_get_allocation (child, &alloc);
-
- if (scrolled_window->vscrollbar)
- gtk_widget_queue_draw_area (child,
- alloc.width - 20,
- 0,
- 20,
- alloc.height);
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (scrolled_window));
- if (scrolled_window->hscrollbar)
- gtk_widget_queue_draw_area (child,
- 0,
- alloc.height - 20,
- alloc.width,
- 20);
+ if (child && gtk_widget_get_visible (child))
+ {
+ GtkAllocation alloc;
+
+ gtk_widget_get_allocation (child, &alloc);
+
+ if (scrolled_window->vscrollbar)
+ gtk_widget_queue_draw_area (child,
+ alloc.width - 20,
+ 0,
+ 20,
+ alloc.height);
+
+ if (scrolled_window->hscrollbar)
+ gtk_widget_queue_draw_area (child,
+ 0,
+ alloc.height - 20,
+ alloc.width,
+ 20);
+ }
}
}
@@ -3798,17 +3795,14 @@ gtk_scrolled_window_overlay_scrollbars_changed (GtkSettings *settings,
GParamSpec *arg,
gpointer user_data)
{
- GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (user_data);
GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (user_data);
- /* FIXME: tear down/set up things to make the switch */
-
g_object_get (settings,
"gtk-enable-overlay-scrollbars",
&priv->overlay_scrollbars,
NULL);
- g_print ("enable-overlay-scrollbar is now: %d\n", priv->overlay_scrollbars);
+ gtk_widget_queue_resize (user_data);
}
#define __GTK_SCROLLED_WINDOW_C__
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,69 @@
From f2c762968b02b73323a75a723ad664ff1645abde Mon Sep 17 00:00:00 2001
From: Michael Natterer <mitch@gimp.org>
Date: Fri, 31 Aug 2012 16:24:07 +0200
Subject: [PATCH 17/68] gtk: handle gtk-primary-button-warps-slider for the
overlay scrollbars
---
gtk/gtkscrolledwindow.c | 38 +++++++++++++++++++++++++++++++++-----
1 file changed, 33 insertions(+), 5 deletions(-)
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 7680f5d..02745b1 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -2725,6 +2725,10 @@ gtk_scrolled_window_scroll_step_timeout (gpointer data)
}
static gboolean
+gtk_scrolled_window_captured_motion_notify_scrollbar (GtkWidget *widget,
+ GdkEvent *event);
+
+static gboolean
gtk_scrolled_window_captured_button_press_scrollbar (GtkWidget *widget,
GdkEvent *event)
{
@@ -2808,12 +2812,36 @@ gtk_scrolled_window_captured_button_press_scrollbar (GtkWidget *widget,
if ((priv->sb_grab_vscroll || priv->sb_grab_hscroll) &&
!priv->sb_drag_slider)
{
- gtk_scrolled_window_scroll_step (scrolled_window);
+ gboolean primary_warps;
+
+ g_object_get (gtk_widget_get_settings (widget),
+ "gtk-primary-button-warps-slider", &primary_warps,
+ NULL);
+
+ if (primary_warps)
+ {
+ GdkEventMotion mevent = { 0, };
+
+ priv->sb_drag_slider = TRUE;
+ priv->sb_grab_offset_x = hslider_rect.width / 2;
+ priv->sb_grab_offset_y = vslider_rect.height / 2;
+
+ mevent.window = bevent->window;
+ mevent.x = bevent->x;
+ mevent.y = bevent->y;
- priv->sb_scroll_timeout_id =
- gdk_threads_add_timeout (SCROLL_INTERVAL_INITIAL,
- gtk_scrolled_window_scroll_step_timeout,
- scrolled_window);
+ gtk_scrolled_window_captured_motion_notify_scrollbar (widget,
+ (GdkEvent *) &mevent);
+ }
+ else
+ {
+ gtk_scrolled_window_scroll_step (scrolled_window);
+
+ priv->sb_scroll_timeout_id =
+ gdk_threads_add_timeout (SCROLL_INTERVAL_INITIAL,
+ gtk_scrolled_window_scroll_step_timeout,
+ scrolled_window);
+ }
}
return TRUE;
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,166 @@
From 4ef417938760f98e530c152ee50071da2af31b06 Mon Sep 17 00:00:00 2001
From: Kristian Rietveld <kris@lanedo.com>
Date: Sun, 2 Sep 2012 14:16:45 +0200
Subject: [PATCH 18/68] Introduce phase field in GdkEventScroll
Using the phase field it is possible to distinguish between
events generated while the user is performing a gesture and
momentum events that are generated after the gesture has been
finished.
---
gdk/gdkevents.c | 1 +
gdk/gdkevents.h | 9 +++++++++
gdk/gdkwindow.c | 1 +
gdk/quartz/gdkevents-quartz.c | 36 +++++++++++++++++++++++++++++++++---
4 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 0f8bba2..d3d67db 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -394,6 +394,7 @@ gdk_event_new (GdkEventType type)
new_event->scroll.y_root = 0.;
new_event->scroll.delta_x = 0.;
new_event->scroll.delta_y = 0.;
+ new_event->scroll.phase = GDK_EVENT_SCROLL_PHASE_NONE;
break;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h
index f6b4e04..765b520 100644
--- a/gdk/gdkevents.h
+++ b/gdk/gdkevents.h
@@ -263,6 +263,14 @@ typedef enum
GDK_OWNER_CHANGE_CLOSE
} GdkOwnerChange;
+typedef enum
+{
+ GDK_EVENT_SCROLL_PHASE_NONE,
+ GDK_EVENT_SCROLL_PHASE_START,
+ GDK_EVENT_SCROLL_PHASE_ACTIVE,
+ GDK_EVENT_SCROLL_PHASE_END
+} GdkEventScrollPhase;
+
struct _GdkEventAny
{
GdkEventType type;
@@ -340,6 +348,7 @@ struct _GdkEventScroll
gboolean has_deltas;
gdouble delta_x;
gdouble delta_y;
+ GdkEventScrollPhase phase;
};
struct _GdkEventKey
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index d48751e..1843873 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -10803,6 +10803,7 @@ proxy_button_event (GdkEvent *source_event,
event->scroll.has_deltas = source_event->scroll.has_deltas;
event->scroll.delta_x = source_event->scroll.delta_x;
event->scroll.delta_y = source_event->scroll.delta_y;
+ event->scroll.phase = source_event->scroll.phase;
return TRUE;
default:
diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
index e7d97dc..bb4da70 100644
--- a/gdk/quartz/gdkevents-quartz.c
+++ b/gdk/quartz/gdkevents-quartz.c
@@ -62,6 +62,7 @@ static GdkWindow *find_toplevel_under_pointer (GdkDisplay *display,
- (BOOL) hasPreciseScrollingDeltas;
- (CGFloat) scrollingDeltaX;
- (CGFloat) scrollingDeltaY;
+- (int) phase;
@end
@@ -990,6 +991,7 @@ fill_scroll_event (GdkWindow *window,
gboolean has_deltas,
gdouble delta_x,
gdouble delta_y,
+ GdkEventScrollPhase phase,
GdkScrollDirection direction)
{
GdkWindowObject *private;
@@ -1012,6 +1014,7 @@ fill_scroll_event (GdkWindow *window,
event->scroll.has_deltas = has_deltas;
event->scroll.delta_x = delta_x;
event->scroll.delta_y = delta_y;
+ event->scroll.phase = phase;
}
static void
@@ -1300,6 +1303,28 @@ test_resize (NSEvent *event, GdkWindow *toplevel, gint x, gint y)
return FALSE;
}
+static GdkEventScrollPhase
+gdk_event_scroll_phase_from_ns_event_phase (NSUInteger phase)
+{
+ switch (phase)
+ {
+ case 0:
+ return GDK_EVENT_SCROLL_PHASE_NONE;
+
+ case 1 << 0:
+ return GDK_EVENT_SCROLL_PHASE_START;
+
+ case 1 << 1:
+ case 1 << 2:
+ return GDK_EVENT_SCROLL_PHASE_ACTIVE;
+
+ case 1 << 3:
+ return GDK_EVENT_SCROLL_PHASE_END;
+ }
+
+ return GDK_EVENT_SCROLL_PHASE_NONE;
+}
+
static gboolean
gdk_event_translate (GdkEvent *event,
NSEvent *nsevent)
@@ -1491,6 +1516,7 @@ gdk_event_translate (GdkEvent *event,
if (gdk_quartz_osx_version() >= GDK_OSX_LION &&
[(id <PreciseDeltas>) nsevent hasPreciseScrollingDeltas])
{
+ GdkEventScrollPhase phase;
dx = [(id <PreciseDeltas>) nsevent scrollingDeltaX];
dy = [(id <PreciseDeltas>) nsevent scrollingDeltaY];
@@ -1509,8 +1535,10 @@ gdk_event_translate (GdkEvent *event,
direction = GDK_SCROLL_LEFT;
}
+ phase = gdk_event_scroll_phase_from_ns_event_phase ([(id <PreciseDeltas>) nsevent phase]);
+
fill_scroll_event (window, event, nsevent, x, y, x_root, y_root,
- TRUE, -dx, -dy, direction);
+ TRUE, -dx, -dy, phase, direction);
}
else
{
@@ -1525,7 +1553,8 @@ gdk_event_translate (GdkEvent *event,
direction = GDK_SCROLL_UP;
fill_scroll_event (window, event, nsevent, x, y, x_root, y_root,
- FALSE, 0.0, fabs (dy), direction);
+ FALSE, 0.0, fabs (dy), GDK_EVENT_SCROLL_PHASE_NONE,
+ direction);
}
else if (dx != 0.0)
{
@@ -1535,7 +1564,8 @@ gdk_event_translate (GdkEvent *event,
direction = GDK_SCROLL_LEFT;
fill_scroll_event (window, event, nsevent, x, y, x_root, y_root,
- FALSE, fabs (dx), 0.0, direction);
+ FALSE, fabs (dx), 0.0, GDK_EVENT_SCROLL_PHASE_NONE,
+ direction);
}
}
}
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,144 @@
From 026f9bc1846eae8fa98a307975fedce1f61d9cd5 Mon Sep 17 00:00:00 2001
From: Kristian Rietveld <kris@lanedo.com>
Date: Fri, 28 Sep 2012 08:24:05 +0200
Subject: [PATCH 19/68] Add hack to lock flow of scroll events to window where
scroll started
A bit evil but there is probably no other way, because this is very
different from GDK's usual behavior.
There's one quirk left, if you start a scroll and move to another GTK+
window in the same process and click, the click won't be processed until
the folow of momentum events has ended.
---
gdk/gdkwindow.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 1843873..1dac543 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -434,6 +434,10 @@ accumulate_get_window (GSignalInvocationHint *ihint,
}
static GQuark quark_pointer_window = 0;
+#ifdef GDK_WINDOWING_QUARTZ
+static GQuark quark_last_scroll_pointer_window = 0;
+static GQuark quark_last_scroll_event_window = 0;
+#endif /* GDK_WINDOWING_QUARTZ */
static void
gdk_window_class_init (GdkWindowObjectClass *klass)
@@ -478,6 +482,12 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
drawable_class->get_source_drawable = gdk_window_get_source_drawable;
quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
+#ifdef GDK_WINDOWING_QUARTZ
+ quark_last_scroll_pointer_window =
+ g_quark_from_static_string ("gtk-last-scroll-pointer-window");
+ quark_last_scroll_event_window =
+ g_quark_from_static_string ("gtk-last-scroll-event-window");
+#endif /* GDK_WINDOWING_QUARTZ */
/* Properties */
@@ -10702,6 +10712,64 @@ proxy_pointer_event (GdkDisplay *display,
GDK_BUTTON4_MASK | \
GDK_BUTTON5_MASK)
+#ifdef GDK_WINDOWING_QUARTZ
+static void
+last_scroll_event_weak_ref_notify (gpointer data,
+ GObject *where_the_object_was)
+{
+ /* If any of pointer_window or event_window is destroyed, we unset
+ * both values in the display's qdata.
+ */
+ GdkDisplay *display = data;
+
+ g_object_set_qdata (G_OBJECT (display), quark_last_scroll_pointer_window,
+ NULL);
+ g_object_set_qdata (G_OBJECT (display), quark_last_scroll_event_window,
+ NULL);
+}
+
+static void
+set_last_scroll_event_windows (GdkDisplay *display,
+ GdkWindow *pointer_window,
+ GdkWindow *event_window)
+{
+ GdkWindow *old_window;
+
+ /* Check whether the values are still set from a previous scroll,
+ * if so we need to release the weak references. (If they are no
+ * longer set, we assume the weak ref notify callback was called).
+ */
+ old_window = g_object_get_qdata (G_OBJECT (display),
+ quark_last_scroll_pointer_window);
+ if (old_window)
+ g_object_weak_unref (G_OBJECT (old_window),
+ last_scroll_event_weak_ref_notify, display);
+
+ old_window = g_object_get_qdata (G_OBJECT (display),
+ quark_last_scroll_event_window);
+ if (old_window)
+ g_object_weak_unref (G_OBJECT (old_window),
+ last_scroll_event_weak_ref_notify, display);
+
+ /* Set new values and setup weak references. Note that pointer_window
+ * and event_window can be NULL, in which case GDK won't proxy the
+ * event. In this case we store NULL into the qdata so that we won't
+ * store the scroll event.
+ */
+ g_object_set_qdata (G_OBJECT (display), quark_last_scroll_pointer_window,
+ pointer_window);
+ if (pointer_window)
+ g_object_weak_ref (G_OBJECT (pointer_window),
+ last_scroll_event_weak_ref_notify, display);
+
+ g_object_set_qdata (G_OBJECT (display), quark_last_scroll_event_window,
+ event_window);
+ if (event_window)
+ g_object_weak_ref (G_OBJECT (event_window),
+ last_scroll_event_weak_ref_notify, display);
+}
+#endif /* GDK_WINDOWING_QUARTZ */
+
static gboolean
proxy_button_event (GdkEvent *source_event,
gulong serial)
@@ -10769,6 +10837,32 @@ proxy_button_event (GdkEvent *source_event,
type, state,
NULL, serial);
+#ifdef GDK_WINDOWING_QUARTZ
+ /* A Quartz-specific hack we cannot handle from within the backend
+ * unfortunately. For scroll events with precise deltas (i.e. these
+ * generated by the Mac touchpad or Magic Mouse, we want to lock the
+ * flow of events belonging to a single gesture to the window the
+ * gesture was started on. The default behavior of GDK, which insists
+ * to send events to the window under the pointer or discard the
+ * events when there's no GDK window under the pointer, makes it
+ * impossible to implement this differently.
+ */
+ if (type == GDK_SCROLL && source_event->scroll.has_deltas)
+ {
+ if (source_event->scroll.phase == GDK_EVENT_SCROLL_PHASE_START)
+ {
+ set_last_scroll_event_windows (display, pointer_window, event_win);
+ }
+ else
+ {
+ pointer_window = g_object_get_qdata (G_OBJECT (display),
+ quark_last_scroll_pointer_window);
+ event_win = g_object_get_qdata (G_OBJECT (display),
+ quark_last_scroll_event_window);
+ }
+ }
+#endif /* GDK_WINDOWING_QUARTZ */
+
if (event_win == NULL || display->ignore_core_events)
return TRUE;
--
1.7.10.2 (Apple Git-33)

View File

@@ -0,0 +1,189 @@
From 69e85305f2d455c8943514edde215ce69791076a Mon Sep 17 00:00:00 2001
From: Kristian Rietveld <kris@lanedo.com>
Date: Sun, 2 Sep 2012 21:21:51 +0200
Subject: [PATCH 20/68] Introduce a background window
The background window covers the part left uncovered by the overshoot
window. Two background windows are used to be able to cover an "L shape"
that appears when is scrolled in the horizontal and vertical direction
at the same time. These background windows are used to capture events,
such as scroll events. In the future, it could also be used to draw a
specific background pattern/gradient (if the window is configured as
INPUT/OUTPUT window).
---
gtk/gtkscrolledwindow.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 02745b1..9d0d87a 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -95,6 +95,8 @@ typedef struct {
/* Kinetic scrolling */
GdkEvent *button_press_event;
GdkWindow *overshoot_window;
+ GdkWindow *vbackground_window;
+ GdkWindow *hbackground_window;
guint pointer_grabbed : 1;
guint kinetic_scrolling : 1;
guint capture_button_press : 1;
@@ -1481,6 +1483,8 @@ gtk_scrolled_window_expose (GtkWidget *widget,
vscrollbar_window = gtk_widget_get_window (scrolled_window->vscrollbar);
if (event->window == priv->overshoot_window ||
+ event->window == priv->vbackground_window ||
+ event->window == priv->hbackground_window ||
event->window == hscrollbar_window ||
event->window == vscrollbar_window)
GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->expose_event (widget, event);
@@ -1871,6 +1875,7 @@ _gtk_scrolled_window_allocate_overshoot_window (GtkScrolledWindow *scrolled_wind
_gtk_scrolled_window_get_overshoot (scrolled_window,
&overshoot_x, &overshoot_y);
+ /* Overshoot window */
window_allocation = relative_allocation;
window_allocation.x += allocation.x;
window_allocation.y += allocation.y;
@@ -1887,6 +1892,46 @@ _gtk_scrolled_window_allocate_overshoot_window (GtkScrolledWindow *scrolled_wind
gdk_window_move_resize (priv->overshoot_window,
window_allocation.x, window_allocation.y,
window_allocation.width, window_allocation.height);
+
+ /* Vertical background window */
+ window_allocation = relative_allocation;
+ window_allocation.x += allocation.x;
+ window_allocation.y += allocation.y;
+
+ if (ABS (overshoot_x) > 0)
+ {
+ window_allocation.width = ABS (overshoot_x);
+ if (overshoot_x > 0)
+ window_allocation.x += relative_allocation.width - overshoot_x;
+
+ gdk_window_move_resize (priv->vbackground_window,
+ window_allocation.x, window_allocation.y,
+ window_allocation.width,
+ window_allocation.height);
+ gdk_window_show (priv->vbackground_window);
+ }
+ else
+ gdk_window_hide (priv->vbackground_window);
+
+ /* Horizontal background window */
+ window_allocation = relative_allocation;
+ window_allocation.x += allocation.x;
+ window_allocation.y += allocation.y;
+
+ if (ABS (overshoot_y) > 0)
+ {
+ window_allocation.height = ABS (overshoot_y);
+ if (overshoot_y > 0)
+ window_allocation.y += relative_allocation.height - overshoot_y;
+
+ gdk_window_move_resize (priv->hbackground_window,
+ window_allocation.x, window_allocation.y,
+ window_allocation.width,
+ window_allocation.height);
+ gdk_window_show (priv->hbackground_window);
+ }
+ else
+ gdk_window_hide (priv->hbackground_window);
}
static void
@@ -3259,6 +3304,7 @@ gtk_scrolled_window_realize (GtkWidget *widget)
gtk_widget_get_allocation (widget, &allocation);
gtk_scrolled_window_relative_allocation (widget, &relative_allocation);
+ /* Overshoot window */
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = allocation.x + relative_allocation.x;
attributes.y = allocation.y + relative_allocation.y;
@@ -3277,6 +3323,45 @@ gtk_scrolled_window_realize (GtkWidget *widget)
gdk_window_set_user_data (priv->overshoot_window, widget);
+ /* Vertical background window */
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.x = allocation.x + relative_allocation.x;
+ attributes.y = allocation.y + relative_allocation.y;
+ attributes.width = 0;
+ attributes.height = 0;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK |
+ GDK_BUTTON_MOTION_MASK | GDK_SCROLL_MASK;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
+
+ priv->vbackground_window =
+ gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes, attributes_mask);
+
+ gdk_window_set_user_data (priv->vbackground_window, widget);
+
+ /* Horizontal background window */
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.x = allocation.x + relative_allocation.x;
+ attributes.y = allocation.y + relative_allocation.y;
+ attributes.width = 0;
+ attributes.height = 0;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK |
+ GDK_BUTTON_MOTION_MASK | GDK_SCROLL_MASK;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
+
+ priv->hbackground_window =
+ gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes, attributes_mask);
+
+ gdk_window_set_user_data (priv->hbackground_window, widget);
+
+
child_widget = gtk_bin_get_child (GTK_BIN (widget));
if (child_widget)
@@ -3296,6 +3381,14 @@ gtk_scrolled_window_unrealize (GtkWidget *widget)
gdk_window_destroy (priv->overshoot_window);
priv->overshoot_window = NULL;
+ gdk_window_set_user_data (priv->vbackground_window, NULL);
+ gdk_window_destroy (priv->vbackground_window);
+ priv->vbackground_window = NULL;
+
+ gdk_window_set_user_data (priv->hbackground_window, NULL);
+ gdk_window_destroy (priv->hbackground_window);
+ priv->hbackground_window = NULL;
+
gtk_widget_set_realized (widget, FALSE);
GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unrealize (widget);
@@ -3308,6 +3401,15 @@ gtk_scrolled_window_map (GtkWidget *widget)
GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
gdk_window_show (priv->overshoot_window);
+ if (gdk_window_get_width (priv->vbackground_window) > 1)
+ gdk_window_show (priv->vbackground_window);
+ else
+ gdk_window_hide (priv->vbackground_window);
+
+ if (gdk_window_get_height (priv->hbackground_window) > 1)
+ gdk_window_show (priv->hbackground_window);
+ else
+ gdk_window_hide (priv->hbackground_window);
GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->map (widget);
}
@@ -3319,6 +3421,8 @@ gtk_scrolled_window_unmap (GtkWidget *widget)
GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window);
gdk_window_hide (priv->overshoot_window);
+ gdk_window_hide (priv->vbackground_window);
+ gdk_window_hide (priv->hbackground_window);
GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unmap (widget);
}
--
1.7.10.2 (Apple Git-33)

Some files were not shown because too many files have changed in this diff Show More