gtkwindow: Only allow unrestricted positioning to text handle popovers
authorCarlos Garnacho <carlosg@gnome.org>
Mon, 6 Jul 2015 14:39:06 +0000 (16:39 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Mon, 6 Jul 2015 14:39:06 +0000 (16:39 +0200)
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
gtk/gtktexthandle.c
gtk/gtkwindow.c
gtk/gtkwindowprivate.h

index e2e7942eaed198c41b6a380e2425a6053652d197..55d4085b2ee49d0c5396d7f5a796415672938df4 100644 (file)
@@ -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));
index c89cf6339cb5f815ca619543bd5f25a1bff5498d..da9828728bd963a70e51fc4e1fdcbe9aef047875 100644 (file)
@@ -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));
index e0d6e8b3f8705bd23dcdb758a08db78628d69de7..e87828083963c3ea634c2ae3bd8209cecfcc7783 100644 (file)
@@ -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)))
index a8236b0c9fa8a600f19c367cbe6d1fb91879248f..c9a2a8a180f4d352107a186e33a542753810eab5 100644 (file)
@@ -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,