[mutter/wip/carlosg/frames-client: 4/5] WIP: core: Port to frames client




commit d5d87e7902cd3055bda45794290eb5cb1bb387b7
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Dec 21 21:22:58 2021 +0100

    WIP: core: Port to frames client
    
    Move away from the internal MetaUI infrastructure for rendering
    frames, and move these to be handled by the frames client. This
    turns a few things upside down, some messaging needs to happen
    now on the frame Window instead (being later propagated to the
    client Window by the frames client), and we also now get some
    extra events, including some we did not expect to get on/from
    frames previously.

 src/backends/meta-settings.c           |   1 -
 src/compositor/meta-window-actor-x11.c |  48 -----
 src/core/display.c                     |  28 +--
 src/core/events.c                      |   2 +
 src/core/frame.c                       | 324 +++++++++++++++++++++++----------
 src/core/frame.h                       |  11 +-
 src/core/window-private.h              |   3 +
 src/core/window.c                      |  39 +---
 src/tests/test-runner.c                |   8 -
 src/x11/atomnames.h                    |   2 +
 src/x11/events.c                       |  83 +++++----
 src/x11/meta-x11-display-private.h     |   3 -
 src/x11/meta-x11-display.c             |   9 +-
 src/x11/meta-x11-window-control.c      |  10 -
 src/x11/meta-x11-window-control.h      |   4 -
 src/x11/window-props.c                 |   3 -
 src/x11/window-x11-private.h           |   2 +
 src/x11/window-x11.c                   |  74 +++++---
 18 files changed, 344 insertions(+), 310 deletions(-)
---
diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c
index 6a754d4e0a..87f58875aa 100644
--- a/src/backends/meta-settings.c
+++ b/src/backends/meta-settings.c
@@ -28,7 +28,6 @@
 #include "backends/meta-backend-private.h"
 #include "backends/meta-logical-monitor.h"
 #include "backends/meta-monitor-manager-private.h"
-#include "ui/theme-private.h"
 
 #ifndef XWAYLAND_GRAB_DEFAULT_ACCESS_RULES
 # warning "XWAYLAND_GRAB_DEFAULT_ACCESS_RULES is not set"
diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c
index 9e64462ea8..7f4c65c4f6 100644
--- a/src/compositor/meta-window-actor-x11.c
+++ b/src/compositor/meta-window-actor-x11.c
@@ -1316,9 +1316,6 @@ meta_window_actor_x11_paint (ClutterActor        *actor,
                              ClutterPaintContext *paint_context)
 {
   MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
-  MetaWindow *window;
-  gboolean appears_focused;
-  MetaShadow *shadow;
 
  /* This window got damage when obscured; we set up a timer
   * to send frame completion events, but since we're drawing
@@ -1330,51 +1327,6 @@ meta_window_actor_x11_paint (ClutterActor        *actor,
       assign_frame_counter_to_frames (actor_x11);
     }
 
-  window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
-  appears_focused = meta_window_appears_focused (window);
-  shadow = appears_focused ? actor_x11->focused_shadow
-                           : actor_x11->unfocused_shadow;
-
-  if (shadow)
-    {
-      MetaShadowParams params;
-      cairo_rectangle_int_t shape_bounds;
-      cairo_region_t *clip = actor_x11->shadow_clip;
-      CoglFramebuffer *framebuffer;
-
-      get_shape_bounds (actor_x11, &shape_bounds);
-      get_shadow_params (actor_x11, appears_focused, &params);
-
-      /* The frame bounds are already subtracted from actor_x11->shadow_clip
-       * if that exists.
-       */
-      if (!clip && clip_shadow_under_window (actor_x11))
-        {
-          cairo_rectangle_int_t bounds;
-
-          get_shadow_bounds (actor_x11, appears_focused, &bounds);
-          clip = cairo_region_create_rectangle (&bounds);
-
-          if (actor_x11->frame_bounds)
-            cairo_region_subtract (clip, actor_x11->frame_bounds);
-        }
-
-      framebuffer = clutter_paint_context_get_framebuffer (paint_context);
-      meta_shadow_paint (shadow,
-                         framebuffer,
-                         params.x_offset + shape_bounds.x,
-                         params.y_offset + shape_bounds.y,
-                         shape_bounds.width,
-                         shape_bounds.height,
-                         (clutter_actor_get_paint_opacity (actor) *
-                          params.opacity * window->opacity) / (255 * 255),
-                         clip,
-                         clip_shadow_under_window (actor_x11));
-
-      if (clip && clip != actor_x11->shadow_clip)
-        cairo_region_destroy (clip);
-    }
-
   CLUTTER_ACTOR_CLASS (meta_window_actor_x11_parent_class)->paint (actor,
                                                                    paint_context);
 }
diff --git a/src/core/display.c b/src/core/display.c
index 60b8add77e..9751364d24 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -965,6 +965,8 @@ meta_display_new (MetaContext  *context,
       meta_display_unset_input_focus (display, timestamp);
     }
 
+  meta_frame_initialize (display);
+
   display->sound_player = g_object_new (META_TYPE_SOUND_PLAYER, NULL);
 
   /* Done opening new display */
@@ -2056,31 +2058,6 @@ meta_display_check_threshold_reached (MetaDisplay *display,
     display->grab_threshold_movement_reached = TRUE;
 }
 
-void
-meta_display_queue_retheme_all_windows (MetaDisplay *display)
-{
-  GSList* windows;
-  GSList *tmp;
-
-  windows = meta_display_list_windows (display, META_LIST_DEFAULT);
-  tmp = windows;
-  while (tmp != NULL)
-    {
-      MetaWindow *window = tmp->data;
-
-      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;
-    }
-
-  g_slist_free (windows);
-}
-
 /*
  * Stores whether syncing is currently enabled.
  */
@@ -2724,7 +2701,6 @@ prefs_changed_callback (MetaPreference pref,
   switch (pref)
     {
     case META_PREF_DRAGGABLE_BORDER_WIDTH:
-      meta_display_queue_retheme_all_windows (display);
       break;
     case META_PREF_CURSOR_THEME:
     case META_PREF_CURSOR_SIZE:
diff --git a/src/core/events.c b/src/core/events.c
index a8f854a021..29b1412e6a 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -409,6 +409,7 @@ meta_display_handle_event (MetaDisplay        *display,
        */
       bypass_clutter = !IS_GESTURE_EVENT (event);
 
+#if 0
       /* 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
@@ -425,6 +426,7 @@ meta_display_handle_event (MetaDisplay        *display,
                             event->type == CLUTTER_TOUCH_BEGIN);
         }
       else
+#endif
         {
           bypass_wayland = meta_window_has_modals (window);
           meta_window_handle_ungrabbed_event (window, event);
diff --git a/src/core/frame.c b/src/core/frame.c
index 9c8cbb9464..952b7f3205 100644
--- a/src/core/frame.c
+++ b/src/core/frame.c
@@ -31,24 +31,39 @@
 #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)
 
+static void
+send_frame_request (MetaWindow *window)
+{
+  MetaX11Display *x11_display = window->display->x11_display;
+  Display *xdisplay = x11_display->xdisplay;
+  XEvent xev = { 0 };
+
+  xev.xclient.type = ClientMessage;
+  xev.xclient.message_type = XInternAtom (xdisplay, "_MUTTER_FRAME", False);
+  xev.xclient.format = 32;
+  xev.xclient.window = x11_display->xroot;
+  xev.xclient.data.l[0] = window->xwindow;
+
+  meta_x11_error_trap_push (x11_display);
+  XSendEvent (xdisplay, x11_display->xroot, False, ClientMessage, &xev);
+  meta_x11_error_trap_pop (x11_display);
+}
+
 void
 meta_window_ensure_frame (MetaWindow *window)
 {
   MetaFrame *frame;
-  XSetWindowAttributes attrs;
-  gulong create_serial;
-  MetaX11Display *x11_display;
 
   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;
@@ -62,29 +77,36 @@ meta_window_ensure_frame (MetaWindow *window)
 
   frame->borders_cached = FALSE;
 
+  send_frame_request (window);
+
+  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;
+void
+meta_window_set_frame_xwindow (MetaWindow *window,
+                               Window      xframe)
+{
+  MetaX11Display *x11_display = window->display->x11_display;
+  MetaFrame *frame = window->frame;
+  gulong create_serial = 0;
+
+  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,
                                  create_serial);
 
   meta_verbose ("Frame for %s is 0x%lx", frame->window->desc, frame->xwindow);
-  attrs.event_mask = EVENT_MASK;
-  XChangeWindowAttributes (x11_display->xdisplay,
-                          frame->xwindow, CWEventMask, &attrs);
 
   meta_x11_display_register_x_window (x11_display, &frame->xwindow, window);
 
@@ -111,6 +133,10 @@ meta_window_ensure_frame (MetaWindow *window)
   /* FIXME handle this error */
   meta_x11_error_trap_pop (x11_display);
 
+  XSelectInput (x11_display->xdisplay,
+                frame->xwindow,
+                KeyPressMask | PropertyChangeMask);
+
   /* Ensure focus is restored after the unmap/map events triggered
    * by XReparentWindow().
    */
@@ -120,41 +146,6 @@ 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);
-      }
-  }
-
   /* Move keybindings to frame instead of window */
   meta_window_grab_keys (window);
 }
@@ -212,8 +203,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 +307,77 @@ 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_HEIGHT,
+                            0, 1,
+                            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 == 1)
+    {
+      borders->visible = (GtkBorder) {
+        0, 0, ((long *) data)[0], 0,
+      };
+    }
+
+  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 +390,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;
         }
 
@@ -355,19 +415,13 @@ 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);
-
   return need_resize;
 }
 
 cairo_region_t *
 meta_frame_get_frame_bounds (MetaFrame *frame)
 {
-  return meta_ui_frame_get_bounds (frame->ui_frame);
+  return NULL;
 }
 
 void
@@ -375,53 +429,137 @@ 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_query_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_HEIGHT))
+    {
+      meta_frame_query_borders (frame, &frame->cached_borders);
+      meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
+      frame->borders_cached = TRUE;
+      return TRUE;
+    }
 
-  if (cursor == META_CURSOR_DEFAULT)
-    XUndefineCursor (x11_display->xdisplay, frame->xwindow);
-  else
+  return FALSE;
+}
+
+/**
+ * meta_frame_type_to_string:
+ * @type: a #MetaFrameType
+ *
+ * Converts a frame type enum value to the name string that would
+ * appear in the theme definition file.
+ *
+ * Return value: the string value
+ */
+const char*
+meta_frame_type_to_string (MetaFrameType type)
+{
+  switch (type)
     {
-      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);
+    case META_FRAME_TYPE_NORMAL:
+      return "normal";
+    case META_FRAME_TYPE_DIALOG:
+      return "dialog";
+    case META_FRAME_TYPE_MODAL_DIALOG:
+      return "modal_dialog";
+    case META_FRAME_TYPE_UTILITY:
+      return "utility";
+    case META_FRAME_TYPE_MENU:
+      return "menu";
+    case META_FRAME_TYPE_BORDER:
+      return "border";
+    case META_FRAME_TYPE_ATTACHED:
+      return "attached";
+#if 0
+    case META_FRAME_TYPE_TOOLBAR:
+      return "toolbar";
+#endif
+    case  META_FRAME_TYPE_LAST:
+      break;
     }
+
+  return "<unknown>";
 }
 
-Window
-meta_frame_get_xwindow (MetaFrame *frame)
+static void
+on_frames_died (GObject      *source,
+                GAsyncResult *result,
+                gpointer      user_data)
 {
-  return frame->xwindow;
+  GSubprocess *proc = user_data;
+  g_autoptr (GError) error = NULL;
+
+  if (!g_subprocess_wait_finish (proc, result, &error))
+    g_warning ("Mutter X11 frames client died: %s\n", error->message);
 }
 
-void
-meta_frame_update_style (MetaFrame *frame)
+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;
+
+  g_print ("hmmmmm %s\n", args[0]);
+  launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
+  g_print ("ohhh %s\n", meta_x11_get_display_name ());
+  g_subprocess_launcher_setenv (launcher, "DISPLAY",
+                                meta_x11_get_display_name (), TRUE);
+
+  proc = g_subprocess_launcher_spawnv (launcher, args, &error);
+  if (proc)
+    g_subprocess_wait_async (proc, NULL, on_frames_died, NULL);
+
+  if (error)
+    g_warning ("Could not launch X11 frames client: %s", error->message);
+}
+
+static void
+on_x11_display_closing (MetaDisplay *display,
+                        gpointer     user_data)
 {
-  meta_ui_frame_update_style (frame->ui_frame);
+  g_print ("closing.... \n");
 }
 
 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);
+  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);
 }
diff --git a/src/core/frame.h b/src/core/frame.h
index 61a5ca7255..8b7c3152a2 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
 {
@@ -50,13 +49,10 @@ struct _MetaFrame
 
   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 +72,9 @@ 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);
+gboolean meta_frame_handle_xevent (MetaFrame *frame,
+                                   XEvent    *event);
 
-void meta_frame_update_style (MetaFrame *frame);
-void meta_frame_update_title (MetaFrame *frame);
+void meta_frame_initialize (MetaDisplay *display);
 
 #endif
diff --git a/src/core/window-private.h b/src/core/window-private.h
index ccb5b719dd..5459b1c7d5 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -914,4 +914,7 @@ gboolean meta_window_unit_cgroup_equal (MetaWindow *window1,
 void meta_window_check_alive_on_event (MetaWindow *window,
                                        uint32_t    timestamp);
 
+void meta_window_set_frame_xwindow (MetaWindow *window,
+                                    Window      xframe);
+
 #endif
diff --git a/src/core/window.c b/src/core/window.c
index 518cebb347..a2f67c6133 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -84,7 +84,6 @@
 #include "meta/meta-enum-types.h"
 #include "meta/meta-x11-errors.h"
 #include "meta/prefs.h"
-#include "ui/ui.h"
 #include "x11/meta-x11-display-private.h"
 #include "x11/window-props.h"
 #include "x11/window-x11.h"
@@ -1758,6 +1757,10 @@ meta_window_should_be_showing (MetaWindow  *window)
     return FALSE;
 #endif
 
+  if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 &&
+      window->frame && !window->frame->xwindow)
+    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) &&
@@ -3232,9 +3235,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
@@ -5326,9 +5326,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
@@ -5448,9 +5445,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.
@@ -5550,16 +5544,6 @@ meta_window_set_icon_geometry (MetaWindow    *window,
     }
 }
 
-static void
-redraw_icon (MetaWindow *window)
-{
-  /* We could probably be smart and just redraw the icon here,
-   * instead of the whole frame.
-   */
-  if (window->frame)
-    meta_frame_queue_draw (window->frame);
-}
-
 static void
 meta_window_update_icon_now (MetaWindow *window,
                              gboolean    force)
@@ -5586,8 +5570,6 @@ meta_window_update_icon_now (MetaWindow *window,
       g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_ICON]);
       g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MINI_ICON]);
       g_object_thaw_notify (G_OBJECT (window));
-
-      redraw_icon (window);
     }
 }
 
@@ -8176,9 +8158,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]);
@@ -8558,16 +8537,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/tests/test-runner.c b/src/tests/test-runner.c
index edaf84f81b..6a98e23ea3 100644
--- a/src/tests/test-runner.c
+++ b/src/tests/test-runner.c
@@ -30,7 +30,6 @@
 #include "meta/window.h"
 #include "meta/meta-workspace-manager.h"
 #include "tests/meta-test-utils.h"
-#include "ui/ui.h"
 #include "wayland/meta-wayland.h"
 #include "x11/meta-x11-display-private.h"
 
@@ -238,13 +237,6 @@ test_case_assert_stacking (TestCase *test,
       MetaWindow *window = meta_display_lookup_stack_id (display, windows[i]);
       if (window != NULL && window->title)
         {
-          /* See comment in meta_ui_new() about why the dummy window for GTK+ theming
-           * is managed as a MetaWindow.
-           */
-          if (META_STACK_ID_IS_X11 (windows[i]) &&
-              meta_ui_window_is_dummy (display->x11_display->ui, windows[i]))
-            continue;
-
           if (stack_string->len > 0)
             g_string_append_c (stack_string, ' ');
 
diff --git a/src/x11/atomnames.h b/src/x11/atomnames.h
index b806e6e9dc..8931c40c53 100644
--- a/src/x11/atomnames.h
+++ b/src/x11/atomnames.h
@@ -71,6 +71,8 @@ item(_MUTTER_TIMESTAMP_PING)
 item(_MUTTER_FOCUS_SET)
 item(_MUTTER_SENTINEL)
 item(_MUTTER_VERSION)
+item(_MUTTER_FRAME_FOR)
+item(_MUTTER_FRAME_HEIGHT)
 item(WM_CLIENT_MACHINE)
 item(MANAGER)
 item(TARGETS)
diff --git a/src/x11/events.c b/src/x11/events.c
index 75472e786e..e145c9cd1d 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
@@ -785,7 +786,6 @@ meta_spew_event_print (MetaX11Display *x11_display,
     return;
 
   event_str = meta_spew_event (x11_display, event);
-  g_print ("%s\n", event_str);
   g_free (event_str);
 }
 
@@ -963,10 +963,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:
@@ -1031,10 +1027,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;
 }
@@ -1400,20 +1392,9 @@ handle_other_xevent (MetaX11Display *x11_display,
               display->grab_window == window)
             meta_display_end_grab_op (display, timestamp);
 
-          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);
-            }
-          else
-            {
-              /* Unmanage destroyed window */
-              meta_window_unmanage (window, timestamp);
-              window = NULL;
-            }
+          /* Unmanage destroyed window */
+          meta_window_unmanage (window, timestamp);
+          window = NULL;
         }
       break;
     case UnmapNotify:
@@ -1474,8 +1455,41 @@ handle_other_xevent (MetaX11Display *x11_display,
     case MapRequest:
       if (window == NULL)
         {
+          {
+            Atom type;
+            int format;
+            unsigned long nitems, bytes_after, *data;
+
+            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)
+                  {
+                    meta_window_set_frame_xwindow (window,
+                                                   event->xmaprequest.window);
+                    XMapWindow (x11_display->xdisplay, event->xmaprequest.window);
+                    meta_window_x11_manage_late (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
            * MapRequest, fall through to ensure it is unminimized in
            * that case.
@@ -1483,7 +1497,6 @@ handle_other_xevent (MetaX11Display *x11_display,
         }
       else if (frame_was_receiver)
         {
-          meta_warning ("Map requests on the frame window are unexpected");
           break;
         }
 
@@ -1559,8 +1572,7 @@ handle_other_xevent (MetaX11Display *x11_display,
         }
       else
         {
-          if (!frame_was_receiver)
-            meta_window_x11_configure_request (window, event);
+          meta_window_x11_configure_request (window, event);
         }
       break;
     case GravityNotify:
@@ -1579,6 +1591,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);
@@ -1632,8 +1646,9 @@ handle_other_xevent (MetaX11Display *x11_display,
             }
           else
 #endif
-          if (!frame_was_receiver)
-            meta_window_x11_client_message (window, event);
+            {
+              meta_window_x11_client_message (window, event);
+            }
         }
       else
         {
@@ -1916,18 +1931,6 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display,
 
   input_event = get_input_event (x11_display, event);
 
-  if (event->type == UnmapNotify)
-    {
-      if (meta_ui_window_should_not_cause_focus (x11_display->xdisplay,
-                                                 modified))
-        {
-          meta_display_add_ignored_crossing_serial (display, event->xany.serial);
-          meta_topic (META_DEBUG_FOCUS,
-                      "Adding EnterNotify serial %lu to ignored focus serials",
-                      event->xany.serial);
-        }
-    }
-
   if (meta_x11_display_process_barrier_xevent (x11_display, input_event))
     {
       bypass_gtk = bypass_compositor = TRUE;
diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h
index d53073e111..ba7b009e73 100644
--- a/src/x11/meta-x11-display-private.h
+++ b/src/x11/meta-x11-display-private.h
@@ -36,7 +36,6 @@
 #include "meta/meta-x11-display.h"
 #include "meta-startup-notification-x11.h"
 #include "meta-x11-stack-private.h"
-#include "ui/ui.h"
 
 typedef struct _MetaGroupPropHooks  MetaGroupPropHooks;
 typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
@@ -123,8 +122,6 @@ struct _MetaX11Display
   MetaAlarmFilter alarm_filter;
   gpointer alarm_filter_data;
 
-  MetaUI *ui;
-
   struct {
     Window xwindow;
     guint timeout_id;
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index 7b89cac248..009eee7204 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>
@@ -147,12 +148,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);
@@ -1243,7 +1238,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;
@@ -1334,7 +1328,6 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
 
   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..03ce5f34bd 100644
--- a/src/x11/meta-x11-window-control.c
+++ b/src/x11/meta-x11-window-control.c
@@ -205,13 +205,3 @@ meta_x11_wm_grab_buttons  (MetaX11Display *x11_display,
   meta_verbose ("Grabbing buttons on frame 0x%lx", frame_xwindow);
   meta_display_grab_window_buttons (display, frame_xwindow);
 }
-
-void
-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/meta-x11-window-control.h b/src/x11/meta-x11-window-control.h
index dfb66f262c..960b294e29 100644
--- a/src/x11/meta-x11-window-control.h
+++ b/src/x11/meta-x11-window-control.h
@@ -74,8 +74,4 @@ MetaGrabOp meta_x11_wm_get_grab_op (MetaX11Display *x11_display);
 void meta_x11_wm_grab_buttons  (MetaX11Display *x11_display,
                                 Window          frame_xwindow);
 
-void meta_x11_wm_set_screen_cursor (MetaX11Display *x11_display,
-                                    Window          frame_on_screen,
-                                    MetaCursor      cursor);
-
 #endif /* META_X11_WINDOW_CONTROL_H */
diff --git a/src/x11/window-props.c b/src/x11/window-props.c
index 1d8cf63a62..03fea7566f 100644
--- a/src/x11/window-props.c
+++ b/src/x11/window-props.c
@@ -1816,9 +1816,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 e12f83be0c..bc6133097d 100644
--- a/src/x11/window-x11-private.h
+++ b/src/x11/window-x11-private.h
@@ -84,6 +84,8 @@ MetaWindowX11Private * meta_window_x11_get_private (MetaWindowX11 *window_x11);
 void meta_window_x11_set_bypass_compositor_hint (MetaWindowX11            *window_x11,
                                                  MetaBypassCompositorHint  requested_value);
 
+void meta_window_x11_manage_late (MetaWindow *window);
+
 G_END_DECLS
 
 #endif
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index 7f8e79aa52..55ca9d3ca0 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -222,8 +222,7 @@ send_configure_notify (MetaWindow *window)
   event.xconfigure.display = x11_display->xdisplay;
   event.xconfigure.event = window->xwindow;
   event.xconfigure.window = window->xwindow;
-  event.xconfigure.x = priv->client_rect.x - priv->border_width;
-  event.xconfigure.y = priv->client_rect.y - priv->border_width;
+
   if (window->frame)
     {
       if (window->withdrawn)
@@ -244,9 +243,26 @@ send_configure_notify (MetaWindow *window)
           event.xconfigure.x += window->frame->rect.x;
           event.xconfigure.y += window->frame->rect.y;
         }
+
+      {
+        MetaFrameBorders borders;
+        cairo_rectangle_int_t rect;
+        meta_window_frame_rect_to_client_rect (window, &window->rect, &rect);
+        event.xconfigure.x = rect.x;
+        event.xconfigure.y = rect.y;
+        event.xconfigure.width = rect.width;
+        event.xconfigure.height = rect.height;
+
+        meta_frame_calc_borders (window->frame, &borders);
+      }
+    }
+  else
+    {
+      event.xconfigure.x = priv->client_rect.x - priv->border_width;
+      event.xconfigure.y = priv->client_rect.y - priv->border_width;
+      event.xconfigure.width = priv->client_rect.width;
+      event.xconfigure.height = priv->client_rect.height;
     }
-  event.xconfigure.width = priv->client_rect.width;
-  event.xconfigure.height = priv->client_rect.height;
   event.xconfigure.border_width = priv->border_width; /* requested not actual */
   event.xconfigure.above = None; /* FIXME */
   event.xconfigure.override_redirect = False;
@@ -538,6 +554,13 @@ meta_window_x11_manage (MetaWindow *window)
 
   if (window->decorated)
     meta_window_ensure_frame (window);
+}
+
+void
+meta_window_x11_manage_late (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 */
   {
@@ -1119,7 +1142,8 @@ update_net_frame_extents (MetaWindow *window)
               window->xwindow, data[0], data[1], data[2], data[3]);
 
   meta_x11_error_trap_push (x11_display);
-  XChangeProperty (x11_display->xdisplay, window->xwindow,
+  XChangeProperty (x11_display->xdisplay,
+                   window->frame ? window->frame->xwindow : window->xwindow,
                    x11_display->atom__NET_FRAME_EXTENTS,
                    XA_CARDINAL,
                    32, PropModeReplace, (guchar*) data, 4);
@@ -1198,7 +1222,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);
@@ -1409,16 +1433,21 @@ meta_window_x11_move_resize_internal (MetaWindow                *window,
     }
 
   /* Calculate the new client rect */
-  meta_window_frame_rect_to_client_rect (window, &constrained_rect, &client_rect);
-
-  /* The above client_rect is in root window coordinates. The
-   * values we need to pass to XConfigureWindow are in parent
-   * coordinates, so if the window is in a frame, we need to
-   * correct the x/y positions here. */
   if (window->frame)
     {
-      client_rect.x = borders.total.left;
-      client_rect.y = borders.total.top;
+      MetaFrameBorders borders;
+
+      meta_frame_calc_borders (window->frame, &borders);
+      client_rect = constrained_rect;
+
+      client_rect.x -= borders.invisible.left;
+      client_rect.y -= borders.invisible.top;
+      client_rect.width += borders.invisible.left + borders.invisible.right;
+      client_rect.height += borders.invisible.top + borders.invisible.bottom;
+    }
+  else
+    {
+      meta_window_frame_rect_to_client_rect (window, &constrained_rect, &client_rect);
     }
 
   if (client_rect.x != priv->client_rect.x ||
@@ -1563,7 +1592,7 @@ meta_window_x11_move_resize_internal (MetaWindow                *window,
         }
 
       XConfigureWindow (window->display->x11_display->xdisplay,
-                        window->xwindow,
+                        window->frame ? window->frame->xwindow : window->xwindow,
                         mask,
                         &values);
 
@@ -1573,10 +1602,7 @@ meta_window_x11_move_resize_internal (MetaWindow                *window,
   if (!configure_frame_first && window->frame)
     frame_shape_changed = meta_frame_sync_to_window (window->frame, need_resize_frame);
 
-  if (window->frame)
-    window->buffer_rect = window->frame->rect;
-  else
-    window->buffer_rect = client_rect;
+  window->buffer_rect = client_rect;
 
   if (need_configure_notify)
     send_configure_notify (window);
@@ -2185,7 +2211,8 @@ meta_window_x11_set_net_wm_state (MetaWindow *window)
   meta_verbose ("Setting _NET_WM_STATE with %d atoms", i);
 
   meta_x11_error_trap_push (x11_display);
-  XChangeProperty (x11_display->xdisplay, window->xwindow,
+  XChangeProperty (x11_display->xdisplay,
+                   window->frame ? window->frame->xwindow : window->xwindow,
                    x11_display->atom__NET_WM_STATE,
                    XA_ATOM,
                    32, PropModeReplace, (guchar*) data, i);
@@ -2211,7 +2238,7 @@ meta_window_x11_set_net_wm_state (MetaWindow *window)
           meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS");
           meta_x11_error_trap_push (x11_display);
           XChangeProperty (x11_display->xdisplay,
-                           window->xwindow,
+                           window->frame ? window->frame->xwindow : window->xwindow,
                            x11_display->atom__NET_WM_FULLSCREEN_MONITORS,
                            XA_CARDINAL, 32, PropModeReplace,
                            (guchar*) data, 4);
@@ -2222,7 +2249,7 @@ meta_window_x11_set_net_wm_state (MetaWindow *window)
           meta_verbose ("Clearing _NET_WM_FULLSCREEN_MONITORS");
           meta_x11_error_trap_push (x11_display);
           XDeleteProperty (x11_display->xdisplay,
-                           window->xwindow,
+                           window->frame ? window->frame->xwindow : window->xwindow,
                            x11_display->atom__NET_WM_FULLSCREEN_MONITORS);
           meta_x11_error_trap_pop (x11_display);
         }
@@ -3924,7 +3951,8 @@ 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->frame ? window->frame->xwindow : window->xwindow,
                    x11_display->atom__NET_WM_ALLOWED_ACTIONS,
                    XA_ATOM,
                    32, PropModeReplace, (guchar*) data, i);


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