[mutter/wip/carlosg/frames-client: 996/1005] x11: Integrate frames client into Mutter
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/carlosg/frames-client: 996/1005] x11: Integrate frames client into Mutter
- Date: Mon, 12 Sep 2022 12:29:21 +0000 (UTC)
commit 7a20ea97b509e5f64d68b020cbf54d4d7949a8e8
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu Sep 8 10:35:47 2022 +0200
x11: Integrate frames client into Mutter
src/core/display.c | 6 +-
src/core/events.c | 23 +--
src/core/frame.c | 332 +++++++++++++++++++++++++++-----------
src/core/frame.h | 15 +-
src/core/window-private.h | 6 +-
src/core/window.c | 30 +---
src/x11/atomnames.h | 3 +
src/x11/events.c | 46 ++++--
src/x11/meta-x11-display.c | 9 +-
src/x11/meta-x11-window-control.c | 3 -
src/x11/window-props.c | 3 -
src/x11/window-x11-private.h | 2 +
src/x11/window-x11.c | 37 ++++-
13 files changed, 332 insertions(+), 183 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index fb92244164..9d9f936e28 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -974,6 +974,8 @@ meta_display_new (MetaContext *context,
return NULL;
}
+ meta_frame_initialize (display);
+
if (display->x11_display)
{
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
@@ -2105,10 +2107,6 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
meta_window_frame_size_changed (window);
- if (window->frame)
- {
- meta_frame_queue_draw (window->frame);
- }
tmp = tmp->next;
}
diff --git a/src/core/events.c b/src/core/events.c
index eca21f52e5..8298620741 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -463,27 +463,8 @@ meta_display_handle_event (MetaDisplay *display,
* trigger ::captured-event handlers along the way.
*/
bypass_clutter = !IS_GESTURE_EVENT (event);
-
- /* When double clicking to un-maximize an X11 window under Wayland,
- * there is a race between X11 and Wayland protocols and the X11
- * XConfigureWindow may be processed by Xwayland before the button
- * press event is forwarded via the Wayland protocol.
- * As a result, the second click may reach another X11 window placed
- * immediately underneath in the X11 stack.
- * The following is to make sure we do not forward the button press
- * event to Wayland if it was handled by the frame UI.
- * See: https://gitlab.gnome.org/GNOME/mutter/issues/88
- */
- if (meta_window_handle_ui_frame_event (window, event))
- {
- bypass_wayland = (event->type == CLUTTER_BUTTON_PRESS ||
- event->type == CLUTTER_TOUCH_BEGIN);
- }
- else
- {
- bypass_wayland = meta_window_has_modals (window);
- meta_window_handle_ungrabbed_event (window, event);
- }
+ bypass_wayland = meta_window_has_modals (window);
+ meta_window_handle_ungrabbed_event (window, event);
/* This might start a grab op. If it does, then filter out the
* event, and if it doesn't, replay the event to release our
diff --git a/src/core/frame.c b/src/core/frame.c
index 9c8cbb9464..f7981af75e 100644
--- a/src/core/frame.c
+++ b/src/core/frame.c
@@ -31,24 +31,46 @@
#include "meta/meta-x11-errors.h"
#include "x11/meta-x11-display-private.h"
+#include <X11/Xatom.h>
+
#define EVENT_MASK (SubstructureRedirectMask | \
StructureNotifyMask | SubstructureNotifyMask | \
- ExposureMask | FocusChangeMask)
+ PropertyChangeMask | FocusChangeMask)
+
+static void on_frames_died (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data);
void
meta_window_ensure_frame (MetaWindow *window)
{
- MetaFrame *frame;
+ MetaX11Display *x11_display = window->display->x11_display;
+ unsigned long data[1] = { 1 };
+
+ meta_x11_error_trap_push (x11_display);
+
+ XChangeProperty (x11_display->xdisplay,
+ window->xwindow,
+ x11_display->atom__MUTTER_NEEDS_FRAME,
+ XA_CARDINAL,
+ 32, PropModeReplace, (guchar*) data, 1);
+
+ meta_x11_error_trap_pop (x11_display);
+}
+
+void
+meta_window_set_frame_xwindow (MetaWindow *window,
+ Window xframe)
+{
+ MetaX11Display *x11_display = window->display->x11_display;
XSetWindowAttributes attrs;
- gulong create_serial;
- MetaX11Display *x11_display;
+ gulong create_serial = 0;
+ MetaFrame *frame;
if (window->frame)
return;
- x11_display = window->display->x11_display;
-
- frame = g_new (MetaFrame, 1);
+ frame = g_new0 (MetaFrame, 1);
frame->window = window;
frame->xwindow = None;
@@ -58,24 +80,22 @@ meta_window_ensure_frame (MetaWindow *window)
frame->child_y = 0;
frame->bottom_height = 0;
frame->right_width = 0;
- frame->current_cursor = 0;
frame->borders_cached = FALSE;
+ window->frame = frame;
+
meta_verbose ("Frame geometry %d,%d %dx%d",
frame->rect.x, frame->rect.y,
frame->rect.width, frame->rect.height);
- frame->ui_frame = meta_ui_create_frame (x11_display->ui,
- x11_display->xdisplay,
- frame->window,
- window->xvisual,
- frame->rect.x,
- frame->rect.y,
- frame->rect.width,
- frame->rect.height,
- &create_serial);
- frame->xwindow = frame->ui_frame->xwindow;
+ meta_verbose ("Setting frame 0x%lx for window %s, "
+ "frame geometry %d,%d %dx%d",
+ xframe, window->desc,
+ frame->rect.x, frame->rect.y,
+ frame->rect.width, frame->rect.height);
+
+ frame->xwindow = xframe;
meta_stack_tracker_record_add (window->display->stack_tracker,
frame->xwindow,
@@ -120,40 +140,7 @@ meta_window_ensure_frame (MetaWindow *window)
/* stick frame to the window */
window->frame = frame;
- /* Now that frame->xwindow is registered with window, we can set its
- * style and background.
- */
- meta_frame_update_style (frame);
- meta_frame_update_title (frame);
-
- meta_ui_map_frame (x11_display->ui, frame->xwindow);
-
- {
- MetaBackend *backend = meta_get_backend ();
- if (META_IS_BACKEND_X11 (backend))
- {
- Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
-
- /* Since the backend selects for events on another connection,
- * make sure to sync the GTK+ connection to ensure that the
- * frame window has been created on the server at this point. */
- XSync (x11_display->xdisplay, False);
-
- unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
- XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
-
- XISelectEvents (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
- frame->xwindow, &mask, 1);
-
- XISetMask (mask.mask, XI_ButtonPress);
- XISetMask (mask.mask, XI_ButtonRelease);
- XISetMask (mask.mask, XI_Motion);
- XISetMask (mask.mask, XI_Enter);
- XISetMask (mask.mask, XI_Leave);
-
- XISelectEvents (xdisplay, frame->xwindow, &mask, 1);
- }
- }
+ XMapWindow (x11_display->xdisplay, frame->xwindow);
/* Move keybindings to frame instead of window */
meta_window_grab_keys (window);
@@ -212,8 +199,6 @@ meta_window_destroy_frame (MetaWindow *window)
meta_x11_error_trap_pop (x11_display);
- meta_ui_frame_unmanage (frame->ui_frame);
-
/* Ensure focus is restored after the unmap/map events triggered
* by XReparentWindow().
*/
@@ -318,6 +303,80 @@ meta_frame_borders_clear (MetaFrameBorders *self)
self->visible.right = self->invisible.right = self->total.right = 0;
}
+static void
+meta_frame_query_borders (MetaFrame *frame,
+ MetaFrameBorders *borders)
+{
+ MetaWindow *window = frame->window;
+ MetaX11Display *x11_display = window->display->x11_display;
+ int format, res;
+ Atom type;
+ unsigned long nitems, bytes_after;
+ unsigned char *data;
+
+ if (!frame->xwindow)
+ return;
+
+ meta_x11_error_trap_push (x11_display);
+
+ res = XGetWindowProperty (x11_display->xdisplay,
+ frame->xwindow,
+ x11_display->atom__GTK_FRAME_EXTENTS,
+ 0, 4,
+ False, XA_CARDINAL,
+ &type, &format,
+ &nitems, &bytes_after,
+ (unsigned char **) &data);
+
+ if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
+ return;
+
+ if (res == Success && nitems == 4)
+ {
+ borders->invisible = (GtkBorder) {
+ ((long *) data)[0],
+ ((long *) data)[1],
+ ((long *) data)[2],
+ ((long *) data)[3],
+ };
+ }
+
+ g_clear_pointer (&data, XFree);
+
+ meta_x11_error_trap_push (x11_display);
+
+ res = XGetWindowProperty (x11_display->xdisplay,
+ frame->xwindow,
+ x11_display->atom__MUTTER_FRAME_EXTENTS,
+ 0, 4,
+ False, XA_CARDINAL,
+ &type, &format,
+ &nitems, &bytes_after,
+ (unsigned char **) &data);
+
+ if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
+ return;
+
+ if (res == Success && nitems == 4)
+ {
+ borders->visible = (GtkBorder) {
+ ((long *) data)[0],
+ ((long *) data)[1],
+ ((long *) data)[2],
+ ((long *) data)[3],
+ };
+ }
+
+ g_clear_pointer (&data, XFree);
+
+ borders->total = (GtkBorder) {
+ borders->invisible.left + frame->cached_borders.visible.left,
+ borders->invisible.right + frame->cached_borders.visible.right,
+ borders->invisible.top + frame->cached_borders.visible.top,
+ borders->invisible.bottom + frame->cached_borders.visible.bottom,
+ };
+}
+
void
meta_frame_calc_borders (MetaFrame *frame,
MetaFrameBorders *borders)
@@ -330,7 +389,7 @@ meta_frame_calc_borders (MetaFrame *frame,
{
if (!frame->borders_cached)
{
- meta_ui_frame_get_borders (frame->ui_frame, &frame->cached_borders);
+ meta_frame_query_borders (frame, &frame->cached_borders);
frame->borders_cached = TRUE;
}
@@ -348,6 +407,9 @@ gboolean
meta_frame_sync_to_window (MetaFrame *frame,
gboolean need_resize)
{
+ MetaWindow *window = frame->window;
+ MetaX11Display *x11_display = window->display->x11_display;
+
meta_topic (META_DEBUG_GEOMETRY,
"Syncing frame geometry %d,%d %dx%d (SE: %d,%d)",
frame->rect.x, frame->rect.y,
@@ -355,11 +417,16 @@ meta_frame_sync_to_window (MetaFrame *frame,
frame->rect.x + frame->rect.width,
frame->rect.y + frame->rect.height);
- meta_ui_frame_move_resize (frame->ui_frame,
- frame->rect.x,
- frame->rect.y,
- frame->rect.width,
- frame->rect.height);
+ meta_x11_error_trap_push (x11_display);
+
+ XMoveResizeWindow (x11_display->xdisplay,
+ frame->xwindow,
+ frame->rect.x,
+ frame->rect.y,
+ frame->rect.width,
+ frame->rect.height);
+
+ meta_x11_error_trap_pop (x11_display);
return need_resize;
}
@@ -367,7 +434,21 @@ meta_frame_sync_to_window (MetaFrame *frame,
cairo_region_t *
meta_frame_get_frame_bounds (MetaFrame *frame)
{
- return meta_ui_frame_get_bounds (frame->ui_frame);
+ MetaFrameBorders borders;
+ cairo_region_t *bounds;
+
+ meta_frame_calc_borders (frame, &borders);
+ /* FIXME: currently just the client area, should shape closer to
+ * frame border, incl. rounded corners.
+ */
+ bounds = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
+ borders.total.left,
+ borders.total.top,
+ frame->rect.width - borders.total.left - borders.total.right,
+ frame->rect.height - borders.total.top - borders.total.bottom,
+ });
+
+ return bounds;
}
void
@@ -375,53 +456,124 @@ meta_frame_get_mask (MetaFrame *frame,
cairo_rectangle_int_t *frame_rect,
cairo_t *cr)
{
- meta_ui_frame_get_mask (frame->ui_frame, frame_rect, cr);
+ MetaFrameBorders borders;
+
+ meta_frame_calc_borders (frame, &borders);
+
+ cairo_rectangle (cr,
+ borders.invisible.left,
+ borders.invisible.top,
+ frame_rect->width,
+ frame_rect->height);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill (cr);
}
-void
-meta_frame_queue_draw (MetaFrame *frame)
+Window
+meta_frame_get_xwindow (MetaFrame *frame)
{
- meta_ui_frame_queue_draw (frame->ui_frame);
+ return frame->xwindow;
}
-void
-meta_frame_set_screen_cursor (MetaFrame *frame,
- MetaCursor cursor)
+gboolean
+meta_frame_handle_xevent (MetaFrame *frame,
+ XEvent *xevent)
{
- MetaX11Display *x11_display;
- Cursor xcursor;
- if (cursor == frame->current_cursor)
- return;
+ MetaWindow *window = frame->window;
+ MetaX11Display *x11_display = window->display->x11_display;
- frame->current_cursor = cursor;
- x11_display = frame->window->display->x11_display;
+ if (xevent->xany.type == PropertyNotify &&
+ xevent->xproperty.state == PropertyNewValue &&
+ (xevent->xproperty.atom == x11_display->atom__GTK_FRAME_EXTENTS ||
+ xevent->xproperty.atom == x11_display->atom__MUTTER_FRAME_EXTENTS))
+ {
+ meta_window_frame_size_changed (window);
+ meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
+ return TRUE;
+ }
- if (cursor == META_CURSOR_DEFAULT)
- XUndefineCursor (x11_display->xdisplay, frame->xwindow);
- else
+ return FALSE;
+}
+
+static void
+on_x11_display_setup (MetaDisplay *display,
+ gpointer user_data)
+{
+ g_autoptr(GSubprocessLauncher) launcher = NULL;
+ g_autoptr (GError) error = NULL;
+ GSubprocess *proc;
+ const char *args[2];
+
+ args[0] = MUTTER_LIBEXECDIR "/mutter-x11-frames";
+ args[1] = NULL;
+
+ launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
+ g_subprocess_launcher_setenv (launcher, "DISPLAY",
+ meta_x11_get_display_name (), TRUE);
+
+ proc = g_subprocess_launcher_spawnv (launcher, args, &error);
+ if (error)
{
- xcursor = meta_x11_display_create_x_cursor (x11_display, cursor);
- XDefineCursor (x11_display->xdisplay, frame->xwindow, xcursor);
- XFlush (x11_display->xdisplay);
- XFreeCursor (x11_display->xdisplay, xcursor);
+ g_warning ("Could not launch X11 frames client: %s", error->message);
+ return;
}
+
+ g_subprocess_wait_async (proc, NULL, on_frames_died, display);
+
+ g_object_set_data_full (G_OBJECT (display), "meta-x11-frames-process",
+ proc, g_object_unref);
}
-Window
-meta_frame_get_xwindow (MetaFrame *frame)
+static void
+on_x11_display_closing (MetaDisplay *display,
+ gpointer user_data)
{
- return frame->xwindow;
+ g_autoptr (GSubprocess) proc = NULL;
+
+ proc = g_object_get_data (G_OBJECT (display), "meta-x11-frames-process");
+ if (proc)
+ g_subprocess_send_signal (proc, SIGTERM);
}
-void
-meta_frame_update_style (MetaFrame *frame)
+static void
+on_frames_died (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
{
- meta_ui_frame_update_style (frame->ui_frame);
+ GSubprocess *proc = G_SUBPROCESS (source);
+ g_autoptr (GError) error = NULL;
+
+ if (!g_subprocess_wait_finish (proc, result, &error))
+ g_warning ("Mutter X11 frames client died: %s\n", error->message);
+
+ if (g_subprocess_get_if_signaled (proc))
+ {
+ int signum;
+
+ signum = g_subprocess_get_term_sig (proc);
+
+ /* Bring it up again, unless it was forcibly closed */
+ if (signum != SIGTERM && signum != SIGKILL)
+ on_x11_display_setup (user_data, NULL);
+ }
}
void
-meta_frame_update_title (MetaFrame *frame)
+meta_frame_initialize (MetaDisplay *display)
{
- if (frame->window->title)
- meta_ui_frame_set_title (frame->ui_frame, frame->window->title);
+ if (meta_is_wayland_compositor ())
+ {
+ g_signal_connect (display, "x11-display-setup",
+ G_CALLBACK (on_x11_display_setup),
+ NULL);
+ g_signal_connect (display, "x11-display-closing",
+ G_CALLBACK (on_x11_display_closing),
+ NULL);
+ }
+ else
+ {
+ g_signal_connect (display, "x11-display-opened",
+ G_CALLBACK (on_x11_display_setup),
+ NULL);
+ }
}
diff --git a/src/core/frame.h b/src/core/frame.h
index 61a5ca7255..84fb037927 100644
--- a/src/core/frame.h
+++ b/src/core/frame.h
@@ -23,7 +23,6 @@
#define META_FRAME_PRIVATE_H
#include "core/window-private.h"
-#include "ui/frames.h"
struct _MetaFrame
{
@@ -33,8 +32,6 @@ struct _MetaFrame
/* reparent window */
Window xwindow;
- MetaCursor current_cursor;
-
/* This rect is trusted info from where we put the
* frame, not the result of ConfigureNotify
*/
@@ -48,15 +45,11 @@ struct _MetaFrame
int right_width;
int bottom_height;
- guint need_reapply_frame_shape : 1;
guint borders_cached : 1;
-
- MetaUIFrame *ui_frame;
};
void meta_window_ensure_frame (MetaWindow *window);
void meta_window_destroy_frame (MetaWindow *window);
-void meta_frame_queue_draw (MetaFrame *frame);
MetaFrameFlags meta_frame_get_flags (MetaFrame *frame);
Window meta_frame_get_xwindow (MetaFrame *frame);
@@ -76,10 +69,8 @@ void meta_frame_get_mask (MetaFrame *frame,
cairo_rectangle_int_t *frame_rect,
cairo_t *cr);
-void meta_frame_set_screen_cursor (MetaFrame *frame,
- MetaCursor cursor);
-
-void meta_frame_update_style (MetaFrame *frame);
-void meta_frame_update_title (MetaFrame *frame);
+gboolean meta_frame_handle_xevent (MetaFrame *frame,
+ XEvent *event);
+void meta_frame_initialize (MetaDisplay *display);
#endif
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 1e559ddc61..c0468bf783 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -817,9 +817,6 @@ void meta_window_handle_enter (MetaWindow *window,
guint root_y);
void meta_window_handle_leave (MetaWindow *window);
-gboolean meta_window_handle_ui_frame_event (MetaWindow *window,
- const ClutterEvent *event);
-
void meta_window_handle_ungrabbed_event (MetaWindow *window,
const ClutterEvent *event);
@@ -903,4 +900,7 @@ gboolean meta_window_calculate_bounds (MetaWindow *window,
int *bounds_width,
int *bounds_height);
+void meta_window_set_frame_xwindow (MetaWindow *window,
+ Window xframe);
+
#endif
diff --git a/src/core/window.c b/src/core/window.c
index 5c09f6e81c..e9a0255350 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -793,6 +793,10 @@ client_window_should_be_mapped (MetaWindow *window)
return FALSE;
#endif
+ if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 &&
+ window->decorated && !window->frame)
+ return FALSE;
+
return !window->shaded;
}
@@ -1712,6 +1716,10 @@ meta_window_should_be_showing (MetaWindow *window)
return FALSE;
#endif
+ if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 &&
+ window->decorated && !window->frame)
+ return FALSE;
+
/* Windows should be showing if they're located on the
* active workspace and they're showing on their own workspace. */
return (meta_window_located_on_workspace (window, workspace_manager->active_workspace) &&
@@ -2944,9 +2952,6 @@ meta_window_tile (MetaWindow *window,
META_MOVE_RESIZE_STATE_CHANGED),
META_GRAVITY_NORTH_WEST,
window->unconstrained_rect);
-
- if (window->frame)
- meta_frame_queue_draw (window->frame);
}
MetaTileMode
@@ -5035,9 +5040,6 @@ meta_window_update_appears_focused (MetaWindow *window)
meta_window_frame_size_changed (window);
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_APPEARS_FOCUSED]);
-
- if (window->frame)
- meta_frame_queue_draw (window->frame);
}
static gboolean
@@ -5157,9 +5159,6 @@ meta_window_set_focused_internal (MetaWindow *window,
window);
}
- if (window->frame)
- meta_frame_queue_draw (window->frame);
-
/* Ungrab click to focus button since the sync grab can interfere
* with some things you might do inside the focused window, by
* causing the client to get funky enter/leave events.
@@ -7833,9 +7832,6 @@ meta_window_set_title (MetaWindow *window,
g_free (window->title);
window->title = g_strdup (title);
- if (window->frame)
- meta_frame_update_title (window->frame);
-
meta_window_update_desc (window);
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_TITLE]);
@@ -8216,16 +8212,6 @@ meta_window_handle_leave (MetaWindow *window)
meta_window_lower (window);
}
-gboolean
-meta_window_handle_ui_frame_event (MetaWindow *window,
- const ClutterEvent *event)
-{
- if (!window->frame)
- return FALSE;
-
- return meta_ui_frame_handle_event (window->frame->ui_frame, event);
-}
-
void
meta_window_handle_ungrabbed_event (MetaWindow *window,
const ClutterEvent *event)
diff --git a/src/x11/atomnames.h b/src/x11/atomnames.h
index b806e6e9dc..4e2939edb0 100644
--- a/src/x11/atomnames.h
+++ b/src/x11/atomnames.h
@@ -71,6 +71,9 @@ item(_MUTTER_TIMESTAMP_PING)
item(_MUTTER_FOCUS_SET)
item(_MUTTER_SENTINEL)
item(_MUTTER_VERSION)
+item(_MUTTER_FRAME_FOR)
+item(_MUTTER_FRAME_EXTENTS)
+item(_MUTTER_NEEDS_FRAME)
item(WM_CLIENT_MACHINE)
item(MANAGER)
item(TARGETS)
diff --git a/src/x11/events.c b/src/x11/events.c
index 8bacd0d2ab..02a86a1a5f 100644
--- a/src/x11/events.c
+++ b/src/x11/events.c
@@ -48,6 +48,7 @@
#include "x11/meta-x11-selection-input-stream-private.h"
#include "x11/meta-x11-selection-output-stream-private.h"
#include "x11/window-x11.h"
+#include "x11/window-x11-private.h"
#include "x11/xprops.h"
#ifdef HAVE_WAYLAND
@@ -965,10 +966,6 @@ handle_input_xevent (MetaX11Display *x11_display,
meta_x11_display_lookup_x_window (x11_display, modified) :
NULL;
- /* If this is an event for a GTK+ widget, let GTK+ handle it. */
- if (meta_ui_window_is_widget (x11_display->ui, modified))
- return FALSE;
-
switch (input_event->evtype)
{
case XI_Enter:
@@ -1039,10 +1036,6 @@ handle_input_xevent (MetaX11Display *x11_display,
break;
}
- /* Don't eat events for GTK frames (we need to update the :hover state on buttons) */
- if (window && window->frame && modified == window->frame->xwindow)
- return FALSE;
-
/* Don't pass these events through to Clutter / GTK+ */
return TRUE;
}
@@ -1410,8 +1403,6 @@ handle_other_xevent (MetaX11Display *x11_display,
if (frame_was_receiver)
{
- meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or
be considered a bug",
- window->frame->xwindow);
meta_x11_error_trap_push (x11_display);
meta_window_destroy_frame (window->frame->window);
meta_x11_error_trap_pop (x11_display);
@@ -1482,6 +1473,37 @@ handle_other_xevent (MetaX11Display *x11_display,
case MapRequest:
if (window == NULL)
{
+ Atom type;
+ int format;
+ unsigned long nitems, bytes_after, *data;
+
+ /* Check whether the new window is a frame for another window */
+ if (XGetWindowProperty (x11_display->xdisplay,
+ event->xmaprequest.window,
+ x11_display->atom__MUTTER_FRAME_FOR,
+ 0, 32, False, XA_WINDOW,
+ &type, &format, &nitems, &bytes_after,
+ (guchar **) &data) == Success &&
+ nitems == 1)
+ {
+ Window client_window;
+
+ client_window = data[0];
+ XFree (data);
+
+ window = meta_x11_display_lookup_x_window (x11_display,
+ client_window);
+
+ if (window != NULL && window->decorated && !window->frame)
+ {
+ meta_window_set_frame_xwindow (window,
+ event->xmaprequest.window);
+ meta_window_x11_initialize_state (window);
+ }
+
+ break;
+ }
+
window = meta_window_x11_new (display, event->xmaprequest.window,
FALSE, META_COMP_EFFECT_CREATE);
/* The window might have initial iconic state, but this is a
@@ -1491,7 +1513,6 @@ handle_other_xevent (MetaX11Display *x11_display,
}
else if (frame_was_receiver)
{
- meta_warning ("Map requests on the frame window are unexpected");
break;
}
@@ -1587,6 +1608,8 @@ handle_other_xevent (MetaX11Display *x11_display,
meta_window_x11_property_notify (window, event);
else if (property_for_window && !frame_was_receiver)
meta_window_x11_property_notify (property_for_window, event);
+ else if (frame_was_receiver)
+ meta_frame_handle_xevent (window->frame, event);
group = meta_x11_display_lookup_group (x11_display,
event->xproperty.window);
@@ -1640,7 +1663,6 @@ handle_other_xevent (MetaX11Display *x11_display,
}
else
#endif
- if (!frame_was_receiver)
meta_window_x11_client_message (window, event);
}
else
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index 76e0b077b0..f353712bc5 100644
--- a/src/x11/meta-x11-display.c
+++ b/src/x11/meta-x11-display.c
@@ -34,6 +34,7 @@
#include "x11/meta-x11-display-private.h"
#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -140,12 +141,6 @@ meta_x11_display_dispose (GObject *object)
meta_x11_selection_shutdown (x11_display);
meta_x11_display_unmanage_windows (x11_display);
- if (x11_display->ui)
- {
- meta_ui_free (x11_display->ui);
- x11_display->ui = NULL;
- }
-
if (x11_display->no_focus_window != None)
{
XUnmapWindow (x11_display->xdisplay, x11_display->no_focus_window);
@@ -1254,7 +1249,6 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
meta_unsigned_long_equal);
x11_display->groups_by_leader = NULL;
- x11_display->ui = NULL;
x11_display->composite_overlay_window = None;
x11_display->guard_window = None;
x11_display->leader_window = None;
@@ -1320,7 +1314,6 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
set_desktop_viewport_hint (x11_display);
set_desktop_geometry_hint (x11_display);
- x11_display->ui = meta_ui_new (x11_display);
x11_display->x11_stack = meta_x11_stack_new (x11_display);
x11_display->keys_grabbed = FALSE;
diff --git a/src/x11/meta-x11-window-control.c b/src/x11/meta-x11-window-control.c
index 4754be5498..7788550861 100644
--- a/src/x11/meta-x11-window-control.c
+++ b/src/x11/meta-x11-window-control.c
@@ -211,7 +211,4 @@ meta_x11_wm_set_screen_cursor (MetaX11Display *x11_display,
Window frame_on_screen,
MetaCursor cursor)
{
- MetaWindow *window = window_from_frame (x11_display, frame_on_screen);
-
- meta_frame_set_screen_cursor (window->frame, cursor);
}
diff --git a/src/x11/window-props.c b/src/x11/window-props.c
index a0a30b39a4..1eb3c990a4 100644
--- a/src/x11/window-props.c
+++ b/src/x11/window-props.c
@@ -1815,9 +1815,6 @@ reload_gtk_theme_variant (MetaWindow *window,
g_free (current_variant);
window->gtk_theme_variant = g_strdup (requested_variant);
-
- if (window->frame)
- meta_frame_update_style (window->frame);
}
}
diff --git a/src/x11/window-x11-private.h b/src/x11/window-x11-private.h
index 22c198268d..973fc083b8 100644
--- a/src/x11/window-x11-private.h
+++ b/src/x11/window-x11-private.h
@@ -93,6 +93,8 @@ void meta_window_x11_set_bypass_compositor_hint (MetaWindowX11 *windo
void meta_window_x11_queue_update_icon (MetaWindowX11 *window_x11);
+void meta_window_x11_initialize_state (MetaWindow *window);
+
G_END_DECLS
#endif
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index 29330d3962..54d5da275d 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -542,6 +542,15 @@ meta_window_x11_manage (MetaWindow *window)
if (window->decorated)
meta_window_ensure_frame (window);
+ else
+ meta_window_x11_initialize_state (window);
+}
+
+void
+meta_window_x11_initialize_state (MetaWindow *window)
+{
+ MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
+ MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
/* Now try applying saved stuff from the session */
{
@@ -1203,7 +1212,7 @@ update_gtk_edge_constraints (MetaWindow *window)
meta_x11_error_trap_push (x11_display);
XChangeProperty (x11_display->xdisplay,
- window->xwindow,
+ window->frame ? window->frame->xwindow : window->xwindow,
x11_display->atom__GTK_EDGE_CONSTRAINTS,
XA_CARDINAL, 32, PropModeReplace,
(guchar*) data, 1);
@@ -1717,9 +1726,6 @@ meta_window_x11_update_icon (MetaWindowX11 *window_x11,
g_object_notify (G_OBJECT (window), "icon");
g_object_notify (G_OBJECT (window), "mini-icon");
g_object_thaw_notify (G_OBJECT (window));
-
- if (window->frame)
- meta_frame_queue_draw (window->frame);
}
}
@@ -2189,6 +2195,16 @@ meta_window_x11_set_net_wm_state (MetaWindow *window)
x11_display->atom__NET_WM_STATE,
XA_ATOM,
32, PropModeReplace, (guchar*) data, i);
+
+ if (window->frame)
+ {
+ XChangeProperty (x11_display->xdisplay,
+ window->frame->xwindow,
+ x11_display->atom__NET_WM_STATE,
+ XA_ATOM,
+ 32, PropModeReplace, (guchar*) data, i);
+ }
+
meta_x11_error_trap_pop (x11_display);
if (window->fullscreen)
@@ -3927,10 +3943,21 @@ meta_window_x11_set_allowed_actions_hint (MetaWindow *window)
meta_verbose ("Setting _NET_WM_ALLOWED_ACTIONS with %d atoms", i);
meta_x11_error_trap_push (x11_display);
- XChangeProperty (x11_display->xdisplay, window->xwindow,
+ XChangeProperty (x11_display->xdisplay,
+ window->xwindow,
x11_display->atom__NET_WM_ALLOWED_ACTIONS,
XA_ATOM,
32, PropModeReplace, (guchar*) data, i);
+
+ if (window->frame)
+ {
+ XChangeProperty (x11_display->xdisplay,
+ window->frame->xwindow,
+ x11_display->atom__NET_WM_ALLOWED_ACTIONS,
+ XA_ATOM,
+ 32, PropModeReplace, (guchar*) data, i);
+ }
+
meta_x11_error_trap_pop (x11_display);
#undef MAX_N_ACTIONS
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]