From 7f57f63ebaa8e3d12bdaef0ebc730cd81c9bb2fe Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 6 Jul 2015 16:39:06 +0200 Subject: [PATCH] gtkwindow: Only allow unrestricted positioning to text handle popovers This behavior has been made optional on add_popover() time, text handles will keep being able to overflow the window, in order to allow text selection on views too close to the window edge. Regular GtkPopovers are reinstaurated to the previous size positioning logic though, that is, limited by the visible area of the window. --- gtk/gtkpopover.c | 4 ++-- gtk/gtktexthandle.c | 2 +- gtk/gtkwindow.c | 36 +++++++++++++++++++++++++++++++----- gtk/gtkwindowprivate.h | 3 ++- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c index e2e7942eae..55d4085b2e 100644 --- a/gtk/gtkpopover.c +++ b/gtk/gtkpopover.c @@ -1699,7 +1699,7 @@ _gtk_popover_parent_hierarchy_changed (GtkWidget *widget, _gtk_window_remove_popover (priv->window, GTK_WIDGET (popover)); if (new_window) - _gtk_window_add_popover (new_window, GTK_WIDGET (popover), priv->widget); + _gtk_window_add_popover (new_window, GTK_WIDGET (popover), priv->widget, TRUE); priv->window = new_window; @@ -1970,7 +1970,7 @@ gtk_popover_update_relative_to (GtkPopover *popover, } if (priv->window) - _gtk_window_add_popover (priv->window, GTK_WIDGET (popover), priv->widget); + _gtk_window_add_popover (priv->window, GTK_WIDGET (popover), priv->widget, TRUE); if (relative_to) scrollable = GTK_SCROLLABLE (gtk_widget_get_ancestor (priv->widget, GTK_TYPE_SCROLLABLE)); diff --git a/gtk/gtktexthandle.c b/gtk/gtktexthandle.c index c89cf6339c..da9828728b 100644 --- a/gtk/gtktexthandle.c +++ b/gtk/gtktexthandle.c @@ -307,7 +307,7 @@ _gtk_text_handle_ensure_widget (GtkTextHandle *handle, priv->windows[pos].widget = g_object_ref_sink (widget); window = gtk_widget_get_ancestor (priv->parent, GTK_TYPE_WINDOW); - _gtk_window_add_popover (GTK_WINDOW (window), widget, priv->parent); + _gtk_window_add_popover (GTK_WINDOW (window), widget, priv->parent, FALSE); gtk_style_context_set_parent (gtk_widget_get_style_context (widget), gtk_widget_get_style_context (priv->parent)); diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index e0d6e8b3f8..e878280839 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -143,6 +143,7 @@ struct _GtkWindowPopover GtkPositionType pos; cairo_rectangle_int_t rect; gulong unmap_id; + guint clamp_allocation : 1; }; struct _GtkWindowPrivate @@ -6356,6 +6357,7 @@ popover_get_rect (GtkWindowPopover *popover, GtkAllocation win_alloc; GtkRequisition req; GtkBorder win_border; + gdouble min, max; gtk_widget_get_preferred_size (popover->widget, NULL, &req); gtk_widget_get_allocation (GTK_WIDGET (window), &win_alloc); @@ -6378,8 +6380,19 @@ popover_get_rect (GtkWindowPopover *popover, rect->height = win_alloc.height; } else - rect->y = CLAMP (popover->rect.y + (popover->rect.height / 2) - - (req.height / 2), 0, win_alloc.y + win_alloc.height + win_border.bottom - req.height); + { + min = 0; + max = win_alloc.y + win_alloc.height + win_border.bottom - req.height; + + if (popover->clamp_allocation) + { + min += win_border.top; + max -= win_border.bottom; + } + + rect->y = CLAMP (popover->rect.y + (popover->rect.height / 2) - + (req.height / 2), min, max); + } if ((popover->pos == GTK_POS_LEFT) == (gtk_widget_get_direction (popover->widget) == GTK_TEXT_DIR_LTR)) @@ -6410,8 +6423,19 @@ popover_get_rect (GtkWindowPopover *popover, rect->width = win_alloc.width; } else - rect->x = CLAMP (popover->rect.x + (popover->rect.width / 2) - - (req.width / 2), 0, win_alloc.x + win_alloc.width + win_border.right - req.width); + { + min = 0; + max = win_alloc.x + win_alloc.width + win_border.right - req.width; + + if (popover->clamp_allocation) + { + min += win_border.left; + max -= win_border.right; + } + + rect->x = CLAMP (popover->rect.x + (popover->rect.width / 2) - + (req.width / 2), min, max); + } if (popover->pos == GTK_POS_TOP) { @@ -11822,7 +11846,8 @@ _gtk_window_get_shadow_width (GtkWindow *window, void _gtk_window_add_popover (GtkWindow *window, GtkWidget *popover, - GtkWidget *parent) + GtkWidget *parent, + gboolean clamp_allocation) { GtkWindowPrivate *priv; GtkWindowPopover *data; @@ -11842,6 +11867,7 @@ _gtk_window_add_popover (GtkWindow *window, data = g_new0 (GtkWindowPopover, 1); data->widget = popover; data->parent = parent; + data->clamp_allocation = !!clamp_allocation; priv->popovers = g_list_prepend (priv->popovers, data); if (gtk_widget_get_realized (GTK_WIDGET (window))) diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h index a8236b0c9f..c9a2a8a180 100644 --- a/gtk/gtkwindowprivate.h +++ b/gtk/gtkwindowprivate.h @@ -105,7 +105,8 @@ void _gtk_window_set_window_group (GtkWindow *window, /* Popovers */ void _gtk_window_add_popover (GtkWindow *window, GtkWidget *popover, - GtkWidget *popover_parent); + GtkWidget *popover_parent, + gboolean clamp_allocation); void _gtk_window_remove_popover (GtkWindow *window, GtkWidget *popover); void _gtk_window_set_popover_position (GtkWindow *window,