[gtk+/toplevel-embedding: 3/3] Special case some code in the case that the window is not toplevel.



commit f71c01532c233c35f80242cb4a6ab16541b6ba28
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Wed Dec 22 21:24:02 2010 +0900

    Special case some code in the case that the window is not toplevel.
    
    Several places are special cased, gtk_window_realize() creates
    a window child of the parent_window() and in several places it
    needs to handle things differently.

 gtk/gtkwindow.c |  153 ++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 96 insertions(+), 57 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 2723c42..7958e9b 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -4875,11 +4875,13 @@ gtk_window_realize (GtkWidget *widget)
   GtkAllocation allocation;
   GtkWindow *window;
   GdkWindow *parent_window;
+  GdkWindow *parent_parent_window;
   GdkWindow *gdk_window;
   GdkWindowAttr attributes;
   gint attributes_mask;
   GtkWindowPrivate *priv;
   GtkStyleContext *context;
+  gboolean embedded_window = FALSE;
 
   window = GTK_WINDOW (widget);
   priv = window->priv;
@@ -4933,8 +4935,20 @@ gtk_window_realize (GtkWidget *widget)
   attributes.wmclass_class = priv->wmclass_class;
   attributes.wclass = GDK_INPUT_OUTPUT;
   attributes.visual = gtk_widget_get_visual (widget);
+  attributes_mask   = 0;
 
-  if (priv->has_frame)
+  if (gtk_widget_get_parent_window (widget))
+    {
+      parent_parent_window = gtk_widget_get_parent_window (widget);
+      attributes.window_type = GDK_WINDOW_CHILD;
+      attributes_mask = GDK_WA_X | GDK_WA_Y;
+      embedded_window = TRUE;
+    }
+  else
+    parent_parent_window = gtk_widget_get_root_window (widget);
+
+  /* Only real windows can possibly have a frame */
+  if (!gtk_widget_get_parent_window (widget) && priv->has_frame)
     {
       gtk_widget_get_allocation (widget, &allocation);
       attributes.width = allocation.width + priv->frame_left + priv->frame_right;
@@ -4952,8 +4966,8 @@ gtk_window_realize (GtkWidget *widget)
       
       attributes_mask = GDK_WA_VISUAL;
 
-      priv->frame = gdk_window_new (gtk_widget_get_root_window (widget),
-				      &attributes, attributes_mask);
+      priv->frame = gdk_window_new (parent_parent_window,
+				    &attributes, attributes_mask);
 						 
       if (priv->opacity_set)
 	gdk_window_set_opacity (priv->frame, priv->opacity);
@@ -4974,10 +4988,7 @@ gtk_window_realize (GtkWidget *widget)
 			NULL);
     }
   else
-    {
-      attributes_mask = 0;
-      parent_window = gtk_widget_get_root_window (widget);
-    }
+    parent_window = parent_parent_window;
 
   gtk_widget_get_allocation (widget, &allocation);
   attributes.width = allocation.width;
@@ -5002,7 +5013,8 @@ gtk_window_realize (GtkWidget *widget)
   if (!priv->has_frame && priv->opacity_set)
     gdk_window_set_opacity (gdk_window, priv->opacity);
 
-  gdk_window_enable_synchronized_configure (gdk_window);
+  if (!embedded_window)
+    gdk_window_enable_synchronized_configure (gdk_window);
 
   gdk_window_set_user_data (gdk_window, window);
 
@@ -5013,57 +5025,61 @@ gtk_window_realize (GtkWidget *widget)
   if (priv->frame)
     gtk_style_context_set_background (context, priv->frame);
 
+
   if (priv->transient_parent &&
       gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)))
     gdk_window_set_transient_for (gdk_window,
                                   gtk_widget_get_window (GTK_WIDGET (priv->transient_parent)));
 
-  if (priv->wm_role)
-    gdk_window_set_role (gdk_window, priv->wm_role);
-
-  if (!priv->decorated)
-    gdk_window_set_decorations (gdk_window, 0);
-
-  if (!priv->deletable)
-    gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
-
-  if (gtk_window_get_skip_pager_hint (window))
-    gdk_window_set_skip_pager_hint (gdk_window, TRUE);
-
-  if (gtk_window_get_skip_taskbar_hint (window))
-    gdk_window_set_skip_taskbar_hint (gdk_window, TRUE);
-
-  if (gtk_window_get_accept_focus (window))
-    gdk_window_set_accept_focus (gdk_window, TRUE);
-  else
-    gdk_window_set_accept_focus (gdk_window, FALSE);
-
-  if (gtk_window_get_focus_on_map (window))
-    gdk_window_set_focus_on_map (gdk_window, TRUE);
-  else
-    gdk_window_set_focus_on_map (gdk_window, FALSE);
-
-  if (priv->modal)
-    gdk_window_set_modal_hint (gdk_window, TRUE);
-  else
-    gdk_window_set_modal_hint (gdk_window, FALSE);
-
-  if (priv->startup_id)
+  if (!embedded_window)
     {
+      if (priv->wm_role)
+	gdk_window_set_role (gdk_window, priv->wm_role);
+      
+      if (!priv->decorated)
+	gdk_window_set_decorations (gdk_window, 0);
+      
+      if (!priv->deletable)
+	gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
+      
+      if (gtk_window_get_skip_pager_hint (window))
+	gdk_window_set_skip_pager_hint (gdk_window, TRUE);
+
+      if (gtk_window_get_skip_taskbar_hint (window))
+	gdk_window_set_skip_taskbar_hint (gdk_window, TRUE);
+      
+      if (gtk_window_get_accept_focus (window))
+	gdk_window_set_accept_focus (gdk_window, TRUE);
+      else
+	gdk_window_set_accept_focus (gdk_window, FALSE);
+      
+      if (gtk_window_get_focus_on_map (window))
+	gdk_window_set_focus_on_map (gdk_window, TRUE);
+      else
+	gdk_window_set_focus_on_map (gdk_window, FALSE);
+      
+      if (priv->modal)
+	gdk_window_set_modal_hint (gdk_window, TRUE);
+      else
+	gdk_window_set_modal_hint (gdk_window, FALSE);
+      
+      if (priv->startup_id)
+	{
 #ifdef GDK_WINDOWING_X11
-      guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
-      if (timestamp != GDK_CURRENT_TIME)
-        gdk_x11_window_set_user_time (gdk_window, timestamp);
+	  guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
+	  if (timestamp != GDK_CURRENT_TIME)
+	    gdk_x11_window_set_user_time (gdk_window, timestamp);
 #endif
-      if (!startup_id_is_fake (priv->startup_id)) 
-        gdk_window_set_startup_id (gdk_window, priv->startup_id);
+	  if (!startup_id_is_fake (priv->startup_id)) 
+	    gdk_window_set_startup_id (gdk_window, priv->startup_id);
+	}
+      
+      /* Icons */
+      gtk_window_realize_icon (window);
+      
+      if (priv->has_resize_grip)
+	resize_grip_create_window (window);
     }
-
-  /* Icons */
-  gtk_window_realize_icon (window);
-
-  if (priv->has_resize_grip)
-    resize_grip_create_window (window);
 }
 
 static void
@@ -5294,12 +5310,25 @@ gtk_window_size_allocate (GtkWidget     *widget,
 
   if (gtk_widget_get_realized (widget))
     {
-      if (priv->frame)
-        gdk_window_resize (priv->frame,
-                           allocation->width + priv->frame_left + priv->frame_right,
-                           allocation->height + priv->frame_top + priv->frame_bottom);
-      update_grip_visibility (window);
-      set_grip_position (window);
+      /* If it's not a toplevel we're embedded, we need to resize the window's 
+       * window and skip the grip.
+       */
+      if (!gtk_widget_is_toplevel (widget))
+	{
+	  gdk_window_move_resize (gtk_widget_get_window (widget),
+				  allocation->x, allocation->y,
+				  allocation->width, allocation->height);
+	}
+      else
+	{
+	  if (priv->frame)
+	    gdk_window_resize (priv->frame,
+			       allocation->width + priv->frame_left + priv->frame_right,
+			       allocation->height + priv->frame_top + priv->frame_bottom);
+	  
+	  update_grip_visibility (window);
+	  set_grip_position (window);
+	}
     }
 }
 
@@ -6044,7 +6073,11 @@ gtk_window_client_event (GtkWidget	*widget,
 static void
 gtk_window_check_resize (GtkContainer *container)
 {
-  if (gtk_widget_get_visible (GTK_WIDGET (container)))
+  /* If the window is not toplevel anymore than it's embedded somewhere,
+   * so handle it like a normal window */
+  if (!gtk_widget_is_toplevel (GTK_WIDGET (container)))
+    GTK_CONTAINER_CLASS (gtk_window_parent_class)->check_resize (container);
+  else if (gtk_widget_get_visible (GTK_WIDGET (container)))
     gtk_window_move_resize (GTK_WINDOW (container));
 }
 
@@ -6802,6 +6835,7 @@ gtk_window_move_resize (GtkWindow *window)
   GtkWindowLastGeometryInfo saved_last_info;
   
   widget = GTK_WIDGET (window);
+
   gdk_window = gtk_widget_get_window (widget);
   container = GTK_CONTAINER (widget);
   info = gtk_window_get_geometry_info (window, TRUE);
@@ -7429,6 +7463,11 @@ gtk_window_draw (GtkWidget *widget,
   GtkStyleContext *context;
   gboolean ret = FALSE;
 
+  /* If the window is not toplevel anymore than it's embedded somewhere,
+   * so just chain up and paint the children */
+  if (!gtk_widget_is_toplevel (widget))
+    return GTK_WIDGET_CLASS (gtk_window_parent_class)->draw (widget, cr);
+
   context = gtk_widget_get_style_context (widget);
 
   gtk_style_context_save (context);



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