[gtk+/resizegrips] Try to make resize grip regular windows



commit 5b87b37689d0ff48d3afca44135a4c2f0ac277a9
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Sep 28 00:14:45 2010 -0400

    Try to make resize grip regular windows
    
    This doesn't quite work yet, since drawing to the grip seems broken.

 gtk/gtkwindow.c |  119 ++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 97 insertions(+), 22 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 6f97950..dcbaa46 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -323,6 +323,8 @@ static gint gtk_window_focus_out_event    (GtkWidget         *widget,
 					   GdkEventFocus     *event);
 static gint gtk_window_client_event	  (GtkWidget	     *widget,
 					   GdkEventClient    *event);
+static gboolean gtk_window_state_event    (GtkWidget          *widget,
+                                           GdkEventWindowState *event);
 static void gtk_window_check_resize       (GtkContainer      *container);
 static gint gtk_window_focus              (GtkWidget        *widget,
 				           GtkDirectionType  direction);
@@ -390,6 +392,7 @@ static void     get_grip_rect                         (GtkWindow    *window,
 static void     gtk_window_set_has_resize_grip        (GtkWindow    *window,
                                                        gboolean      value);
 static void     resize_grip_create_window             (GtkWindow    *window);
+static void     resize_grip_destroy_window            (GtkWindow    *window);
 
 static void        gtk_window_notify_keys_changed (GtkWindow   *window);
 static GtkKeyHash *gtk_window_get_key_hash        (GtkWindow   *window);
@@ -560,6 +563,7 @@ gtk_window_class_init (GtkWindowClass *klass)
   widget_class->draw = gtk_window_draw;
   widget_class->get_preferred_width = gtk_window_get_preferred_width;
   widget_class->get_preferred_height = gtk_window_get_preferred_height;
+  widget_class->window_state_event = gtk_window_state_event;
 
   container_class->check_resize = gtk_window_check_resize;
 
@@ -4638,9 +4642,6 @@ gtk_window_unmap (GtkWidget *widget)
   else
     gdk_window_withdraw (gdk_window);
 
-  if (priv->grip_window)
-    gdk_window_hide (priv->grip_window);
-
   priv->configure_request_count = 0;
   priv->configure_notify_received = FALSE;
 
@@ -4894,6 +4895,9 @@ gtk_window_unrealize (GtkWidget *widget)
   /* Icons */
   gtk_window_unrealize_icon (window);
 
+  if (priv->grip_window != NULL)
+    resize_grip_destroy_window (window);
+
   GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
 }
 
@@ -4936,6 +4940,50 @@ set_grip_cursor (GtkWindow *window)
 }
 
 static void
+set_grip_shape (GtkWindow *window)
+{
+  GtkWindowPrivate *priv = window->priv;
+
+  if (priv->has_resize_grip && priv->grip_window != NULL)
+    {
+      cairo_region_t *region;
+      cairo_surface_t *surface;
+      cairo_t *cr;
+      double width, height;
+
+
+      width = gdk_window_get_width (priv->grip_window);
+      height = gdk_window_get_height (priv->grip_window);
+      surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+
+      cr = cairo_create (surface);
+      cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
+      cairo_paint (cr);
+      cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+      if (get_grip_edge (GTK_WIDGET (window)) == GDK_WINDOW_EDGE_SOUTH_EAST)
+        {
+          cairo_move_to (cr, width, 0.0);
+          cairo_line_to (cr, width, height);
+          cairo_line_to (cr, 0.0, height);
+        }
+      else
+        {
+          cairo_move_to (cr, 0.0, 0.0);
+          cairo_line_to (cr, width, height);
+          cairo_line_to (cr, 0.0, height);
+        }
+      cairo_close_path (cr);
+      cairo_fill (cr);
+      cairo_destroy (cr);
+      region = gdk_cairo_region_create_from_surface (surface);
+      cairo_surface_destroy (surface);
+
+      gdk_window_shape_combine_region (priv->grip_window,
+                                       region, 0, 0);
+    }
+}
+
+static void
 gtk_window_size_allocate (GtkWidget     *widget,
 			  GtkAllocation *allocation)
 {
@@ -4979,6 +5027,7 @@ gtk_window_size_allocate (GtkWidget     *widget,
                               rect.width, rect.height);
 
       set_grip_cursor (window);
+      set_grip_shape (window);
     }
 }
 
@@ -5121,6 +5170,7 @@ get_grip_rect (GtkWindow    *window,
   style = gtk_widget_get_style (widget);
 
   /* These are in effect the max/default size of the grip. */
+  /* FIXME: need to take from style */
   w = 18;
   h = 18;
 
@@ -5141,6 +5191,35 @@ get_grip_rect (GtkWindow    *window,
 }
 
 static void
+set_grip_visibility (GtkWindow *window)
+{
+  GtkWindowPrivate *priv;
+  GdkWindowState state;
+
+  priv = window->priv;
+
+  state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window)));
+  if (priv->has_resize_grip && priv->resizable &&
+      (state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) == 0)
+    gdk_window_show (priv->grip_window);
+  else
+    gdk_window_hide (priv->grip_window);
+}
+
+static gboolean
+gtk_window_state_event (GtkWidget           *widget,
+                        GdkEventWindowState *event)
+{
+  GtkWindow *window = GTK_WINDOW (widget);
+  GtkWindowPrivate *priv = window->priv;
+
+  if (priv->grip_window)
+    set_grip_visibility (window);
+
+  return FALSE;
+}
+
+static void
 resize_grip_create_window (GtkWindow *window)
 {
   GtkWidget *widget;
@@ -5162,7 +5241,7 @@ resize_grip_create_window (GtkWindow *window)
   attributes.width = rect.width;
   attributes.height = rect.height;
   attributes.window_type = GDK_WINDOW_CHILD;
-  attributes.wclass = GDK_INPUT_ONLY;
+  attributes.wclass = GDK_INPUT_OUTPUT;
   attributes.event_mask = gtk_widget_get_events (widget) | GDK_BUTTON_PRESS_MASK;
 
   attributes_mask = GDK_WA_X | GDK_WA_Y;
@@ -5176,6 +5255,8 @@ resize_grip_create_window (GtkWindow *window)
   gdk_window_raise (priv->grip_window);
 
   set_grip_cursor (window);
+  set_grip_shape (window);
+  set_grip_visibility (window);
 }
 
 static void
@@ -5200,27 +5281,17 @@ gtk_window_set_has_resize_grip (GtkWindow *window,
   if (value != priv->has_resize_grip)
     {
       priv->has_resize_grip = value;
-      //gtk_widget_queue_resize (statusbar->label);  // XXX
       gtk_widget_queue_draw (widget);
 
       if (gtk_widget_get_realized (widget))
         {
           if (priv->has_resize_grip && priv->grip_window == NULL)
-            {
-              resize_grip_create_window (window);
-
-              if (gtk_widget_get_mapped (widget))
-                {
-                  gdk_window_show (priv->grip_window);
-                }
-            }
+            resize_grip_create_window (window);
           else if (!priv->has_resize_grip && priv->grip_window != NULL)
-            {
-              resize_grip_destroy_window (window);
-            }
+            resize_grip_destroy_window (window);
         }
 
-      g_object_notify (G_OBJECT (priv), "has-resize-grip");
+      g_object_notify (G_OBJECT (window), "has-resize-grip");
     }
 }
 
@@ -6897,22 +6968,23 @@ gtk_window_draw (GtkWidget *widget,
   if (GTK_WIDGET_CLASS (gtk_window_parent_class)->draw)
     ret = GTK_WIDGET_CLASS (gtk_window_parent_class)->draw (widget, cr);
 
-  if (priv->has_resize_grip)
+  if (priv->has_resize_grip && gtk_cairo_should_draw_window (cr, priv->grip_window))
     {
       GdkRectangle rect;
-      GtkAllocation allocation;
 
-      gtk_widget_get_allocation (widget, &allocation);
+      cairo_save (cr);
+      gtk_cairo_transform_to_window (cr, widget, priv->grip_window);
       get_grip_rect (GTK_WINDOW (widget), &rect);
-
       gtk_paint_resize_grip (gtk_widget_get_style (widget),
                              cr,
                              gtk_widget_get_state (widget),
                              widget,
                              "statusbar",
                              get_grip_edge (widget),
-                             rect.x, rect.y,
+                             0, 0,
                              rect.width, rect.height);
+
+      cairo_restore (cr);
     }
 
   return ret;
@@ -7556,6 +7628,9 @@ gtk_window_set_resizable (GtkWindow *window,
 
   g_object_notify (G_OBJECT (window), "resizable");
 
+  if (priv->grip_window != NULL)
+    set_grip_visibility (window);
+
   gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]