[mutter/bilelmoussaoui/untangle-window: 1/2] core: Untangle meta_window_shared_new




commit ee6a3a3ffb791f1dedc28ce1aacca94b67876e3d
Author: Bilal Elmoussaoui <belmouss redhat com>
Date:   Mon May 16 16:48:01 2022 +0200

    core: Untangle meta_window_shared_new
    
    The constructor used to take Wayland/X11 specific types which makes
    building without Wayland/X11 not possible.
    
    Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2272

 src/core/window-private.h         |   8 -
 src/core/window.c                 | 817 +++++++++++++++++++-------------------
 src/wayland/meta-window-wayland.c |  55 ++-
 src/x11/window-x11-private.h      |   2 +
 src/x11/window-x11.c              | 153 ++++++-
 5 files changed, 578 insertions(+), 457 deletions(-)
---
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 8d2d4a0203..86986f6903 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -647,14 +647,6 @@ struct _MetaWindowClass
 #define META_WINDOW_ALLOWS_HORIZONTAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && 
(w)->size_hints.min_width < (w)->size_hints.max_width)
 #define META_WINDOW_ALLOWS_VERTICAL_RESIZE(w)   (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && 
(w)->size_hints.min_height < (w)->size_hints.max_height)
 
-MetaWindow * _meta_window_shared_new       (MetaDisplay         *display,
-                                            MetaWindowClientType client_type,
-                                            MetaWaylandSurface  *surface,
-                                            Window               xwindow,
-                                            gulong               existing_wm_state,
-                                            MetaCompEffect       effect,
-                                            XWindowAttributes   *attrs);
-
 void        meta_window_unmanage           (MetaWindow  *window,
                                             guint32      timestamp);
 void        meta_window_unmanage_on_idle   (MetaWindow *window);
diff --git a/src/core/window.c b/src/core/window.c
index 95a8e33e04..713d65bcf5 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -203,6 +203,10 @@ enum
   PROP_GTK_MENUBAR_OBJECT_PATH,
   PROP_ON_ALL_WORKSPACES,
   PROP_IS_ALIVE,
+  PROP_DISPLAY,
+  PROP_EFFECT,
+  PROP_SURFACE,
+  PROP_XWINDOW,
 
   PROP_LAST,
 };
@@ -416,6 +420,18 @@ meta_window_get_property(GObject         *object,
     case PROP_ON_ALL_WORKSPACES:
       g_value_set_boolean (value, win->on_all_workspaces);
       break;
+    case PROP_DISPLAY:
+      g_value_set_object (value, win->display);
+      break;
+    case PROP_EFFECT:
+      g_value_set_int (value, win->pending_compositor_effect);
+      break;
+    case PROP_SURFACE:
+      g_value_set_pointer (value, win->surface);
+      break;
+    case PROP_XWINDOW:
+      g_value_set_ulong (value, win->xwindow);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -428,349 +444,88 @@ meta_window_set_property(GObject         *object,
                          const GValue    *value,
                          GParamSpec      *pspec)
 {
+  MetaWindow *win = META_WINDOW (object);
+
   switch (prop_id)
     {
+    case PROP_DISPLAY:
+      win->display = g_value_get_object (value);
+      break;
+    case PROP_EFFECT:
+      win->pending_compositor_effect = g_value_get_int (value);
+      break;
+    case PROP_SURFACE:
+      win->surface = g_value_get_pointer (value);
+      break;
+    case PROP_XWINDOW:
+      win->xwindow = g_value_get_ulong (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     }
 }
 
-static void
-meta_window_class_init (MetaWindowClass *klass)
+static gboolean
+is_desktop_or_dock_foreach (MetaWindow *window,
+                            void       *data)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  gboolean *result = data;
 
-  object_class->finalize = meta_window_finalize;
+  *result =
+    window->type == META_WINDOW_DESKTOP ||
+    window->type == META_WINDOW_DOCK ||
+    window->skip_from_window_list;
+  if (*result)
+    return FALSE; /* stop as soon as we find one */
+  else
+    return TRUE;
+}
 
-  object_class->get_property = meta_window_get_property;
-  object_class->set_property = meta_window_set_property;
+/* window is the window that's newly mapped provoking
+ * the possible change
+ */
+static void
+maybe_leave_show_desktop_mode (MetaWindow *window)
+{
+  MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
+  gboolean is_desktop_or_dock;
 
-  klass->grab_op_began = meta_window_real_grab_op_began;
-  klass->grab_op_ended = meta_window_real_grab_op_ended;
-  klass->current_workspace_changed = meta_window_real_current_workspace_changed;
-  klass->update_struts = meta_window_real_update_struts;
-  klass->get_default_skip_hints = meta_window_real_get_default_skip_hints;
-  klass->get_client_pid = meta_window_real_get_client_pid;
+  if (!workspace_manager->active_workspace->showing_desktop)
+    return;
 
-  obj_props[PROP_TITLE] =
-    g_param_spec_string ("title",
-                         "Title",
-                         "The title of the window",
-                         NULL,
-                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_ICON] =
-    g_param_spec_pointer ("icon",
-                          "Icon",
-                          "Normal icon, usually 96x96 pixels",
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_MINI_ICON] =
-    g_param_spec_pointer ("mini-icon",
-                          "Mini Icon",
-                          "Mini icon, usually 16x16 pixels",
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_DECORATED] =
-    g_param_spec_boolean ("decorated",
-                          "Decorated",
-                          "Whether window is decorated",
-                          TRUE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_FULLSCREEN] =
-    g_param_spec_boolean ("fullscreen",
-                          "Fullscreen",
-                          "Whether window is fullscreened",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_MAXIMIZED_HORIZONTALLY] =
-    g_param_spec_boolean ("maximized-horizontally",
-                          "Maximized horizontally",
-                          "Whether window is maximized horizontally",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_MAXIMIZED_VERTICALLY] =
-    g_param_spec_boolean ("maximized-vertically",
-                          "Maximizing vertically",
-                          "Whether window is maximized vertically",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_MINIMIZED] =
-    g_param_spec_boolean ("minimized",
-                          "Minimizing",
-                          "Whether window is minimized",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_WINDOW_TYPE] =
-    g_param_spec_enum ("window-type",
-                       "Window Type",
-                       "The type of the window",
-                       META_TYPE_WINDOW_TYPE,
-                       META_WINDOW_NORMAL,
-                       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_USER_TIME] =
-    g_param_spec_uint ("user-time",
-                       "User time",
-                       "Timestamp of last user interaction",
-                       0,
-                       G_MAXUINT,
-                       0,
-                       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_DEMANDS_ATTENTION] =
-    g_param_spec_boolean ("demands-attention",
-                          "Demands Attention",
-                          "Whether the window has _NET_WM_STATE_DEMANDS_ATTENTION set",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_URGENT] =
-    g_param_spec_boolean ("urgent",
-                          "Urgent",
-                          "Whether the urgent flag of WM_HINTS is set",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_SKIP_TASKBAR] =
-    g_param_spec_boolean ("skip-taskbar",
-                          "Skip taskbar",
-                          "Whether the skip-taskbar flag of WM_HINTS is set",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_MUTTER_HINTS] =
-    g_param_spec_string ("mutter-hints",
-                         "_MUTTER_HINTS",
-                         "Contents of the _MUTTER_HINTS property of this window",
-                         NULL,
-                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_APPEARS_FOCUSED] =
-    g_param_spec_boolean ("appears-focused",
-                          "Appears focused",
-                          "Whether the window is drawn as being focused",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_RESIZEABLE] =
-    g_param_spec_boolean ("resizeable",
-                          "Resizeable",
-                          "Whether the window can be resized",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_ABOVE] =
-    g_param_spec_boolean ("above",
-                          "Above",
-                          "Whether the window is shown as always-on-top",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_WM_CLASS] =
-    g_param_spec_string ("wm-class",
-                         "WM_CLASS",
-                         "Contents of the WM_CLASS property of this window",
-                         NULL,
-                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_GTK_APPLICATION_ID] =
-    g_param_spec_string ("gtk-application-id",
-                         "_GTK_APPLICATION_ID",
-                         "Contents of the _GTK_APPLICATION_ID property of this window",
-                         NULL,
-                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_GTK_UNIQUE_BUS_NAME] =
-    g_param_spec_string ("gtk-unique-bus-name",
-                         "_GTK_UNIQUE_BUS_NAME",
-                         "Contents of the _GTK_UNIQUE_BUS_NAME property of this window",
-                         NULL,
-                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_GTK_APPLICATION_OBJECT_PATH] =
-    g_param_spec_string ("gtk-application-object-path",
-                         "_GTK_APPLICATION_OBJECT_PATH",
-                         "Contents of the _GTK_APPLICATION_OBJECT_PATH property of this window",
-                         NULL,
-                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_GTK_WINDOW_OBJECT_PATH] =
-    g_param_spec_string ("gtk-window-object-path",
-                         "_GTK_WINDOW_OBJECT_PATH",
-                         "Contents of the _GTK_WINDOW_OBJECT_PATH property of this window",
-                         NULL,
-                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_GTK_APP_MENU_OBJECT_PATH] =
-    g_param_spec_string ("gtk-app-menu-object-path",
-                         "_GTK_APP_MENU_OBJECT_PATH",
-                         "Contents of the _GTK_APP_MENU_OBJECT_PATH property of this window",
-                         NULL,
-                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_GTK_MENUBAR_OBJECT_PATH] =
-    g_param_spec_string ("gtk-menubar-object-path",
-                         "_GTK_MENUBAR_OBJECT_PATH",
-                         "Contents of the _GTK_MENUBAR_OBJECT_PATH property of this window",
-                         NULL,
-                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-  obj_props[PROP_ON_ALL_WORKSPACES] =
-    g_param_spec_boolean ("on-all-workspaces",
-                          "On all workspaces",
-                          "Whether the window is set to appear on all workspaces",
-                          FALSE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  /* If the window is a transient for the dock or desktop, don't
+   * leave show desktop mode when the window opens. That's
+   * so you can e.g. hide all windows, manipulate a file on
+   * the desktop via a dialog, then unshow windows again.
+   */
+  is_desktop_or_dock = FALSE;
+  is_desktop_or_dock_foreach (window,
+                              &is_desktop_or_dock);
 
-  obj_props[PROP_IS_ALIVE] =
-    g_param_spec_boolean ("is-alive",
-                          "Is alive",
-                          "Whether the window responds to pings",
-                          TRUE,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  meta_window_foreach_ancestor (window, is_desktop_or_dock_foreach,
+                                &is_desktop_or_dock);
 
-  g_object_class_install_properties (object_class, PROP_LAST, obj_props);
+  if (!is_desktop_or_dock)
+    {
+      meta_workspace_manager_minimize_all_on_active_workspace_except (workspace_manager,
+                                                                      window);
+      meta_workspace_manager_unshow_desktop (workspace_manager);
+    }
+}
 
-  window_signals[WORKSPACE_CHANGED] =
-    g_signal_new ("workspace-changed",
-                  G_TYPE_FROM_CLASS (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
+gboolean
+meta_window_should_attach_to_parent (MetaWindow *window)
+{
+  MetaWindow *parent;
 
-  window_signals[FOCUS] =
-    g_signal_new ("focus",
-                  G_TYPE_FROM_CLASS (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
+  if (!meta_prefs_get_attach_modal_dialogs () ||
+      window->type != META_WINDOW_MODAL_DIALOG)
+    return FALSE;
 
-  window_signals[RAISED] =
-    g_signal_new ("raised",
-                  G_TYPE_FROM_CLASS (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
-
-  window_signals[UNMANAGING] =
-    g_signal_new ("unmanaging",
-                  G_TYPE_FROM_CLASS (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
-
-  window_signals[UNMANAGED] =
-    g_signal_new ("unmanaged",
-                  G_TYPE_FROM_CLASS (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
-
-  /**
-   * MetaWindow::position-changed:
-   * @window: a #MetaWindow
-   *
-   * This is emitted when the position of a window might
-   * have changed. Specifically, this is emitted when the
-   * position of the toplevel window has changed, or when
-   * the position of the client window has changed.
-   */
-  window_signals[POSITION_CHANGED] =
-    g_signal_new ("position-changed",
-                  G_TYPE_FROM_CLASS (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
-
-  /**
-   * MetaWindow::shown:
-   * @window: a #MetaWindow
-   *
-   * This is emitted after a window has been shown.
-   */
-  window_signals[SHOWN] =
-    g_signal_new ("shown",
-                  G_TYPE_FROM_CLASS (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
-
-  /**
-   * MetaWindow::size-changed:
-   * @window: a #MetaWindow
-   *
-   * This is emitted when the size of a window might
-   * have changed. Specifically, this is emitted when the
-   * size of the toplevel window has changed, or when the
-   * size of the client window has changed.
-   */
-  window_signals[SIZE_CHANGED] =
-    g_signal_new ("size-changed",
-                  G_TYPE_FROM_CLASS (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
-}
-
-static void
-meta_window_init (MetaWindow *self)
-{
-  self->stamp = next_window_stamp++;
-  meta_prefs_add_listener (prefs_changed_callback, self);
-  self->is_alive = TRUE;
-}
-
-static gboolean
-is_desktop_or_dock_foreach (MetaWindow *window,
-                            void       *data)
-{
-  gboolean *result = data;
-
-  *result =
-    window->type == META_WINDOW_DESKTOP ||
-    window->type == META_WINDOW_DOCK ||
-    window->skip_from_window_list;
-  if (*result)
-    return FALSE; /* stop as soon as we find one */
-  else
-    return TRUE;
-}
-
-/* window is the window that's newly mapped provoking
- * the possible change
- */
-static void
-maybe_leave_show_desktop_mode (MetaWindow *window)
-{
-  MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
-  gboolean is_desktop_or_dock;
-
-  if (!workspace_manager->active_workspace->showing_desktop)
-    return;
-
-  /* If the window is a transient for the dock or desktop, don't
-   * leave show desktop mode when the window opens. That's
-   * so you can e.g. hide all windows, manipulate a file on
-   * the desktop via a dialog, then unshow windows again.
-   */
-  is_desktop_or_dock = FALSE;
-  is_desktop_or_dock_foreach (window,
-                              &is_desktop_or_dock);
-
-  meta_window_foreach_ancestor (window, is_desktop_or_dock_foreach,
-                                &is_desktop_or_dock);
-
-  if (!is_desktop_or_dock)
-    {
-      meta_workspace_manager_minimize_all_on_active_workspace_except (workspace_manager,
-                                                                      window);
-      meta_workspace_manager_unshow_desktop (workspace_manager);
-    }
-}
-
-gboolean
-meta_window_should_attach_to_parent (MetaWindow *window)
-{
-  MetaWindow *parent;
-
-  if (!meta_prefs_get_attach_modal_dialogs () ||
-      window->type != META_WINDOW_MODAL_DIALOG)
-    return FALSE;
-
-  parent = meta_window_get_transient_for (window);
-  if (!parent)
-    return FALSE;
+  parent = meta_window_get_transient_for (window);
+  if (!parent)
+    return FALSE;
 
   switch (parent->type)
     {
@@ -955,54 +710,21 @@ meta_window_manage (MetaWindow *window)
   META_WINDOW_GET_CLASS (window)->manage (window);
 }
 
-MetaWindow *
-_meta_window_shared_new (MetaDisplay         *display,
-                         MetaWindowClientType client_type,
-                         MetaWaylandSurface  *surface,
-                         Window               xwindow,
-                         gulong               existing_wm_state,
-                         MetaCompEffect       effect,
-                         XWindowAttributes   *attrs)
+static void
+meta_window_constructed (GObject *object)
 {
+  MetaWindow *window = META_WINDOW (object);
+  MetaDisplay *display = window->display;
   MetaContext *context = meta_display_get_context (display);
   MetaBackend *backend = meta_context_get_backend (context);
   MetaWorkspaceManager *workspace_manager = display->workspace_manager;
-  MetaWindow *window;
-
-  COGL_TRACE_BEGIN_SCOPED (MetaWindowSharedNew,
-                           "Window (new)");
-
-  g_assert (attrs != NULL);
 
-  meta_verbose ("attrs->map_state = %d (%s)",
-                attrs->map_state,
-                (attrs->map_state == IsUnmapped) ?
-                "IsUnmapped" :
-                (attrs->map_state == IsViewable) ?
-                "IsViewable" :
-                (attrs->map_state == IsUnviewable) ?
-                "IsUnviewable" :
-                "(unknown)");
-
-  if (client_type == META_WINDOW_CLIENT_TYPE_X11 && !meta_is_wayland_compositor ())
-    window = g_object_new (META_TYPE_WINDOW_X11, NULL);
-#ifdef HAVE_WAYLAND
-  else if (client_type == META_WINDOW_CLIENT_TYPE_X11)
-    window = g_object_new (META_TYPE_WINDOW_XWAYLAND, NULL);
-  else if (client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
-    window = g_object_new (META_TYPE_WINDOW_WAYLAND, NULL);
-#endif
-  else
-    g_assert_not_reached ();
+  COGL_TRACE_BEGIN_SCOPED (MetaWindowSharedInit,
+                           "Window (init)");
 
   window->constructing = TRUE;
 
-  window->client_type = client_type;
-  window->surface = surface;
-  window->xwindow = xwindow;
-
-  window->display = display;
-  meta_display_register_stamp (window->display, &window->stamp, window);
+  meta_display_register_stamp (display, &window->stamp, window);
 
   window->workspace = NULL;
 
@@ -1014,21 +736,10 @@ _meta_window_shared_new (MetaDisplay         *display,
   meta_window_update_sandboxed_app_id (window);
   meta_window_update_desc (window);
 
-  window->override_redirect = attrs->override_redirect;
 
   /* avoid tons of stack updates */
-  meta_stack_freeze (window->display->stack);
+  meta_stack_freeze (display->stack);
 
-  window->rect.x = attrs->x;
-  window->rect.y = attrs->y;
-  window->rect.width = attrs->width;
-  window->rect.height = attrs->height;
-
-  /* size_hints are the "request" */
-  window->size_hints.x = attrs->x;
-  window->size_hints.y = attrs->y;
-  window->size_hints.width = attrs->width;
-  window->size_hints.height = attrs->height;
   /* initialize the remaining size_hints as if size_hints.flags were zero */
   meta_set_normal_hints (window, NULL);
 
@@ -1037,9 +748,6 @@ _meta_window_shared_new (MetaDisplay         *display,
   window->saved_rect_fullscreen = window->rect;
   window->unconstrained_rect = window->rect;
 
-  window->depth = attrs->depth;
-  window->xvisual = attrs->visual;
-
   window->title = NULL;
 
   window->frame = NULL;
@@ -1065,10 +773,8 @@ _meta_window_shared_new (MetaDisplay         *display,
   window->minimized = FALSE;
   window->tab_unminimized = FALSE;
   window->iconic = FALSE;
-  window->mapped = attrs->map_state != IsUnmapped;
   window->known_to_compositor = FALSE;
   window->visible_to_compositor = FALSE;
-  window->pending_compositor_effect = effect;
   /* if already mapped, no need to worry about focus-on-first-time-showing */
   window->showing_for_first_time = !window->mapped;
   /* if already mapped we don't want to do the placement thing;
@@ -1101,18 +807,6 @@ _meta_window_shared_new (MetaDisplay         *display,
   window->mwm_has_move_func = TRUE;
   window->mwm_has_resize_func = TRUE;
 
-  switch (client_type)
-    {
-    case META_WINDOW_CLIENT_TYPE_X11:
-      window->decorated = TRUE;
-      window->hidden = FALSE;
-      break;
-    case META_WINDOW_CLIENT_TYPE_WAYLAND:
-      window->decorated = FALSE;
-      window->hidden = TRUE;
-      break;
-    }
-
   window->has_close_func = TRUE;
   window->has_minimize_func = TRUE;
   window->has_maximize_func = TRUE;
@@ -1199,23 +893,10 @@ _meta_window_shared_new (MetaDisplay         *display,
       meta_verbose ("Window %s asked to start out minimized", window->desc);
     }
 
-  if (existing_wm_state == IconicState)
-    {
-      /* WM_STATE said minimized */
-      window->minimized = TRUE;
-      meta_verbose ("Window %s had preexisting WM_STATE = IconicState, minimizing",
-                    window->desc);
-
-      /* Assume window was previously placed, though perhaps it's
-       * been iconic its whole life, we have no way of knowing.
-       */
-      window->placed = TRUE;
-    }
-
   /* Apply any window attributes such as initial workspace
    * based on startup notification
    */
-  meta_display_apply_startup_properties (window->display, window);
+  meta_display_apply_startup_properties (display, window);
 
   /* Try to get a "launch timestamp" for the window.  If the window is
    * a transient, we'd like to be able to get a last-usage timestamp
@@ -1239,7 +920,7 @@ _meta_window_shared_new (MetaDisplay         *display,
        * being recorded as a fallback for potential transients
        */
       window->net_wm_user_time =
-        meta_display_get_current_time_roundtrip (window->display);
+        meta_display_get_current_time_roundtrip (display);
   }
 
   window->attached = meta_window_should_attach_to_parent (window);
@@ -1347,8 +1028,7 @@ _meta_window_shared_new (MetaDisplay         *display,
    * means restacking it.
    */
   if (meta_window_is_stackable (window))
-    meta_stack_add (window->display->stack,
-                    window);
+    meta_stack_add (display->stack, window);
   else if (window->override_redirect)
     window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */
 
@@ -1361,18 +1041,18 @@ _meta_window_shared_new (MetaDisplay         *display,
       set_net_wm_state (window);
     }
 
-  meta_compositor_add_window (window->display->compositor, window);
+  meta_compositor_add_window (display->compositor, window);
   window->known_to_compositor = TRUE;
 
   /* Sync stack changes */
-  meta_stack_thaw (window->display->stack);
+  meta_stack_thaw (display->stack);
 
   /* Usually the we'll have queued a stack sync anyways, because we've
    * added a new frame window or restacked. But if an undecorated
    * window is mapped, already stacked in the right place, then we
    * might need to do this explicitly.
    */
-  meta_stack_tracker_queue_sync_stack (window->display->stack_tracker);
+  meta_stack_tracker_queue_sync_stack (display->stack_tracker);
 
   /* disable show desktop mode unless we're a desktop component */
   maybe_leave_show_desktop_mode (window);
@@ -1404,9 +1084,7 @@ _meta_window_shared_new (MetaDisplay         *display,
   meta_display_notify_window_created (display, window);
 
   if (window->wm_state_demands_attention)
-    g_signal_emit_by_name (window->display, "window-demands-attention", window);
-
-  return window;
+    g_signal_emit_by_name (display, "window-demands-attention", window);
 }
 
 static gboolean
@@ -1427,6 +1105,311 @@ detach_foreach_func (MetaWindow *window,
   return TRUE;
 }
 
+static void
+meta_window_class_init (MetaWindowClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = meta_window_finalize;
+  object_class->constructed = meta_window_constructed;
+
+  object_class->get_property = meta_window_get_property;
+  object_class->set_property = meta_window_set_property;
+
+  klass->grab_op_began = meta_window_real_grab_op_began;
+  klass->grab_op_ended = meta_window_real_grab_op_ended;
+  klass->current_workspace_changed = meta_window_real_current_workspace_changed;
+  klass->update_struts = meta_window_real_update_struts;
+  klass->get_default_skip_hints = meta_window_real_get_default_skip_hints;
+  klass->get_client_pid = meta_window_real_get_client_pid;
+
+  obj_props[PROP_TITLE] =
+    g_param_spec_string ("title",
+                         "Title",
+                         "The title of the window",
+                         NULL,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_ICON] =
+    g_param_spec_pointer ("icon",
+                          "Icon",
+                          "Normal icon, usually 96x96 pixels",
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_MINI_ICON] =
+    g_param_spec_pointer ("mini-icon",
+                          "Mini Icon",
+                          "Mini icon, usually 16x16 pixels",
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_DECORATED] =
+    g_param_spec_boolean ("decorated",
+                          "Decorated",
+                          "Whether window is decorated",
+                          TRUE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_FULLSCREEN] =
+    g_param_spec_boolean ("fullscreen",
+                          "Fullscreen",
+                          "Whether window is fullscreened",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_MAXIMIZED_HORIZONTALLY] =
+    g_param_spec_boolean ("maximized-horizontally",
+                          "Maximized horizontally",
+                          "Whether window is maximized horizontally",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_MAXIMIZED_VERTICALLY] =
+    g_param_spec_boolean ("maximized-vertically",
+                          "Maximizing vertically",
+                          "Whether window is maximized vertically",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_MINIMIZED] =
+    g_param_spec_boolean ("minimized",
+                          "Minimizing",
+                          "Whether window is minimized",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_WINDOW_TYPE] =
+    g_param_spec_enum ("window-type",
+                       "Window Type",
+                       "The type of the window",
+                       META_TYPE_WINDOW_TYPE,
+                       META_WINDOW_NORMAL,
+                       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_USER_TIME] =
+    g_param_spec_uint ("user-time",
+                       "User time",
+                       "Timestamp of last user interaction",
+                       0,
+                       G_MAXUINT,
+                       0,
+                       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_DEMANDS_ATTENTION] =
+    g_param_spec_boolean ("demands-attention",
+                          "Demands Attention",
+                          "Whether the window has _NET_WM_STATE_DEMANDS_ATTENTION set",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_URGENT] =
+    g_param_spec_boolean ("urgent",
+                          "Urgent",
+                          "Whether the urgent flag of WM_HINTS is set",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_SKIP_TASKBAR] =
+    g_param_spec_boolean ("skip-taskbar",
+                          "Skip taskbar",
+                          "Whether the skip-taskbar flag of WM_HINTS is set",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_MUTTER_HINTS] =
+    g_param_spec_string ("mutter-hints",
+                         "_MUTTER_HINTS",
+                         "Contents of the _MUTTER_HINTS property of this window",
+                         NULL,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_APPEARS_FOCUSED] =
+    g_param_spec_boolean ("appears-focused",
+                          "Appears focused",
+                          "Whether the window is drawn as being focused",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_RESIZEABLE] =
+    g_param_spec_boolean ("resizeable",
+                          "Resizeable",
+                          "Whether the window can be resized",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_ABOVE] =
+    g_param_spec_boolean ("above",
+                          "Above",
+                          "Whether the window is shown as always-on-top",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_WM_CLASS] =
+    g_param_spec_string ("wm-class",
+                         "WM_CLASS",
+                         "Contents of the WM_CLASS property of this window",
+                         NULL,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_GTK_APPLICATION_ID] =
+    g_param_spec_string ("gtk-application-id",
+                         "_GTK_APPLICATION_ID",
+                         "Contents of the _GTK_APPLICATION_ID property of this window",
+                         NULL,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_GTK_UNIQUE_BUS_NAME] =
+    g_param_spec_string ("gtk-unique-bus-name",
+                         "_GTK_UNIQUE_BUS_NAME",
+                         "Contents of the _GTK_UNIQUE_BUS_NAME property of this window",
+                         NULL,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_GTK_APPLICATION_OBJECT_PATH] =
+    g_param_spec_string ("gtk-application-object-path",
+                         "_GTK_APPLICATION_OBJECT_PATH",
+                         "Contents of the _GTK_APPLICATION_OBJECT_PATH property of this window",
+                         NULL,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_GTK_WINDOW_OBJECT_PATH] =
+    g_param_spec_string ("gtk-window-object-path",
+                         "_GTK_WINDOW_OBJECT_PATH",
+                         "Contents of the _GTK_WINDOW_OBJECT_PATH property of this window",
+                         NULL,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_GTK_APP_MENU_OBJECT_PATH] =
+    g_param_spec_string ("gtk-app-menu-object-path",
+                         "_GTK_APP_MENU_OBJECT_PATH",
+                         "Contents of the _GTK_APP_MENU_OBJECT_PATH property of this window",
+                         NULL,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_GTK_MENUBAR_OBJECT_PATH] =
+    g_param_spec_string ("gtk-menubar-object-path",
+                         "_GTK_MENUBAR_OBJECT_PATH",
+                         "Contents of the _GTK_MENUBAR_OBJECT_PATH property of this window",
+                         NULL,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_ON_ALL_WORKSPACES] =
+    g_param_spec_boolean ("on-all-workspaces",
+                          "On all workspaces",
+                          "Whether the window is set to appear on all workspaces",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+  obj_props[PROP_IS_ALIVE] =
+    g_param_spec_boolean ("is-alive",
+                          "Is alive",
+                          "Whether the window responds to pings",
+                          TRUE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+  obj_props[PROP_DISPLAY] =
+    g_param_spec_object ("display",
+                         "Display",
+                         "The display the window is attached to",
+                         META_TYPE_DISPLAY,
+                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+  obj_props[PROP_EFFECT] =
+    g_param_spec_int ("effect",
+                      "Compositor effect",
+                      "The compositor effect",
+                      META_COMP_EFFECT_CREATE,
+                      META_COMP_EFFECT_NONE,
+                      META_COMP_EFFECT_NONE,
+                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+  obj_props[PROP_SURFACE] =
+    g_param_spec_pointer ("surface",
+                          "Surface",
+                          "The corresponding Wayland surface",
+                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READABLE);
+
+  obj_props[PROP_XWINDOW] =
+    g_param_spec_ulong ("xwindow",
+                        "X Window",
+                        "The corresponding X Window",
+                        0, G_MAXULONG, 0,
+                        G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class, PROP_LAST, obj_props);
+
+  window_signals[WORKSPACE_CHANGED] =
+    g_signal_new ("workspace-changed",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  window_signals[FOCUS] =
+    g_signal_new ("focus",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  window_signals[RAISED] =
+    g_signal_new ("raised",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  window_signals[UNMANAGING] =
+    g_signal_new ("unmanaging",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  window_signals[UNMANAGED] =
+    g_signal_new ("unmanaged",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  /**
+   * MetaWindow::position-changed:
+   * @window: a #MetaWindow
+   *
+   * This is emitted when the position of a window might
+   * have changed. Specifically, this is emitted when the
+   * position of the toplevel window has changed, or when
+   * the position of the client window has changed.
+   */
+  window_signals[POSITION_CHANGED] =
+    g_signal_new ("position-changed",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  /**
+   * MetaWindow::shown:
+   * @window: a #MetaWindow
+   *
+   * This is emitted after a window has been shown.
+   */
+  window_signals[SHOWN] =
+    g_signal_new ("shown",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  /**
+   * MetaWindow::size-changed:
+   * @window: a #MetaWindow
+   *
+   * This is emitted when the size of a window might
+   * have changed. Specifically, this is emitted when the
+   * size of the toplevel window has changed, or when the
+   * size of the client window has changed.
+   */
+  window_signals[SIZE_CHANGED] =
+    g_signal_new ("size-changed",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+}
+
+static void
+meta_window_init (MetaWindow *window)
+{
+  window->stamp = next_window_stamp++;
+  meta_prefs_add_listener (prefs_changed_callback, window);
+  window->is_alive = TRUE;
+}
+
 void
 meta_window_unmanage (MetaWindow  *window,
                       guint32      timestamp)
diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c
index 2b389bfbf8..c6f042d8b2 100644
--- a/src/wayland/meta-window-wayland.c
+++ b/src/wayland/meta-window-wayland.c
@@ -728,6 +728,33 @@ meta_window_wayland_unmap (MetaWindow *window)
 {
 }
 
+static void
+meta_window_wayland_constructed (GObject *object)
+{
+  MetaWindow *window = META_WINDOW (object);
+  window->client_type = META_WINDOW_CLIENT_TYPE_WAYLAND;
+
+  window->override_redirect = FALSE;
+  window->rect.x = 0;
+  window->rect.y = 0;
+  window->rect.width = 0;
+  window->rect.height = 0;
+  /* size_hints are the "request" */
+  window->size_hints.x = 0;
+  window->size_hints.y = 0;
+  window->size_hints.width = 0;
+  window->size_hints.height = 0;
+
+  window->depth = 24;
+  window->xvisual = NULL;
+
+  window->mapped = FALSE;
+
+  window->decorated = FALSE;
+  window->hidden = TRUE;
+  G_OBJECT_CLASS (meta_window_wayland_parent_class)->constructed (object);
+}
+
 static void
 meta_window_wayland_finalize (GObject *object)
 {
@@ -746,6 +773,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
   MetaWindowClass *window_class = META_WINDOW_CLASS (klass);
 
   object_class->finalize = meta_window_wayland_finalize;
+  object_class->constructed = meta_window_wayland_constructed;
 
   window_class->manage = meta_window_wayland_manage;
   window_class->unmanage = meta_window_wayland_unmanage;
@@ -775,31 +803,14 @@ MetaWindow *
 meta_window_wayland_new (MetaDisplay        *display,
                          MetaWaylandSurface *surface)
 {
-  XWindowAttributes attrs = { 0 };
   MetaWindowWayland *wl_window;
   MetaWindow *window;
 
-  /*
-   * Set attributes used by _meta_window_shared_new, don't bother trying to fake
-   * X11 window attributes with the rest, since they'll be ignored anyway.
-   */
-  attrs.x = 0;
-  attrs.y = 0;
-  attrs.width = 0;
-  attrs.height = 0;
-  attrs.depth = 24;
-  attrs.visual = NULL;
-  attrs.map_state = IsUnmapped;
-  attrs.override_redirect = False;
-
-  window = _meta_window_shared_new (display,
-                                    META_WINDOW_CLIENT_TYPE_WAYLAND,
-                                    surface,
-                                    None,
-                                    WithdrawnState,
-                                    META_COMP_EFFECT_CREATE,
-                                    &attrs);
-
+  window = g_object_new (META_TYPE_WINDOW_WAYLAND,
+                         "display", display,
+                         "effect", META_COMP_EFFECT_CREATE,
+                         "surface", surface,
+                         NULL);
   wl_window = META_WINDOW_WAYLAND (window);
   set_geometry_scale_for_window (wl_window, wl_window->geometry_scale);
 
diff --git a/src/x11/window-x11-private.h b/src/x11/window-x11-private.h
index 7e5a72d034..20cb445282 100644
--- a/src/x11/window-x11-private.h
+++ b/src/x11/window-x11-private.h
@@ -59,6 +59,8 @@ struct _MetaWindowX11Private
 
   Atom type_atom;
 
+  XWindowAttributes attributes;
+
   /* Requested geometry */
   int border_width;
 
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index 617a1dfaa0..86935f492c 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -47,6 +47,11 @@
 #include "meta/meta-later.h"
 #include "meta/meta-x11-errors.h"
 #include "meta/prefs.h"
+
+#ifdef HAVE_XWAYLAND
+#include "wayland/meta-window-xwayland.h"
+#endif
+
 #include "x11/meta-x11-display-private.h"
 #include "x11/session.h"
 #include "x11/window-props.h"
@@ -68,6 +73,17 @@ enum _MetaGtkEdgeConstraints
 
 G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW)
 
+enum
+{
+  PROP_0,
+
+  PROP_ATTRIBUTES,
+
+  PROP_LAST,
+};
+
+static GParamSpec *obj_props[PROP_LAST];
+
 static void
 meta_window_x11_maybe_focus_delayed (MetaWindow *window,
                                      GQueue     *other_focus_candidates,
@@ -2133,6 +2149,89 @@ meta_window_x11_is_focus_async (MetaWindow *window)
   return !window->input && priv->wm_take_focus;
 }
 
+static void
+meta_window_x11_constructed (GObject *object)
+{
+  MetaWindow *window = META_WINDOW (object);
+  MetaWindowX11 *x11_window = META_WINDOW_X11 (object);
+  MetaWindowX11Private *priv = meta_window_x11_get_instance_private (x11_window);
+  XWindowAttributes attrs = priv->attributes;
+
+  meta_verbose ("attrs->map_state = %d (%s)",
+                attrs.map_state,
+                (attrs.map_state == IsUnmapped) ?
+                "IsUnmapped" :
+                (attrs.map_state == IsViewable) ?
+                "IsViewable" :
+                (attrs.map_state == IsUnviewable) ?
+                "IsUnviewable" :
+                "(unknown)");
+
+  window->client_type = META_WINDOW_CLIENT_TYPE_X11;
+  window->override_redirect = attrs.override_redirect;
+
+  window->rect.x = attrs.x;
+  window->rect.y = attrs.y;
+  window->rect.width = attrs.width;
+  window->rect.height = attrs.height;
+
+  /* size_hints are the "request" */
+  window->size_hints.x = attrs.x;
+  window->size_hints.y = attrs.y;
+  window->size_hints.width = attrs.width;
+  window->size_hints.height = attrs.height;
+
+  window->depth = attrs.depth;
+  window->xvisual = attrs.visual;
+  window->mapped = attrs.map_state != IsUnmapped;
+
+  window->decorated = TRUE;
+  window->hidden = FALSE;
+  priv->border_width = attrs.border_width;
+
+  G_OBJECT_CLASS (meta_window_x11_parent_class)->constructed (object);
+}
+
+static void
+meta_window_x11_get_property (GObject     *object,
+                              guint        prop_id,
+                              GValue      *value,
+                              GParamSpec  *pspec)
+{
+  MetaWindowX11 *win = META_WINDOW_X11 (object);
+  MetaWindowX11Private *priv = meta_window_x11_get_instance_private (win);
+
+  switch (prop_id)
+    {
+    case PROP_ATTRIBUTES:
+      g_value_set_pointer (value, &priv->attributes);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+meta_window_x11_set_property (GObject       *object,
+                              guint          prop_id,
+                              const GValue  *value,
+                              GParamSpec    *pspec)
+{
+  MetaWindowX11 *win = META_WINDOW_X11 (object);
+  MetaWindowX11Private *priv = meta_window_x11_get_instance_private (win);
+
+  switch (prop_id)
+    {
+    case PROP_ATTRIBUTES:
+      priv->attributes = *((XWindowAttributes *) g_value_get_pointer (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
 static void
 meta_window_x11_dispose (GObject *object)
 {
@@ -2161,7 +2260,10 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   MetaWindowClass *window_class = META_WINDOW_CLASS (klass);
 
+  object_class->get_property = meta_window_x11_get_property;
+  object_class->set_property = meta_window_x11_set_property;
   object_class->dispose = meta_window_x11_dispose;
+  object_class->constructed = meta_window_x11_constructed;
 
   window_class->manage = meta_window_x11_manage;
   window_class->unmanage = meta_window_x11_unmanage;
@@ -2194,6 +2296,14 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
   klass->freeze_commits = meta_window_x11_impl_freeze_commits;
   klass->thaw_commits = meta_window_x11_impl_thaw_commits;
   klass->always_update_shape = meta_window_x11_impl_always_update_shape;
+
+  obj_props[PROP_ATTRIBUTES] =
+    g_param_spec_pointer ("attributes",
+                          "Attributes",
+                          "The corresponding attributes",
+                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class, PROP_LAST, obj_props);
 }
 
 void
@@ -3769,18 +3879,41 @@ meta_window_x11_new (MetaDisplay       *display,
       goto error;
     }
 
-  window = _meta_window_shared_new (display,
-                                    META_WINDOW_CLIENT_TYPE_X11,
-                                    NULL,
-                                    xwindow,
-                                    existing_wm_state,
-                                    effect,
-                                    &attrs);
+#ifdef HAVE_XWAYLAND
+  if (meta_is_wayland_compositor ())
+    {
+      window = g_object_new (META_TYPE_WINDOW_XWAYLAND,
+                             "display", display,
+                             "effect", effect,
+                             "attributes", &attrs,
+                             "xwindow", xwindow,
+                             NULL);    
+    }
+  else
+#else
+    {
+      window = g_object_new (META_TYPE_WINDOW_X11,
+                             "display", display,
+                             "effect", effect,
+                             "attributes", &attrs,
+                             "xwindow", xwindow,
+                             NULL);
+    }
+#endif
+  if (existing_wm_state == IconicState)
+    {
+      /* WM_STATE said minimized */
+      window->minimized = TRUE;
+      meta_verbose ("Window %s had preexisting WM_STATE = IconicState, minimizing",
+                    window->desc);
 
-  MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
-  MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
+      /* Assume window was previously placed, though perhaps it's
+       * been iconic its whole life, we have no way of knowing.
+       */
+      window->placed = TRUE;
+    }
 
-  priv->border_width = attrs.border_width;
+  MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
 
   if (!window->override_redirect)
     meta_window_x11_update_icon (window_x11, TRUE);


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