[gtk+/wip/frame-window] csd: add a frame window
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/frame-window] csd: add a frame window
- Date: Sat, 25 May 2013 22:21:43 +0000 (UTC)
commit b8391bf2caada94c28f0887d8739e19129e8939c
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Apr 28 17:49:49 2013 -0400
csd: add a frame window
To improve the compatibility of client-side decorations with
traditional decorations, we introduce a frame window, which is
the actual toplevel. widget->window for the GtkWindow is a child
of this window, and just as with traditional window decorations,
corresponds to the window content.
All sizes (default size, size allocation, parameters given
to gtk_window_resize, etc) refer to the size of the content.
The resize handle windows and the titlebar widgets are children
of the frame window.
gtk/gtkwindow.c | 848 ++++++++++++++++++++++++-------------------------------
1 files changed, 374 insertions(+), 474 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 6970c7d..3b94740 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -155,6 +155,7 @@ struct _GtkWindowPrivate
GtkWidget *popup_menu;
GdkWindow *border_window[8];
+ GdkWindow *frame_window;
/* The following flags are initially TRUE (before a window is mapped).
* They cause us to compute a configure request that involves
@@ -296,6 +297,7 @@ typedef struct {
GdkGeometry geometry; /* Last set of geometry hints we set */
GdkWindowHints flags;
GdkRectangle configure_request;
+ gint title_height;
} GtkWindowLastGeometryInfo;
struct _GtkWindowGeometryInfo
@@ -338,7 +340,7 @@ struct _GtkWindowGeometryInfo
* increments and affect the geometry widget only
*/
guint resize_is_geometry : 1;
-
+
GtkWindowLastGeometryInfo last;
};
@@ -491,6 +493,9 @@ static void gtk_window_get_preferred_height_for_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
+static void get_decoration_size (GtkWindow *window,
+ GtkBorder *decorations);
+
static GSList *toplevel_list = NULL;
static guint window_signals[LAST_SIGNAL] = { 0 };
static GList *default_icon_list = NULL;
@@ -1203,11 +1208,11 @@ gtk_window_class_init (GtkWindowClass *klass)
static gboolean
gtk_window_get_maximized (GtkWindow *window)
{
- GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+ GtkWindowPrivate *priv = window->priv;
gboolean maximized = FALSE;
- if (gdk_window)
- maximized = (gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_MAXIMIZED);
+ if (priv->frame_window)
+ maximized = (gdk_window_get_state (priv->frame_window) & GDK_WINDOW_STATE_MAXIMIZED);
return maximized;
}
@@ -1234,12 +1239,13 @@ gtk_window_title_max_clicked (GtkWidget *widget, gpointer data)
static gboolean
send_delete_event (gpointer data)
{
- GtkWidget *window = GTK_WIDGET (data);
+ GtkWindow *window = GTK_WINDOW (data);
+ GtkWindowPrivate *priv = window->priv;
GdkEvent *event;
event = gdk_event_new (GDK_DELETE);
- event->any.window = g_object_ref (gtk_widget_get_window (window));
+ event->any.window = g_object_ref (priv->frame_window);
event->any.send_event = TRUE;
gtk_main_do_event (event);
@@ -1788,7 +1794,7 @@ gtk_window_set_title (GtkWindow *window,
priv->title = new_title;
if (gtk_widget_get_realized (widget))
- gdk_window_set_title (gtk_widget_get_window (widget), priv->title);
+ gdk_window_set_title (priv->frame_window, priv->title);
if (priv->title_box != NULL)
gtk_header_bar_set_title (GTK_HEADER_BAR (priv->title_box), priv->title);
@@ -1886,8 +1892,7 @@ gtk_window_set_role (GtkWindow *window,
priv->wm_role = new_role;
if (gtk_widget_get_realized (GTK_WIDGET (window)))
- gdk_window_set_role (gtk_widget_get_window (GTK_WIDGET (window)),
- priv->wm_role);
+ gdk_window_set_role (priv->frame_window, priv->wm_role);
g_object_notify (G_OBJECT (window), "role");
}
@@ -1927,14 +1932,11 @@ gtk_window_set_startup_id (GtkWindow *window,
if (gtk_widget_get_realized (widget))
{
- GdkWindow *gdk_window;
guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
- gdk_window = gtk_widget_get_window (widget);
-
#ifdef GDK_WINDOWING_X11
- if (timestamp != GDK_CURRENT_TIME && GDK_IS_X11_WINDOW(gdk_window))
- gdk_x11_window_set_user_time (gdk_window, timestamp);
+ if (timestamp != GDK_CURRENT_TIME && GDK_IS_X11_WINDOW(priv->frame_window))
+ gdk_x11_window_set_user_time (priv->frame_window, timestamp);
#endif
/* Here we differentiate real and "fake" startup notification IDs,
@@ -1944,8 +1946,7 @@ gtk_window_set_startup_id (GtkWindow *window,
gtk_window_present_with_time (window, timestamp);
else
{
- gdk_window_set_startup_id (gdk_window,
- priv->startup_id);
+ gdk_window_set_startup_id (priv->frame_window, priv->startup_id);
/* If window is mapped, terminate the startup-notification too */
if (gtk_widget_get_mapped (widget) &&
@@ -3318,16 +3319,13 @@ void
gtk_window_set_hide_titlebar_when_maximized (GtkWindow *window,
gboolean setting)
{
+ GtkWindowPrivate *priv = window->priv;
g_return_if_fail (GTK_IS_WINDOW (window));
#ifdef GDK_WINDOWING_X11
{
- GdkWindow *gdk_window;
-
- gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
-
- if (GDK_IS_X11_WINDOW (gdk_window))
- gdk_x11_window_set_hide_titlebar_when_maximized (gdk_window, setting);
+ if (GDK_IS_X11_WINDOW (priv->frame_window))
+ gdk_x11_window_set_hide_titlebar_when_maximized (priv->frame_window, setting);
}
#endif
@@ -3380,6 +3378,7 @@ gtk_window_get_geometry_info (GtkWindow *window,
info->last.configure_request.y = 0;
info->last.configure_request.width = -1;
info->last.configure_request.height = -1;
+ info->last.title_height = 0;
info->widget = NULL;
info->mask = 0;
priv->geometry_info = info;
@@ -3514,7 +3513,6 @@ gtk_window_set_decorated (GtkWindow *window,
gboolean setting)
{
GtkWindowPrivate *priv;
- GdkWindow *gdk_window;
g_return_if_fail (GTK_IS_WINDOW (window));
@@ -3527,20 +3525,19 @@ gtk_window_set_decorated (GtkWindow *window,
priv->decorated = setting;
- gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
- if (gdk_window)
+ if (priv->frame_window)
{
if (priv->decorated)
{
if (priv->client_decorated)
- gdk_window_set_decorations (gdk_window, 0);
+ gdk_window_set_decorations (priv->frame_window, 0);
else if (priv->custom_title)
- gdk_window_set_decorations (gdk_window, GDK_DECOR_BORDER);
+ gdk_window_set_decorations (priv->frame_window, GDK_DECOR_BORDER);
else
- gdk_window_set_decorations (gdk_window, GDK_DECOR_ALL);
+ gdk_window_set_decorations (priv->frame_window, GDK_DECOR_ALL);
}
else
- gdk_window_set_decorations (gdk_window, 0);
+ gdk_window_set_decorations (priv->frame_window, 0);
}
update_window_buttons (window);
@@ -3589,7 +3586,6 @@ gtk_window_set_deletable (GtkWindow *window,
gboolean setting)
{
GtkWindowPrivate *priv;
- GdkWindow *gdk_window;
g_return_if_fail (GTK_IS_WINDOW (window));
@@ -3602,14 +3598,13 @@ gtk_window_set_deletable (GtkWindow *window,
priv->deletable = setting;
- gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
- if (gdk_window)
+ if (priv->frame_window)
{
if (priv->deletable)
- gdk_window_set_functions (gdk_window,
+ gdk_window_set_functions (priv->frame_window,
GDK_FUNC_ALL);
else
- gdk_window_set_functions (gdk_window,
+ gdk_window_set_functions (priv->frame_window,
GDK_FUNC_ALL | GDK_FUNC_CLOSE);
}
@@ -3745,13 +3740,11 @@ gtk_window_realize_icon (GtkWindow *window)
GtkWindowPrivate *priv = window->priv;
GtkWidget *widget;
GtkWindowIconInfo *info;
- GdkWindow *gdk_window;
GList *icon_list;
widget = GTK_WIDGET (window);
- gdk_window = gtk_widget_get_window (widget);
- g_return_if_fail (gdk_window != NULL);
+ g_return_if_fail (priv->frame_window != NULL);
/* no point setting an icon on override-redirect */
if (priv->type == GTK_WINDOW_POPUP)
@@ -3804,7 +3797,7 @@ gtk_window_realize_icon (GtkWindow *window)
info->realized = TRUE;
- gdk_window_set_icon_list (gtk_widget_get_window (widget), icon_list);
+ gdk_window_set_icon_list (priv->frame_window, icon_list);
set_title_icon (window, icon_list);
if (info->using_themed_icon)
@@ -4679,12 +4672,13 @@ gtk_window_move (GtkWindow *window,
{
GtkWindowGeometryInfo *info;
GtkWidget *widget;
+ GtkWindowPrivate *priv = window->priv;
g_return_if_fail (GTK_IS_WINDOW (window));
widget = GTK_WIDGET (window);
- info = gtk_window_get_geometry_info (window, TRUE);
+ info = gtk_window_get_geometry_info (window, TRUE);
if (gtk_widget_get_mapped (widget))
{
@@ -4719,7 +4713,7 @@ gtk_window_move (GtkWindow *window,
* the same as the position being changed by the window
* manager.
*/
- gdk_window_move (gtk_widget_get_window (GTK_WIDGET (window)), x, y);
+ gdk_window_move (priv->frame_window, x, y);
}
else
{
@@ -4784,13 +4778,11 @@ gtk_window_get_position (GtkWindow *window,
{
GtkWindowPrivate *priv;
GtkWidget *widget;
- GdkWindow *gdk_window;
g_return_if_fail (GTK_IS_WINDOW (window));
priv = window->priv;
widget = GTK_WIDGET (window);
- gdk_window = gtk_widget_get_window (widget);
if (priv->gravity == GDK_GRAVITY_STATIC)
{
@@ -4803,7 +4795,7 @@ gtk_window_get_position (GtkWindow *window,
* do. We should likely be consistent about whether we get
* the client-side info or the server-side info.
*/
- gdk_window_get_origin (gdk_window, root_x, root_y);
+ gdk_window_get_origin (gtk_widget_get_window (widget), root_x, root_y);
}
else
{
@@ -4824,9 +4816,9 @@ gtk_window_get_position (GtkWindow *window,
gint x, y;
gint w, h;
- if (gtk_widget_get_mapped (widget))
+ if (gtk_widget_get_mapped (widget) && priv->frame_window)
{
- gdk_window_get_frame_extents (gdk_window, &frame_extents);
+ gdk_window_get_frame_extents (priv->frame_window, &frame_extents);
x = frame_extents.x;
y = frame_extents.y;
gtk_window_get_size (window, &w, &h);
@@ -4835,6 +4827,7 @@ gtk_window_get_position (GtkWindow *window,
{
/* We just say the frame has 0 size on all sides.
* Not sure what else to do.
+ * FIXME: could do better here for csd
*/
gtk_window_compute_configure_request (window,
&frame_extents,
@@ -5217,6 +5210,8 @@ create_decoration (GtkWidget *widget)
if (priv->title_box == NULL)
{
priv->title_box = gtk_header_bar_new ();
+ if (gtk_widget_get_realized (widget))
+ gtk_widget_set_parent_window (priv->title_box, priv->frame_window);
g_object_set (priv->title_box,
"spacing", 0,
"hpadding", 0,
@@ -5283,14 +5278,14 @@ gtk_window_show (GtkWidget *widget)
&configure_request,
&new_geometry,
&new_flags);
-
+
/* We update this because we are going to go ahead
* and gdk_window_resize() below, rather than
* queuing it.
*/
info->last.configure_request.width = configure_request.width;
info->last.configure_request.height = configure_request.height;
-
+
/* and allocate the window - this is normally done
* in move_resize in response to configure notify
*/
@@ -5362,7 +5357,6 @@ gtk_window_map (GtkWidget *widget)
GtkWidget *child;
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = window->priv;
- GdkWindow *gdk_window;
gboolean auto_mnemonics;
GtkPolicyType visible_focus;
@@ -5381,31 +5375,29 @@ gtk_window_map (GtkWidget *widget)
if (priv->title_box != NULL)
gtk_widget_map (priv->title_box);
- gdk_window = gtk_widget_get_window (widget);
-
if (priv->maximize_initially)
- gdk_window_maximize (gdk_window);
+ gdk_window_maximize (priv->frame_window);
else
- gdk_window_unmaximize (gdk_window);
+ gdk_window_unmaximize (priv->frame_window);
if (priv->stick_initially)
- gdk_window_stick (gdk_window);
+ gdk_window_stick (priv->frame_window);
else
- gdk_window_unstick (gdk_window);
+ gdk_window_unstick (priv->frame_window);
if (priv->iconify_initially)
- gdk_window_iconify (gdk_window);
+ gdk_window_iconify (priv->frame_window);
else
- gdk_window_deiconify (gdk_window);
+ gdk_window_deiconify (priv->frame_window);
if (priv->fullscreen_initially)
- gdk_window_fullscreen (gdk_window);
+ gdk_window_fullscreen (priv->frame_window);
else
- gdk_window_unfullscreen (gdk_window);
+ gdk_window_unfullscreen (priv->frame_window);
- gdk_window_set_keep_above (gdk_window, priv->above_initially);
+ gdk_window_set_keep_above (priv->frame_window, priv->above_initially);
- gdk_window_set_keep_below (gdk_window, priv->below_initially);
+ gdk_window_set_keep_below (priv->frame_window, priv->below_initially);
if (priv->type == GTK_WINDOW_TOPLEVEL)
{
@@ -5425,15 +5417,17 @@ gtk_window_map (GtkWidget *widget)
* Some applications use X directly to change the properties;
* in that case, we shouldn't overwrite what they did.
*/
- gdk_window_set_type_hint (gdk_window, priv->gdk_type_hint);
+ gdk_window_set_type_hint (priv->frame_window, priv->gdk_type_hint);
priv->reset_type_hint = FALSE;
}
- gdk_window_show (gdk_window);
+ gdk_window_show (gtk_widget_get_window (widget));
if (priv->grip_window)
gdk_window_show (priv->grip_window);
+ gdk_window_show (priv->frame_window);
+
if (!disable_startup_notification)
{
/* Do we have a custom startup-notification id? */
@@ -5486,7 +5480,7 @@ gtk_window_map_event (GtkWidget *widget,
* the window being unmapped. more details can be found in:
* http://bugzilla.gnome.org/show_bug.cgi?id=316180
*/
- gdk_window_hide (gtk_widget_get_window (widget));
+ gdk_window_hide (GTK_WINDOW (widget)->priv->frame_window);
}
return FALSE;
}
@@ -5498,7 +5492,6 @@ gtk_window_unmap (GtkWidget *widget)
GtkWindowPrivate *priv = window->priv;
GtkWidget *child;
GtkWindowGeometryInfo *info;
- GdkWindow *gdk_window;
GdkWindowState state;
if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
@@ -5507,10 +5500,8 @@ gtk_window_unmap (GtkWidget *widget)
return;
}
- gdk_window = gtk_widget_get_window (widget);
-
gtk_widget_set_mapped (widget, FALSE);
- gdk_window_withdraw (gdk_window);
+ gdk_window_withdraw (priv->frame_window);
priv->configure_request_count = 0;
priv->configure_notify_received = FALSE;
@@ -5528,7 +5519,7 @@ gtk_window_unmap (GtkWidget *widget)
info->position_constraints_changed = FALSE;
}
- state = gdk_window_get_state (gdk_window);
+ state = gdk_window_get_state (priv->frame_window);
priv->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
priv->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
priv->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
@@ -5649,6 +5640,8 @@ gtk_window_realize (GtkWidget *widget)
GdkWindowAttr attributes;
gint attributes_mask;
GtkWindowPrivate *priv;
+ GtkBorder border;
+ gint title_height = 0;
gint i;
window = GTK_WINDOW (widget);
@@ -5709,14 +5702,14 @@ gtk_window_realize (GtkWidget *widget)
allocation.height = 200;
}
gtk_widget_size_allocate (widget, &allocation);
-
+
_gtk_container_queue_resize (GTK_CONTAINER (widget));
g_return_if_fail (!gtk_widget_get_realized (widget));
}
-
+
gtk_widget_set_realized (widget, TRUE);
-
+
switch (priv->type)
{
case GTK_WINDOW_TOPLEVEL:
@@ -5740,8 +5733,15 @@ gtk_window_realize (GtkWidget *widget)
parent_window = gtk_widget_get_root_window (widget);
gtk_widget_get_allocation (widget, &allocation);
- attributes.width = allocation.width;
- attributes.height = allocation.height;
+ if (priv->title_box)
+ gtk_widget_get_preferred_height_for_width (priv->title_box,
+ allocation.width,
+ NULL,
+ &title_height);
+ get_decoration_size (window, &border);
+
+ attributes.width = allocation.width + border.left + border.right;
+ attributes.height = allocation.height + border.top + border.bottom + title_height;
attributes.event_mask = gtk_widget_get_events (widget);
attributes.event_mask |= (GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK |
@@ -5762,7 +5762,17 @@ gtk_window_realize (GtkWidget *widget)
attributes_mask |= (priv->title ? GDK_WA_TITLE : 0);
attributes_mask |= (priv->wmclass_name ? GDK_WA_WMCLASS : 0);
- gdk_window = gdk_window_new (parent_window, &attributes, attributes_mask);
+ priv->frame_window = gdk_window_new (parent_window, &attributes, attributes_mask);
+ gtk_widget_register_window (widget, priv->frame_window);
+
+ attributes.x = border.left;
+ attributes.y = border.top + title_height;
+ attributes.width = allocation.width;
+ attributes.height = allocation.height;
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes_mask |= GDK_WA_X | GDK_WA_Y;
+
+ gdk_window = gdk_window_new (priv->frame_window, &attributes, attributes_mask);
gtk_widget_set_window (widget, gdk_window);
gtk_widget_register_window (widget, gdk_window);
@@ -5772,19 +5782,6 @@ gtk_window_realize (GtkWidget *widget)
if (!priv->client_decorated)
gtk_style_context_set_background (gtk_widget_get_style_context (widget), gdk_window);
- attributes.x = allocation.x;
- attributes.y = allocation.y;
- attributes.width = allocation.width;
- attributes.height = allocation.height;
- attributes.window_type = GDK_WINDOW_CHILD;
-
- attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK;
-
- attributes.visual = gtk_widget_get_visual (widget);
- attributes.wclass = GDK_INPUT_OUTPUT;
-
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
-
if (priv->client_decorated)
{
GdkCursorType cursor_type[8] = {
@@ -5807,7 +5804,7 @@ gtk_window_realize (GtkWidget *widget)
for (i = 0; i < 8; i++)
{
attributes.cursor = gdk_cursor_new (cursor_type[i]);
- priv->border_window[i] = gdk_window_new (gdk_window, &attributes, attributes_mask);
+ priv->border_window[i] = gdk_window_new (priv->frame_window, &attributes, attributes_mask);
g_object_unref (attributes.cursor);
gdk_window_show (priv->border_window[i]);
@@ -5817,60 +5814,60 @@ gtk_window_realize (GtkWidget *widget)
if (priv->transient_parent &&
gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)))
- gdk_window_set_transient_for (gdk_window,
+ gdk_window_set_transient_for (priv->frame_window,
gtk_widget_get_window (GTK_WIDGET (priv->transient_parent)));
if (priv->wm_role)
- gdk_window_set_role (gdk_window, priv->wm_role);
+ gdk_window_set_role (priv->frame_window, priv->wm_role);
if (!priv->decorated || priv->client_decorated)
- gdk_window_set_decorations (gdk_window, 0);
+ gdk_window_set_decorations (priv->frame_window, 0);
else if (priv->custom_title)
- gdk_window_set_decorations (gdk_window, GDK_DECOR_BORDER);
+ gdk_window_set_decorations (priv->frame_window, GDK_DECOR_BORDER);
if (!priv->deletable)
- gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
+ gdk_window_set_functions (priv->frame_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
if (gtk_window_get_skip_pager_hint (window))
- gdk_window_set_skip_pager_hint (gdk_window, TRUE);
+ gdk_window_set_skip_pager_hint (priv->frame_window, TRUE);
if (gtk_window_get_skip_taskbar_hint (window))
- gdk_window_set_skip_taskbar_hint (gdk_window, TRUE);
+ gdk_window_set_skip_taskbar_hint (priv->frame_window, TRUE);
if (gtk_window_get_accept_focus (window))
- gdk_window_set_accept_focus (gdk_window, TRUE);
+ gdk_window_set_accept_focus (priv->frame_window, TRUE);
else
- gdk_window_set_accept_focus (gdk_window, FALSE);
+ gdk_window_set_accept_focus (priv->frame_window, FALSE);
if (gtk_window_get_focus_on_map (window))
- gdk_window_set_focus_on_map (gdk_window, TRUE);
+ gdk_window_set_focus_on_map (priv->frame_window, TRUE);
else
- gdk_window_set_focus_on_map (gdk_window, FALSE);
+ gdk_window_set_focus_on_map (priv->frame_window, FALSE);
if (priv->modal)
- gdk_window_set_modal_hint (gdk_window, TRUE);
+ gdk_window_set_modal_hint (priv->frame_window, TRUE);
else
- gdk_window_set_modal_hint (gdk_window, FALSE);
+ gdk_window_set_modal_hint (priv->frame_window, FALSE);
if (priv->startup_id)
{
#ifdef GDK_WINDOWING_X11
- if (GDK_IS_X11_WINDOW (gdk_window))
+ if (GDK_IS_X11_WINDOW (priv->frame_window))
{
guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
if (timestamp != GDK_CURRENT_TIME)
- gdk_x11_window_set_user_time (gdk_window, timestamp);
+ gdk_x11_window_set_user_time (priv->frame_window, timestamp);
}
#endif
if (!startup_id_is_fake (priv->startup_id))
- gdk_window_set_startup_id (gdk_window, priv->startup_id);
+ gdk_window_set_startup_id (priv->frame_window, priv->startup_id);
}
#ifdef GDK_WINDOWING_X11
if (priv->initial_timestamp != GDK_CURRENT_TIME)
{
- if (GDK_IS_X11_WINDOW (gdk_window))
- gdk_x11_window_set_user_time (gdk_window, priv->initial_timestamp);
+ if (GDK_IS_X11_WINDOW (priv->frame_window))
+ gdk_x11_window_set_user_time (priv->frame_window, priv->initial_timestamp);
}
#endif
@@ -5879,6 +5876,9 @@ gtk_window_realize (GtkWidget *widget)
if (priv->has_resize_grip)
resize_grip_create_window (window);
+
+ if (priv->title_box)
+ gtk_widget_set_parent_window (priv->title_box, priv->frame_window);
}
static void
@@ -5932,6 +5932,13 @@ gtk_window_unrealize (GtkWidget *widget)
}
GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
+
+ if (priv->frame_window)
+ {
+ gtk_widget_unregister_window (widget, priv->frame_window);
+ gdk_window_destroy (priv->frame_window);
+ priv->frame_window = NULL;
+ }
}
static GtkJunctionSides
@@ -6102,10 +6109,10 @@ sum_borders (GtkBorder *one,
}
static void
-get_decoration_size (GtkWidget *widget,
+get_decoration_size (GtkWindow *window,
GtkBorder *decorations)
{
- GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
+ GtkWindowPrivate *priv = window->priv;
GtkBorder border = { 0 };
GtkBorder margin;
GtkStyleContext *context;
@@ -6117,11 +6124,11 @@ get_decoration_size (GtkWidget *widget,
if (!priv->client_decorated)
return;
- if (gtk_window_get_maximized (GTK_WINDOW (widget)))
+ if (gtk_window_get_maximized (window))
return;
- state = gtk_widget_get_state_flags (widget);
- context = gtk_widget_get_style_context (widget);
+ state = gtk_widget_get_state_flags (GTK_WIDGET (window));
+ context = gtk_widget_get_style_context (GTK_WIDGET (window));
gtk_style_context_save (context);
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BACKGROUND);
@@ -6197,8 +6204,8 @@ update_border_windows (GtkWindow *window)
"decoration-resize-handle", &handle,
NULL);
- width = gtk_widget_get_allocated_width (widget) - (border.left + border.right);
- height = gtk_widget_get_allocated_height (widget) - (border.top + border.bottom);
+ width = gdk_window_get_width (priv->frame_window) - (border.left + border.right);
+ height = gdk_window_get_height (priv->frame_window) - (border.top + border.bottom);
if (resize_h && resize_v)
{
@@ -6374,7 +6381,6 @@ _gtk_window_set_allocation (GtkWindow *window,
{
GtkWidget *widget = (GtkWidget *)window;
GtkWindowPrivate *priv = window->priv;
- GtkAllocation child_allocation;
gint border_width;
GtkBorder window_border = { 0 };
gint title_height = 0;
@@ -6384,14 +6390,9 @@ _gtk_window_set_allocation (GtkWindow *window,
gtk_widget_set_allocation (widget, allocation);
- get_decoration_size (widget, &window_border);
+ get_decoration_size (window, &window_border);
border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
- child_allocation.x = 0;
- child_allocation.y = 0;
- child_allocation.width = allocation->width;
- child_allocation.height = allocation->height;
-
if (priv->title_box != NULL &&
priv->decorated &&
!priv->fullscreen)
@@ -6400,9 +6401,7 @@ _gtk_window_set_allocation (GtkWindow *window,
title_allocation.x = window_border.left;
title_allocation.y = window_border.top;
- title_allocation.width =
- MAX (1, (gint) allocation->width -
- window_border.left - window_border.right);
+ title_allocation.width = allocation->width;
gtk_widget_get_preferred_height_for_width (priv->title_box,
title_allocation.width,
@@ -6414,15 +6413,6 @@ _gtk_window_set_allocation (GtkWindow *window,
gtk_widget_size_allocate (priv->title_box, &title_allocation);
}
- if (priv->decorated &&
- !priv->fullscreen)
- {
- child_allocation.x += window_border.left;
- child_allocation.y += window_border.top + title_height;
- child_allocation.width -= window_border.left + window_border.right;
- child_allocation.height -= window_border.top + window_border.bottom +
- title_height;
- }
if (gtk_widget_get_realized (widget))
{
@@ -6440,15 +6430,18 @@ _gtk_window_set_allocation (GtkWindow *window,
update_grip_visibility (window);
set_grip_position (window);
update_border_windows (window);
+
+ gdk_window_move_resize (gtk_widget_get_window (widget),
+ window_border.left,
+ window_border.top + title_height,
+ allocation->width, allocation->height);
}
}
- child_allocation.x += border_width;
- child_allocation.y += border_width;
- child_allocation.width = MAX (1, child_allocation.width - border_width * 2);
- child_allocation.height = MAX (1, child_allocation.height - border_width * 2);
-
- *allocation_out = child_allocation;
+ allocation_out->x = border_width;
+ allocation_out->y = border_width;
+ allocation_out->width = MAX (1, allocation->width - border_width * 2);
+ allocation_out->height = MAX (1, allocation->height - border_width * 2);
}
static void
@@ -6470,10 +6463,8 @@ static gint
gtk_window_configure_event (GtkWidget *widget,
GdkEventConfigure *event)
{
- GtkAllocation allocation;
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = window->priv;
- gboolean expected_reply = priv->configure_request_count > 0;
if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
{
@@ -6498,9 +6489,10 @@ gtk_window_configure_event (GtkWidget *widget,
if (priv->configure_request_count > 0)
{
priv->configure_request_count -= 1;
- gdk_window_thaw_toplevel_updates_libgtk_only (gtk_widget_get_window (widget));
+ gdk_window_thaw_toplevel_updates_libgtk_only (priv->frame_window);
}
-
+
+#if 0
/* As an optimization, we avoid a resize when possible.
*
* The only times we can avoid a resize are:
@@ -6508,13 +6500,13 @@ gtk_window_configure_event (GtkWidget *widget,
* - we know we have made more requests and so will get more
* notifies and can wait to resize when we get them
*/
- gtk_widget_get_allocation (widget, &allocation);
if (!expected_reply &&
- (allocation.width == event->width &&
- allocation.height == event->height))
+ (gdk_window_get_width (priv->frame_window) == event->width &&
+ gdk_window_get_height (priv->frame_window) == event->height))
{
return TRUE;
}
+#endif
/*
* If we do need to resize, we do that by:
@@ -6524,13 +6516,14 @@ gtk_window_configure_event (GtkWidget *widget,
* gtk_window_move_resize() in an idle handler
*
*/
-
+
priv->configure_notify_received = TRUE;
- gdk_window_invalidate_rect (gtk_widget_get_window (widget), NULL, FALSE); // XXX - What was this for again?
+ if (priv->frame_window)
+ gdk_window_invalidate_rect (priv->frame_window, NULL, FALSE); // XXX - What was this for again?
_gtk_container_queue_resize (GTK_CONTAINER (widget));
-
+
return TRUE;
}
@@ -6602,8 +6595,7 @@ gtk_window_style_updated (GtkWidget *widget)
if (gtk_widget_get_realized (widget))
{
- gdk_window_set_background_rgba (gtk_widget_get_window (widget),
- &transparent);
+ gdk_window_set_background_rgba (priv->frame_window, &transparent);
gtk_widget_queue_resize (widget);
}
}
@@ -6747,6 +6739,7 @@ gtk_window_resize_grip_is_visible (GtkWindow *window)
{
GtkWidget *widget;
GtkWindowPrivate *priv;
+ GdkWindowState state;
GdkWindowEdge edge;
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
@@ -6763,15 +6756,13 @@ gtk_window_resize_grip_is_visible (GtkWindow *window)
if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
return FALSE;
- if (gtk_widget_get_realized (widget))
- {
- GdkWindowState state;
+ if (!priv->frame_window)
+ return FALSE;
- state = gdk_window_get_state (gtk_widget_get_window (widget));
+ state = gdk_window_get_state (priv->frame_window);
- if (state & GDK_WINDOW_STATE_MAXIMIZED || state & GDK_WINDOW_STATE_FULLSCREEN)
- return FALSE;
- }
+ if (state & GDK_WINDOW_STATE_MAXIMIZED || state & GDK_WINDOW_STATE_FULLSCREEN)
+ return FALSE;
if (!get_drag_edge (widget, &edge))
return FALSE;
@@ -6819,14 +6810,12 @@ gtk_window_get_resize_grip_area (GtkWindow *window,
GtkAllocation allocation;
gint grip_width;
gint grip_height;
- GtkBorder window_border = { 0 };
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
if (!priv->has_resize_grip)
return FALSE;
- get_decoration_size (widget, &window_border);
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_style_get (widget,
@@ -6842,12 +6831,10 @@ gtk_window_get_resize_grip_area (GtkWindow *window,
rect->width = grip_width;
rect->height = grip_height;
- rect->y = allocation.y + allocation.height -
- grip_height - window_border.bottom;
+ rect->y = allocation.y + allocation.height - grip_height;
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
- rect->x = allocation.x + allocation.width -
- grip_width - window_border.right;
+ rect->x = allocation.x + allocation.width - grip_width;
else
rect->x = allocation.x;
@@ -7022,14 +7009,11 @@ gtk_window_button_press_event (GtkWidget *widget,
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = window->priv;
GdkWindowEdge edge;
- GdkWindow *gdk_window;
-
- gdk_window = gtk_widget_get_window (widget);
if (event->window == priv->grip_window)
{
if (get_drag_edge (widget, &edge))
- gdk_window_begin_resize_drag_for_device (gdk_window,
+ gdk_window_begin_resize_drag_for_device (priv->frame_window,
edge,
gdk_event_get_device ((GdkEvent *) event),
event->button,
@@ -7071,7 +7055,7 @@ gtk_window_button_press_event (GtkWidget *widget,
break;
case GTK_WINDOW_REGION_TITLE:
case GTK_WINDOW_REGION_EDGE:
- gdk_window_begin_move_drag_for_device (gdk_window,
+ gdk_window_begin_move_drag_for_device (priv->frame_window,
gdk_event_get_device ((GdkEvent *) event),
event->button,
event->x_root,
@@ -7082,7 +7066,7 @@ gtk_window_button_press_event (GtkWidget *widget,
default:
if (!maximized)
{
- gdk_window_begin_resize_drag_for_device (gdk_window,
+ gdk_window_begin_resize_drag_for_device (priv->frame_window,
(GdkWindowEdge)region,
gdk_event_get_device ((GdkEvent *) event),
event->button,
@@ -7470,46 +7454,25 @@ gtk_window_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- GtkWindow *window;
+ GtkWindow *window = GTK_WINDOW (widget);
GtkWidget *child;
- GtkWindowPrivate *priv;
- guint border_width;
- gint title_min = 0, title_nat = 0;
- gint child_min = 0, child_nat = 0;
- GtkBorder window_border = { 0 };
- window = GTK_WINDOW (widget);
- priv = window->priv;
child = gtk_bin_get_child (GTK_BIN (window));
- border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
-
- if (priv->decorated &&
- !priv->fullscreen)
- {
- get_decoration_size (widget, &window_border);
-
- if (priv->title_box != NULL)
- gtk_widget_get_preferred_width (priv->title_box,
- &title_min, &title_nat);
-
- title_min += border_width * 2 +
- window_border.left + window_border.right;
- title_nat += border_width * 2 +
- window_border.left + window_border.right;
- }
+ *minimum_size = 0;
+ *natural_size = 0;
if (child && gtk_widget_get_visible (child))
{
+ gint child_min, child_nat;
+ guint border_width;
+
gtk_widget_get_preferred_width (child, &child_min, &child_nat);
- child_min += border_width * 2 +
- window_border.left + window_border.right;
- child_nat += border_width * 2 +
- window_border.left + window_border.right;
- }
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
- *minimum_size = MAX (title_min, child_min);
- *natural_size = MAX (title_nat, child_nat);
+ *minimum_size += child_min + border_width * 2;
+ *natural_size += child_nat + border_width * 2;
+ }
}
@@ -7519,49 +7482,27 @@ gtk_window_get_preferred_width_for_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- GtkWindow *window;
+ GtkWindow *window = GTK_WINDOW (widget);
GtkWidget *child;
- GtkWindowPrivate *priv;
- guint border_width;
- gint title_min = 0, title_nat = 0;
- gint child_min = 0, child_nat = 0;
- GtkBorder window_border = { 0 };
- window = GTK_WINDOW (widget);
- priv = window->priv;
child = gtk_bin_get_child (GTK_BIN (window));
- border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
-
- if (priv->decorated &&
- !priv->fullscreen)
- {
- get_decoration_size (widget, &window_border);
-
- if (priv->title_box != NULL)
- gtk_widget_get_preferred_width_for_height (priv->title_box,
- height,
- &title_min, &title_nat);
-
- title_min += border_width * 2 +
- window_border.left + window_border.right;
- title_nat += border_width * 2 +
- window_border.left + window_border.right;
- }
+ *minimum_size = 0;
+ *natural_size = 0;
if (child && gtk_widget_get_visible (child))
{
+ gint child_min, child_nat;
+ guint border_width;
+
gtk_widget_get_preferred_width_for_height (child,
height,
&child_min, &child_nat);
- child_min += border_width * 2 +
- window_border.left + window_border.right;
- child_nat += border_width * 2 +
- window_border.left + window_border.right;
- }
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
- *minimum_size = MAX (title_min, child_min);
- *natural_size = MAX (title_nat, child_nat);
+ *minimum_size += child_min + border_width * 2;
+ *natural_size += child_nat + border_width * 2;
+ }
}
static void
@@ -7569,44 +7510,21 @@ gtk_window_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- GtkWindow *window;
- GtkWindowPrivate *priv;
+ GtkWindow *window = GTK_WINDOW (widget);
GtkWidget *child;
- guint border_width;
- int title_min = 0;
- int title_height = 0;
- GtkBorder window_border = { 0 };
- window = GTK_WINDOW (widget);
- priv = window->priv;
child = gtk_bin_get_child (GTK_BIN (window));
*minimum_size = 0;
*natural_size = 0;
- border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
-
- if (priv->decorated &&
- !priv->fullscreen)
- {
- get_decoration_size (widget, &window_border);
-
- if (priv->title_box != NULL)
- gtk_widget_get_preferred_height (priv->title_box,
- &title_min,
- &title_height);
-
- *minimum_size = title_min +
- window_border.top + window_border.bottom;
-
- *natural_size = title_height +
- window_border.top + window_border.bottom;
- }
-
if (child && gtk_widget_get_visible (child))
{
gint child_min, child_nat;
+ guint border_width;
+
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
*minimum_size += child_min + 2 * border_width;
*natural_size += child_nat + 2 * border_width;
@@ -7620,46 +7538,22 @@ gtk_window_get_preferred_height_for_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- GtkWindow *window;
- GtkWindowPrivate *priv;
+ GtkWindow *window = GTK_WINDOW (widget);
GtkWidget *child;
- guint border_width;
- int title_min = 0;
- int title_height = 0;
- GtkBorder window_border = { 0 };
- window = GTK_WINDOW (widget);
- priv = window->priv;
child = gtk_bin_get_child (GTK_BIN (window));
*minimum_size = 0;
*natural_size = 0;
- border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
-
- if (priv->decorated &&
- !priv->fullscreen)
- {
- get_decoration_size (widget, &window_border);
-
- if (priv->title_box != NULL)
- gtk_widget_get_preferred_height_for_width (priv->title_box,
- width,
- &title_min,
- &title_height);
-
- *minimum_size = title_min +
- window_border.top + window_border.bottom;
-
- *natural_size = title_height +
- window_border.top + window_border.bottom;
- }
-
if (child && gtk_widget_get_visible (child))
{
gint child_min, child_nat;
+ guint border_width;
+
gtk_widget_get_preferred_height_for_width (child, width,
&child_min, &child_nat);
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
*minimum_size += child_min + 2 * border_width;
*natural_size += child_nat + 2 * border_width;
@@ -7860,6 +7754,7 @@ geometry_size_to_pixels (GdkGeometry *geometry,
}
/* This function doesn't constrain to geometry hints */
+/* CSD: this function determines the requested size for the _content_ */
static void
gtk_window_compute_configure_request_size (GtkWindow *window,
GdkGeometry *geometry,
@@ -8245,6 +8140,72 @@ gtk_window_constrain_position (GtkWindow *window,
}
static void
+add_frame_size_to_geometry (GtkWindow *window,
+ GdkGeometry *geometry)
+{
+ GtkWindowPrivate *priv = window->priv;
+ GtkBorder border;
+ gint title_height = 0;
+
+ if (!priv->client_decorated)
+ return;
+
+ get_decoration_size (window, &border);
+ if (priv->title_box)
+ title_height = gtk_widget_get_allocated_height (priv->title_box);
+
+ geometry->min_width += border.left + border.right;
+ geometry->max_width += border.left + border.right;
+ geometry->min_height += border.top + border.bottom + title_height;
+ geometry->max_height += border.top + border.bottom + title_height;
+}
+
+static void
+add_frame_size_to_allocation (GtkWindow *window,
+ GdkRectangle *rect)
+{
+ GtkWindowPrivate *priv = window->priv;
+ GtkBorder border;
+ GtkWindowGeometryInfo *info;
+
+ if (!priv->client_decorated)
+ return;
+
+ info = gtk_window_get_geometry_info (window, TRUE);
+ get_decoration_size (window, &border);
+
+ /* FIXME gravity */
+ rect->x -= border.left;
+ rect->y -= border.top;
+ rect->width += border.left + border.right;
+ rect->height += border.top + border.bottom + info->last.title_height;
+}
+
+static void
+subtract_frame_size_from_allocation (GtkWindow *window,
+ GdkRectangle *rect)
+{
+ GtkWindowPrivate *priv = window->priv;
+ GtkBorder border;
+ GtkWindowGeometryInfo *info;
+
+ if (!priv->client_decorated)
+ return;
+
+ info = gtk_window_get_geometry_info (window, TRUE);
+ get_decoration_size (window, &border);
+
+ /* FIXME gravity */
+ rect->x += border.left;
+ rect->y += border.top;
+ rect->width -= border.left + border.right;
+ rect->height -= border.top + border.bottom + info->last.title_height;
+
+ rect->width = MAX (1, rect->width);
+ rect->height = MAX (1, rect->height);
+}
+
+static void
gtk_window_move_resize (GtkWindow *window)
{
/* Overview:
@@ -8285,17 +8246,21 @@ gtk_window_move_resize (GtkWindow *window)
GtkContainer *container;
GtkWindowGeometryInfo *info;
GdkGeometry new_geometry;
- GdkWindow *gdk_window;
guint new_flags;
GdkRectangle new_request;
gboolean configure_request_size_changed;
gboolean configure_request_pos_changed;
gboolean hints_changed; /* do we need to send these again */
GtkWindowLastGeometryInfo saved_last_info;
-
+ GdkWindow *gdk_window;
+
widget = GTK_WIDGET (window);
- gdk_window = gtk_widget_get_window (widget);
+ if (priv->frame_window)
+ gdk_window = priv->frame_window;
+ else
+ gdk_window = gtk_widget_get_window (widget);
+
container = GTK_CONTAINER (widget);
info = gtk_window_get_geometry_info (window, TRUE);
@@ -8303,8 +8268,8 @@ gtk_window_move_resize (GtkWindow *window)
configure_request_pos_changed = FALSE;
gtk_window_compute_configure_request (window, &new_request,
- &new_geometry, &new_flags);
-
+ &new_geometry, &new_flags);
+
/* This check implies the invariant that we never set info->last
* without setting the hints and sending off a configure request.
*
@@ -8397,13 +8362,11 @@ gtk_window_move_resize (GtkWindow *window)
int notify_x, notify_y;
/* this is the position from the last configure notify */
- gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
-
+ gdk_window_get_position (gdk_window, ¬ify_x, ¬ify_y);
g_message ("--- %s ---\n"
"last : %d,%d\t%d x %d\n"
"this : %d,%d\t%d x %d\n"
"alloc : %d,%d\t%d x %d\n"
- "req : \t%d x %d\n"
"resize: \t%d x %d\n"
"size_changed: %d pos_changed: %d hints_changed: %d\n"
"configure_notify_received: %d\n"
@@ -8419,10 +8382,8 @@ gtk_window_move_resize (GtkWindow *window)
new_request.width,
new_request.height,
notify_x, notify_y,
- widget->allocation.width,
- widget->allocation.height,
- widget->requisition.width,
- widget->requisition.height,
+ gtk_widget_get_allocated_width (widget),
+ gtk_widget_get_allocated_height (widget),
info->resize_width,
info->resize_height,
configure_request_pos_changed,
@@ -8438,7 +8399,15 @@ gtk_window_move_resize (GtkWindow *window)
info->last.geometry = new_geometry;
info->last.flags = new_flags;
info->last.configure_request = new_request;
-
+
+ if (priv->title_box != NULL)
+ {
+ gtk_widget_get_preferred_height_for_width (priv->title_box,
+ info->last.configure_request.width,
+ NULL,
+ &info->last.title_height);
+ }
+
/* need to set PPosition so the WM will look at our position,
* but we don't want to count PPosition coming and going as a hints
* change for future iterations. So we saved info->last prior to
@@ -8467,15 +8436,20 @@ gtk_window_move_resize (GtkWindow *window)
/* Set hints if necessary
*/
if (hints_changed)
- gdk_window_set_geometry_hints (gdk_window,
- &new_geometry,
- new_flags);
+ {
+ add_frame_size_to_geometry (window, &new_geometry);
+ gdk_window_set_geometry_hints (gdk_window, &new_geometry, new_flags);
+ }
allocation.x = 0;
allocation.y = 0;
allocation.width = gdk_window_get_width (gdk_window);
allocation.height = gdk_window_get_height (gdk_window);
+ subtract_frame_size_from_allocation (window, &allocation);
+ allocation.x = 0;
+ allocation.y = 0;
+
/* handle resizing/moving and widget tree allocation
*/
if (priv->configure_notify_received)
@@ -8493,7 +8467,6 @@ gtk_window_move_resize (GtkWindow *window)
*/
priv->configure_notify_received = FALSE;
- /* gtk_window_configure_event() filled in widget->allocation */
gtk_widget_size_allocate (widget, &allocation);
set_grip_position (window);
@@ -8560,6 +8533,7 @@ gtk_window_move_resize (GtkWindow *window)
*/
/* Now send the configure request */
+ add_frame_size_to_allocation (window, &new_request);
if (configure_request_pos_changed)
{
gdk_window_move_resize (gdk_window,
@@ -8592,8 +8566,11 @@ gtk_window_move_resize (GtkWindow *window)
else
{
/* Increment the number of have-not-yet-received-notify requests */
- priv->configure_request_count += 1;
- gdk_window_freeze_toplevel_updates_libgtk_only (gdk_window);
+ if (priv->frame_window)
+ {
+ priv->configure_request_count += 1;
+ gdk_window_freeze_toplevel_updates_libgtk_only (priv->frame_window);
+ }
/* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
* configure event in response to our resizing request.
@@ -8621,6 +8598,7 @@ gtk_window_move_resize (GtkWindow *window)
{
/* Handle any position changes.
*/
+ add_frame_size_to_allocation (window, &new_request);
if (configure_request_pos_changed)
{
gdk_window_move (gdk_window,
@@ -8869,20 +8847,19 @@ static gboolean
gtk_window_draw (GtkWidget *widget,
cairo_t *cr)
{
- GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
+ GtkWindow *window = GTK_WINDOW (widget);
+ GtkWindowPrivate *priv = window->priv;
GtkStyleContext *context;
gboolean ret = FALSE;
- GtkAllocation allocation;
GtkBorder window_border;
- gint title_height;
+ gint x, y, width, height;
context = gtk_widget_get_style_context (widget);
- get_decoration_size (widget, &window_border);
- gtk_widget_get_allocation (widget, &allocation);
+ get_decoration_size (window, &window_border);
- if (!gtk_widget_get_app_paintable (widget) &&
- gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
+ if (priv->frame_window &&
+ gtk_cairo_should_draw_window (cr, priv->frame_window))
{
if (priv->client_decorated &&
priv->decorated &&
@@ -8891,48 +8868,49 @@ gtk_window_draw (GtkWidget *widget,
{
gtk_style_context_save (context);
+ /* The ::draw signal gets emitted for the frame window too,
+ * causing draw signal handlers on the window to draw there.
+ * This is hard to avoid, so we just clear everything to fully
+ * transparent before drawing our frames, to prevent window
+ * content from peeking through in the translucent frame parts.
+ */
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 0., 0., 0., 0.);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BACKGROUND);
gtk_style_context_add_class (context, "window-frame");
gtk_render_background (context, cr,
window_border.left, window_border.top,
- allocation.width -
+ gdk_window_get_width (priv->frame_window) -
(window_border.left + window_border.right),
- allocation.height -
+ gdk_window_get_height (priv->frame_window) -
(window_border.top + window_border.bottom));
gtk_render_frame (context, cr,
window_border.left, window_border.top,
- allocation.width -
+ gdk_window_get_width (priv->frame_window) -
(window_border.left + window_border.right),
- allocation.height -
+ gdk_window_get_height (priv->frame_window) -
(window_border.top + window_border.bottom));
gtk_style_context_restore (context);
}
- if (priv->title_box && gtk_widget_get_visible (priv->title_box))
- title_height = gtk_widget_get_allocated_height (priv->title_box);
- else
- title_height = 0;
-
- gtk_render_background (context, cr,
- window_border.left,
- window_border.top + title_height,
- allocation.width -
- (window_border.left + window_border.right),
- allocation.height -
- (window_border.top + window_border.bottom +
- title_height));
- gtk_render_frame (context, cr,
- window_border.left,
- window_border.top + title_height,
- allocation.width -
- (window_border.left + window_border.right),
- allocation.height -
- (window_border.top + window_border.bottom +
- title_height));
+ if (!gtk_widget_get_app_paintable (widget))
+ {
+ gdk_window_get_position (gtk_widget_get_window (widget), &x, &y);
+ width = gdk_window_get_width (gtk_widget_get_window (widget));
+ height = gdk_window_get_height (gtk_widget_get_window (widget));
+
+ gtk_render_background (context, cr, x, y, width, height);
+ gtk_render_frame (context, cr, x, y, width, height);
+ }
}
+
if (GTK_WIDGET_CLASS (gtk_window_parent_class)->draw)
ret = GTK_WIDGET_CLASS (gtk_window_parent_class)->draw (widget, cr);
@@ -9005,7 +8983,6 @@ gtk_window_present_with_time (GtkWindow *window,
{
GtkWindowPrivate *priv;
GtkWidget *widget;
- GdkWindow *gdk_window;
g_return_if_fail (GTK_IS_WINDOW (window));
@@ -9014,17 +8991,15 @@ gtk_window_present_with_time (GtkWindow *window,
if (gtk_widget_get_visible (widget))
{
- gdk_window = gtk_widget_get_window (widget);
-
- g_assert (gdk_window != NULL);
+ g_assert (priv->frame_window != NULL);
- gdk_window_show (gdk_window);
+ gdk_window_show (priv->frame_window);
/* Translate a timestamp of GDK_CURRENT_TIME appropriately */
if (timestamp == GDK_CURRENT_TIME)
{
#ifdef GDK_WINDOWING_X11
- if (GDK_IS_X11_WINDOW(gdk_window))
+ if (GDK_IS_X11_WINDOW (priv->frame_window))
{
GdkDisplay *display;
@@ -9036,7 +9011,7 @@ gtk_window_present_with_time (GtkWindow *window,
timestamp = gtk_get_current_event_time ();
}
- gdk_window_focus (gdk_window, timestamp);
+ gdk_window_focus (priv->frame_window, timestamp);
}
else
{
@@ -9068,21 +9043,14 @@ gtk_window_present_with_time (GtkWindow *window,
void
gtk_window_iconify (GtkWindow *window)
{
- GtkWindowPrivate *priv;
- GtkWidget *widget;
- GdkWindow *toplevel;
-
+ GtkWindowPrivate *priv = window->priv;
+
g_return_if_fail (GTK_IS_WINDOW (window));
- priv = window->priv;
- widget = GTK_WIDGET (window);
-
priv->iconify_initially = TRUE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_iconify (toplevel);
+ if (priv->frame_window != NULL)
+ gdk_window_iconify (priv->frame_window);
}
/**
@@ -9101,21 +9069,14 @@ gtk_window_iconify (GtkWindow *window)
void
gtk_window_deiconify (GtkWindow *window)
{
- GtkWindowPrivate *priv;
- GtkWidget *widget;
- GdkWindow *toplevel;
-
- g_return_if_fail (GTK_IS_WINDOW (window));
+ GtkWindowPrivate *priv = window->priv;
- priv = window->priv;
- widget = GTK_WIDGET (window);
+ g_return_if_fail (GTK_IS_WINDOW (window));
priv->iconify_initially = FALSE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_deiconify (toplevel);
+ if (priv->frame_window != NULL)
+ gdk_window_deiconify (priv->frame_window);
}
/**
@@ -9139,21 +9100,14 @@ gtk_window_deiconify (GtkWindow *window)
void
gtk_window_stick (GtkWindow *window)
{
- GtkWindowPrivate *priv;
- GtkWidget *widget;
- GdkWindow *toplevel;
-
- g_return_if_fail (GTK_IS_WINDOW (window));
+ GtkWindowPrivate *priv = window->priv;
- priv = window->priv;
- widget = GTK_WIDGET (window);
+ g_return_if_fail (GTK_IS_WINDOW (window));
priv->stick_initially = TRUE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_stick (toplevel);
+ if (priv->frame_window != NULL)
+ gdk_window_stick (priv->frame_window);
}
/**
@@ -9174,21 +9128,14 @@ gtk_window_stick (GtkWindow *window)
void
gtk_window_unstick (GtkWindow *window)
{
- GtkWindowPrivate *priv;
- GtkWidget *widget;
- GdkWindow *toplevel;
-
- g_return_if_fail (GTK_IS_WINDOW (window));
+ GtkWindowPrivate *priv = window->priv;
- priv = window->priv;
- widget = GTK_WIDGET (window);
+ g_return_if_fail (GTK_IS_WINDOW (window));
priv->stick_initially = FALSE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_unstick (toplevel);
+ if (priv->frame_window != NULL)
+ gdk_window_unstick (priv->frame_window);
}
/**
@@ -9214,21 +9161,14 @@ gtk_window_unstick (GtkWindow *window)
void
gtk_window_maximize (GtkWindow *window)
{
- GtkWindowPrivate *priv;
- GtkWidget *widget;
- GdkWindow *toplevel;
-
- g_return_if_fail (GTK_IS_WINDOW (window));
+ GtkWindowPrivate *priv = window->priv;
- priv = window->priv;
- widget = GTK_WIDGET (window);
+ g_return_if_fail (GTK_IS_WINDOW (window));
priv->maximize_initially = TRUE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_maximize (toplevel);
+ if (priv->frame_window != NULL)
+ gdk_window_maximize (priv->frame_window);
}
/**
@@ -9249,21 +9189,14 @@ gtk_window_maximize (GtkWindow *window)
void
gtk_window_unmaximize (GtkWindow *window)
{
- GtkWindowPrivate *priv;
- GtkWidget *widget;
- GdkWindow *toplevel;
-
- g_return_if_fail (GTK_IS_WINDOW (window));
+ GtkWindowPrivate *priv = window->priv;
- priv = window->priv;
- widget = GTK_WIDGET (window);
+ g_return_if_fail (GTK_IS_WINDOW (window));
priv->maximize_initially = FALSE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_unmaximize (toplevel);
+ if (priv->frame_window != NULL)
+ gdk_window_unmaximize (priv->frame_window);
}
/**
@@ -9286,21 +9219,14 @@ gtk_window_unmaximize (GtkWindow *window)
void
gtk_window_fullscreen (GtkWindow *window)
{
- GtkWindowPrivate *priv;
- GtkWidget *widget;
- GdkWindow *toplevel;
+ GtkWindowPrivate *priv = window->priv;
g_return_if_fail (GTK_IS_WINDOW (window));
- priv = window->priv;
- widget = GTK_WIDGET (window);
-
priv->fullscreen_initially = TRUE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_fullscreen (toplevel);
+ if (priv->frame_window != NULL)
+ gdk_window_fullscreen (priv->frame_window);
}
/**
@@ -9323,21 +9249,14 @@ gtk_window_fullscreen (GtkWindow *window)
void
gtk_window_unfullscreen (GtkWindow *window)
{
- GtkWidget *widget;
- GdkWindow *toplevel;
- GtkWindowPrivate *priv;
+ GtkWindowPrivate *priv = window->priv;
g_return_if_fail (GTK_IS_WINDOW (window));
- priv = window->priv;
- widget = GTK_WIDGET (window);
-
priv->fullscreen_initially = FALSE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_unfullscreen (toplevel);
+ if (priv->frame_window != NULL)
+ gdk_window_unfullscreen (priv->frame_window);
}
/**
@@ -9372,23 +9291,16 @@ void
gtk_window_set_keep_above (GtkWindow *window,
gboolean setting)
{
- GtkWidget *widget;
- GtkWindowPrivate *priv;
- GdkWindow *toplevel;
+ GtkWindowPrivate *priv = window->priv;
g_return_if_fail (GTK_IS_WINDOW (window));
- priv = window->priv;
- widget = GTK_WIDGET (window);
-
priv->above_initially = setting != FALSE;
if (setting)
priv->below_initially = FALSE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_set_keep_above (toplevel, setting);
+ if (priv->frame_window != NULL)
+ gdk_window_set_keep_above (priv->frame_window, setting);
}
/**
@@ -9423,23 +9335,16 @@ void
gtk_window_set_keep_below (GtkWindow *window,
gboolean setting)
{
- GtkWidget *widget;
- GtkWindowPrivate *priv;
- GdkWindow *toplevel;
+ GtkWindowPrivate *priv = window->priv;
g_return_if_fail (GTK_IS_WINDOW (window));
- priv = window->priv;
- widget = GTK_WIDGET (window);
-
priv->below_initially = setting != FALSE;
if (setting)
priv->above_initially = FALSE;
- toplevel = gtk_widget_get_window (widget);
-
- if (toplevel != NULL)
- gdk_window_set_keep_below (toplevel, setting);
+ if (priv->frame_window != NULL)
+ gdk_window_set_keep_below (priv->frame_window, setting);
}
/**
@@ -9568,18 +9473,17 @@ gtk_window_begin_resize_drag (GtkWindow *window,
guint32 timestamp)
{
GtkWidget *widget;
- GdkWindow *toplevel;
+ GtkWindowPrivate *priv = window->priv;
g_return_if_fail (GTK_IS_WINDOW (window));
widget = GTK_WIDGET (window);
g_return_if_fail (gtk_widget_get_visible (widget));
- toplevel = gtk_widget_get_window (widget);
-
- gdk_window_begin_resize_drag (toplevel,
- edge, button,
- root_x, root_y,
- timestamp);
+ if (priv->frame_window)
+ gdk_window_begin_resize_drag (priv->frame_window,
+ edge, button,
+ root_x, root_y,
+ timestamp);
}
/**
@@ -9605,19 +9509,18 @@ gtk_window_begin_move_drag (GtkWindow *window,
gint root_y,
guint32 timestamp)
{
+ GtkWindowPrivate *priv = window->priv;
GtkWidget *widget;
- GdkWindow *toplevel;
g_return_if_fail (GTK_IS_WINDOW (window));
widget = GTK_WIDGET (window);
g_return_if_fail (gtk_widget_get_visible (widget));
- toplevel = gtk_widget_get_window (widget);
-
- gdk_window_begin_move_drag (toplevel,
- button,
- root_x, root_y,
- timestamp);
+ if (priv->frame_window)
+ gdk_window_begin_move_drag (priv->frame_window,
+ button,
+ root_x, root_y,
+ timestamp);
}
/**
@@ -9692,17 +9595,15 @@ static void
gtk_window_set_theme_variant (GtkWindow *window)
{
#ifdef GDK_WINDOWING_X11
- GdkWindow *gdk_window;
+ GtkWindowPrivate *priv = window->priv;
gboolean dark_theme_requested;
g_object_get (gtk_settings_get_for_screen (window->priv->screen),
"gtk-application-prefer-dark-theme", &dark_theme_requested,
NULL);
- gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
-
- if (GDK_IS_X11_WINDOW (gdk_window))
- gdk_x11_window_set_theme_variant (gdk_window,
+ if (GDK_IS_X11_WINDOW (priv->frame_window))
+ gdk_x11_window_set_theme_variant (priv->frame_window,
dark_theme_requested ? "dark" : NULL);
#endif
}
@@ -11137,12 +11038,11 @@ gtk_window_set_has_user_ref_count (GtkWindow *window,
static void
ensure_state_flag_backdrop (GtkWidget *widget)
{
- GdkWindow *window;
+ GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
gboolean window_focused = TRUE;
- window = gtk_widget_get_window (widget);
-
- window_focused = gdk_window_get_state (window) & GDK_WINDOW_STATE_FOCUSED;
+ if (priv->frame_window)
+ window_focused = gdk_window_get_state (priv->frame_window) & GDK_WINDOW_STATE_FOCUSED;
if (!window_focused)
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_BACKDROP, FALSE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]