diff --git a/src/Makefile.am b/src/Makefile.am
index b81c6ec51..53f6f7af4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -163,6 +163,8 @@ libmutter_wayland_la_SOURCES = \
core/util-private.h \
core/window-props.c \
core/window-props.h \
+ core/window-x11.c \
+ core/window-x11.h \
core/window.c \
core/window-private.h \
meta/window.h \
diff --git a/src/core/display.c b/src/core/display.c
index 7376f0eb3..24365f3b0 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -36,6 +36,7 @@
#include
#include "screen-private.h"
#include "window-private.h"
+#include "window-x11.h"
#include "window-props.h"
#include "group-props.h"
#include "frame.h"
@@ -1581,7 +1582,7 @@ handle_net_restack_window (MetaDisplay* display,
*
* Also, unconditionally following these is REALLY stupid--we should
* combine this code with the stuff in
- * meta_window_configure_request() which is smart about whether to
+ * meta_window_x11_configure_request() which is smart about whether to
* follow the request or do something else (though not smart enough
* and is also too stupid to handle the sibling stuff).
*/
@@ -2692,9 +2693,9 @@ handle_other_xevent (MetaDisplay *display,
XShapeEvent *sev = (XShapeEvent*) event;
if (sev->kind == ShapeBounding)
- meta_window_update_shape_region_x11 (window);
+ meta_window_x11_update_shape_region (window);
else if (sev->kind == ShapeInput)
- meta_window_update_input_region_x11 (window);
+ meta_window_x11_update_input_region (window);
}
else
{
@@ -2903,7 +2904,7 @@ handle_other_xevent (MetaDisplay *display,
else
{
if (!frame_was_receiver)
- meta_window_configure_request (window, event);
+ meta_window_x11_configure_request (window, event);
}
break;
case GravityNotify:
@@ -2920,9 +2921,9 @@ handle_other_xevent (MetaDisplay *display,
MetaScreen *screen;
if (window && !frame_was_receiver)
- meta_window_property_notify (window, event);
+ meta_window_x11_property_notify (window, event);
else if (property_for_window && !frame_was_receiver)
- meta_window_property_notify (property_for_window, event);
+ meta_window_x11_property_notify (property_for_window, event);
group = meta_display_lookup_group (display,
event->xproperty.window);
@@ -2993,7 +2994,7 @@ handle_other_xevent (MetaDisplay *display,
if (window)
{
if (!frame_was_receiver)
- meta_window_client_message (window, event);
+ meta_window_x11_client_message (window, event);
}
else
{
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 7c09e6835..679719b45 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -615,12 +615,6 @@ void meta_window_move_resize_wayland (MetaWindow *window,
int height,
int dx,
int dy);
-gboolean meta_window_configure_request (MetaWindow *window,
- XEvent *event);
-gboolean meta_window_property_notify (MetaWindow *window,
- XEvent *event);
-gboolean meta_window_client_message (MetaWindow *window,
- XEvent *event);
void meta_window_set_focused_internal (MetaWindow *window,
gboolean focused);
@@ -697,8 +691,6 @@ void meta_window_set_user_time (MetaWindow *window,
void meta_window_update_icon_now (MetaWindow *window);
-void meta_window_update_role (MetaWindow *window);
-void meta_window_update_net_wm_type (MetaWindow *window);
void meta_window_update_for_monitors_changed (MetaWindow *window);
void meta_window_update_on_all_workspaces (MetaWindow *window);
@@ -712,10 +704,6 @@ void meta_window_compute_tile_match (MetaWindow *window);
gboolean meta_window_updates_are_frozen (MetaWindow *window);
-void meta_window_update_opaque_region_x11 (MetaWindow *window);
-void meta_window_update_input_region_x11 (MetaWindow *window);
-void meta_window_update_shape_region_x11 (MetaWindow *window);
-
void meta_window_set_title (MetaWindow *window,
const char *title);
void meta_window_set_wm_class (MetaWindow *window,
@@ -756,4 +744,9 @@ void meta_window_pong (MetaWindow *window,
guint32 timestamp);
Window meta_window_get_toplevel_xwindow (MetaWindow *window);
+void meta_window_activate_full (MetaWindow *window,
+ guint32 timestamp,
+ MetaClientType source_indication,
+ MetaWorkspace *workspace);
+
#endif
diff --git a/src/core/window-props.c b/src/core/window-props.c
index 6e07d6ef8..ca73bd27b 100644
--- a/src/core/window-props.c
+++ b/src/core/window-props.c
@@ -39,6 +39,7 @@
#include
#include "window-props.h"
+#include "window-x11.h"
#include
#include "xprops.h"
#include "frame.h"
@@ -229,7 +230,7 @@ reload_net_wm_window_type (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
- meta_window_update_net_wm_type (window);
+ meta_window_x11_update_net_wm_type (window);
}
static void
@@ -333,7 +334,7 @@ reload_wm_window_role (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
- meta_window_update_role (window);
+ meta_window_x11_update_role (window);
}
static void
@@ -558,7 +559,7 @@ reload_opaque_region (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
- meta_window_update_opaque_region_x11 (window);
+ meta_window_x11_update_opaque_region (window);
}
static void
diff --git a/src/core/window-x11.c b/src/core/window-x11.c
new file mode 100644
index 000000000..3391a548a
--- /dev/null
+++ b/src/core/window-x11.c
@@ -0,0 +1,1148 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2001 Havoc Pennington, Anders Carlsson
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2003 Rob Adams
+ * Copyright (C) 2004-2006 Elijah Newren
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include "config.h"
+
+#include "window-x11.h"
+
+#include
+#include
+#include /* For display->resource_mask */
+
+#ifdef HAVE_SHAPE
+#include
+#endif
+
+#include
+#include
+#include
+
+#include "window-private.h"
+#include "window-props.h"
+#include "xprops.h"
+
+void
+meta_window_x11_set_net_wm_state (MetaWindow *window)
+{
+ int i;
+ unsigned long data[13];
+
+ i = 0;
+ if (window->shaded)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_SHADED;
+ ++i;
+ }
+ if (window->wm_state_modal)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_MODAL;
+ ++i;
+ }
+ if (window->skip_pager)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_SKIP_PAGER;
+ ++i;
+ }
+ if (window->skip_taskbar)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_SKIP_TASKBAR;
+ ++i;
+ }
+ if (window->maximized_horizontally)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ;
+ ++i;
+ }
+ if (window->maximized_vertically)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_VERT;
+ ++i;
+ }
+ if (window->fullscreen)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_FULLSCREEN;
+ ++i;
+ }
+ if (!meta_window_showing_on_its_workspace (window) || window->shaded)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_HIDDEN;
+ ++i;
+ }
+ if (window->wm_state_above)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_ABOVE;
+ ++i;
+ }
+ if (window->wm_state_below)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_BELOW;
+ ++i;
+ }
+ if (window->wm_state_demands_attention)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION;
+ ++i;
+ }
+ if (window->on_all_workspaces_requested)
+ {
+ data[i] = window->display->atom__NET_WM_STATE_STICKY;
+ ++i;
+ }
+ if (meta_window_appears_focused (window))
+ {
+ data[i] = window->display->atom__NET_WM_STATE_FOCUSED;
+ ++i;
+ }
+
+ meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i);
+
+ meta_error_trap_push (window->display);
+ XChangeProperty (window->display->xdisplay, window->xwindow,
+ window->display->atom__NET_WM_STATE,
+ XA_ATOM,
+ 32, PropModeReplace, (guchar*) data, i);
+ meta_error_trap_pop (window->display);
+
+ if (window->fullscreen)
+ {
+ data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen,
+ window->fullscreen_monitors[0]);
+ data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen,
+ window->fullscreen_monitors[1]);
+ data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen,
+ window->fullscreen_monitors[2]);
+ data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen,
+ window->fullscreen_monitors[3]);
+
+ meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n");
+ meta_error_trap_push (window->display);
+ XChangeProperty (window->display->xdisplay,
+ window->xwindow,
+ window->display->atom__NET_WM_FULLSCREEN_MONITORS,
+ XA_CARDINAL, 32, PropModeReplace,
+ (guchar*) data, 4);
+ meta_error_trap_pop (window->display);
+ }
+}
+
+void
+meta_window_x11_update_net_wm_type (MetaWindow *window)
+{
+ int n_atoms;
+ Atom *atoms;
+ int i;
+
+ window->type_atom = None;
+ n_atoms = 0;
+ atoms = NULL;
+
+ meta_prop_get_atom_list (window->display, window->xwindow,
+ window->display->atom__NET_WM_WINDOW_TYPE,
+ &atoms, &n_atoms);
+
+ i = 0;
+ while (i < n_atoms)
+ {
+ /* We break as soon as we find one we recognize,
+ * supposed to prefer those near the front of the list
+ */
+ if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG ||
+ atoms[i] ==
+ window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP ||
+ atoms[i] ==
+ window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_COMBO ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND ||
+ atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
+ {
+ window->type_atom = atoms[i];
+ break;
+ }
+
+ ++i;
+ }
+
+ meta_XFree (atoms);
+
+ if (meta_is_verbose ())
+ {
+ char *str;
+
+ str = NULL;
+ if (window->type_atom != None)
+ {
+ meta_error_trap_push (window->display);
+ str = XGetAtomName (window->display->xdisplay, window->type_atom);
+ meta_error_trap_pop (window->display);
+ }
+
+ meta_verbose ("Window %s type atom %s\n", window->desc,
+ str ? str : "(none)");
+
+ if (str)
+ meta_XFree (str);
+ }
+
+ meta_window_recalc_window_type (window);
+}
+
+void
+meta_window_x11_update_role (MetaWindow *window)
+{
+ char *str;
+
+ g_return_if_fail (!window->override_redirect);
+
+ if (window->role)
+ g_free (window->role);
+ window->role = NULL;
+
+ if (meta_prop_get_latin1_string (window->display, window->xwindow,
+ window->display->atom_WM_WINDOW_ROLE,
+ &str))
+ {
+ window->role = g_strdup (str);
+ meta_XFree (str);
+ }
+
+ meta_verbose ("Updated role of %s to '%s'\n",
+ window->desc, window->role ? window->role : "null");
+}
+
+static void
+meta_window_set_opaque_region (MetaWindow *window,
+ cairo_region_t *region)
+{
+ g_clear_pointer (&window->opaque_region, cairo_region_destroy);
+
+ if (region != NULL)
+ window->opaque_region = cairo_region_reference (region);
+
+ if (window->display->compositor)
+ meta_compositor_window_shape_changed (window->display->compositor, window);
+}
+
+void
+meta_window_x11_update_opaque_region (MetaWindow *window)
+{
+ cairo_region_t *opaque_region = NULL;
+ gulong *region = NULL;
+ int nitems;
+
+ if (meta_prop_get_cardinal_list (window->display,
+ window->xwindow,
+ window->display->atom__NET_WM_OPAQUE_REGION,
+ ®ion, &nitems))
+ {
+ cairo_rectangle_int_t *rects;
+ int i, rect_index, nrects;
+
+ if (nitems % 4 != 0)
+ {
+ meta_verbose ("_NET_WM_OPAQUE_REGION does not have a list of 4-tuples.");
+ goto out;
+ }
+
+ /* empty region */
+ if (nitems == 0)
+ goto out;
+
+ nrects = nitems / 4;
+
+ rects = g_new (cairo_rectangle_int_t, nrects);
+
+ rect_index = 0;
+ i = 0;
+ while (i < nitems)
+ {
+ cairo_rectangle_int_t *rect = &rects[rect_index];
+
+ rect->x = region[i++];
+ rect->y = region[i++];
+ rect->width = region[i++];
+ rect->height = region[i++];
+
+ rect_index++;
+ }
+
+ opaque_region = cairo_region_create_rectangles (rects, nrects);
+
+ g_free (rects);
+ }
+
+ out:
+ meta_XFree (region);
+
+ meta_window_set_opaque_region (window, opaque_region);
+ cairo_region_destroy (opaque_region);
+}
+
+static cairo_region_t *
+region_create_from_x_rectangles (const XRectangle *rects,
+ int n_rects)
+{
+ int i;
+ cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects);
+
+ for (i = 0; i < n_rects; i ++)
+ {
+ cairo_rects[i].x = rects[i].x;
+ cairo_rects[i].y = rects[i].y;
+ cairo_rects[i].width = rects[i].width;
+ cairo_rects[i].height = rects[i].height;
+ }
+
+ return cairo_region_create_rectangles (cairo_rects, n_rects);
+}
+
+static void
+meta_window_set_input_region (MetaWindow *window,
+ cairo_region_t *region)
+{
+ g_clear_pointer (&window->input_region, cairo_region_destroy);
+
+ if (region != NULL)
+ window->input_region = cairo_region_reference (region);
+
+ if (window->display->compositor)
+ meta_compositor_window_shape_changed (window->display->compositor, window);
+}
+
+void
+meta_window_x11_update_input_region (MetaWindow *window)
+{
+ cairo_region_t *region = NULL;
+
+#ifdef HAVE_SHAPE
+ if (META_DISPLAY_HAS_SHAPE (window->display))
+ {
+ /* Translate the set of XShape rectangles that we
+ * get from the X server to a cairo_region. */
+ XRectangle *rects = NULL;
+ int n_rects, ordering;
+
+ int x_bounding, y_bounding, x_clip, y_clip;
+ unsigned w_bounding, h_bounding, w_clip, h_clip;
+ int bounding_shaped, clip_shaped;
+
+ meta_error_trap_push (window->display);
+ XShapeQueryExtents (window->display->xdisplay, window->xwindow,
+ &bounding_shaped, &x_bounding, &y_bounding,
+ &w_bounding, &h_bounding,
+ &clip_shaped, &x_clip, &y_clip,
+ &w_clip, &h_clip);
+
+ rects = XShapeGetRectangles (window->display->xdisplay,
+ window->xwindow,
+ ShapeInput,
+ &n_rects,
+ &ordering);
+ meta_error_trap_pop (window->display);
+
+ /* XXX: The x shape extension doesn't provide a way to only test if an
+ * input shape has been specified, so we have to query and throw away the
+ * rectangles. */
+ if (rects)
+ {
+ if (n_rects > 1 ||
+ (n_rects == 1 &&
+ (rects[0].x != x_bounding ||
+ rects[1].y != y_bounding ||
+ rects[2].width != w_bounding ||
+ rects[3].height != h_bounding)))
+ region = region_create_from_x_rectangles (rects, n_rects);
+
+ XFree (rects);
+ }
+ }
+#endif /* HAVE_SHAPE */
+
+ if (region != NULL)
+ {
+ cairo_rectangle_int_t client_area;
+
+ client_area.x = 0;
+ client_area.y = 0;
+ client_area.width = window->rect.width;
+ client_area.height = window->rect.height;
+
+ /* The shape we get back from the client may have coordinates
+ * outside of the frame. The X SHAPE Extension requires that
+ * the overall shape the client provides never exceeds the
+ * "bounding rectangle" of the window -- the shape that the
+ * window would have gotten if it was unshaped. In our case,
+ * this is simply the client area.
+ */
+ cairo_region_intersect_rectangle (region, &client_area);
+ }
+
+ meta_window_set_input_region (window, region);
+ cairo_region_destroy (region);
+}
+
+static void
+meta_window_set_shape_region (MetaWindow *window,
+ cairo_region_t *region)
+{
+ g_clear_pointer (&window->shape_region, cairo_region_destroy);
+
+ if (region != NULL)
+ window->shape_region = cairo_region_reference (region);
+
+ if (window->display->compositor)
+ meta_compositor_window_shape_changed (window->display->compositor, window);
+}
+
+void
+meta_window_x11_update_shape_region (MetaWindow *window)
+{
+ cairo_region_t *region = NULL;
+
+#ifdef HAVE_SHAPE
+ if (META_DISPLAY_HAS_SHAPE (window->display))
+ {
+ /* Translate the set of XShape rectangles that we
+ * get from the X server to a cairo_region. */
+ XRectangle *rects = NULL;
+ int n_rects, ordering;
+
+ int x_bounding, y_bounding, x_clip, y_clip;
+ unsigned w_bounding, h_bounding, w_clip, h_clip;
+ int bounding_shaped, clip_shaped;
+
+ meta_error_trap_push (window->display);
+ XShapeQueryExtents (window->display->xdisplay, window->xwindow,
+ &bounding_shaped, &x_bounding, &y_bounding,
+ &w_bounding, &h_bounding,
+ &clip_shaped, &x_clip, &y_clip,
+ &w_clip, &h_clip);
+
+ if (bounding_shaped)
+ {
+ rects = XShapeGetRectangles (window->display->xdisplay,
+ window->xwindow,
+ ShapeBounding,
+ &n_rects,
+ &ordering);
+ }
+ meta_error_trap_pop (window->display);
+
+ if (rects)
+ {
+ region = region_create_from_x_rectangles (rects, n_rects);
+ XFree (rects);
+ }
+ }
+#endif /* HAVE_SHAPE */
+
+ if (region != NULL)
+ {
+ cairo_rectangle_int_t client_area;
+
+ client_area.x = 0;
+ client_area.y = 0;
+ client_area.width = window->rect.width;
+ client_area.height = window->rect.height;
+
+ /* The shape we get back from the client may have coordinates
+ * outside of the frame. The X SHAPE Extension requires that
+ * the overall shape the client provides never exceeds the
+ * "bounding rectangle" of the window -- the shape that the
+ * window would have gotten if it was unshaped. In our case,
+ * this is simply the client area.
+ */
+ cairo_region_intersect_rectangle (region, &client_area);
+ }
+
+ meta_window_set_shape_region (window, region);
+ cairo_region_destroy (region);
+}
+
+/* Generally meta_window_same_application() is a better idea
+ * of "sameness", since it handles the case where multiple apps
+ * want to look like the same app or the same app wants to look
+ * like multiple apps, but in the case of workarounds for legacy
+ * applications (which likely aren't setting the group properly
+ * anyways), it may be desirable to check this as well.
+ */
+static gboolean
+meta_window_same_client (MetaWindow *window,
+ MetaWindow *other_window)
+{
+ int resource_mask = window->display->xdisplay->resource_mask;
+
+ return ((window->xwindow & ~resource_mask) ==
+ (other_window->xwindow & ~resource_mask));
+}
+
+gboolean
+meta_window_x11_configure_request (MetaWindow *window,
+ XEvent *event)
+{
+ /* Note that x, y is the corner of the window border,
+ * and width, height is the size of the window inside
+ * its border, but that we always deny border requests
+ * and give windows a border of 0. But we save the
+ * requested border here.
+ */
+ if (event->xconfigurerequest.value_mask & CWBorderWidth)
+ window->border_width = event->xconfigurerequest.border_width;
+
+ meta_window_move_resize_request(window,
+ event->xconfigurerequest.value_mask,
+ window->size_hints.win_gravity,
+ event->xconfigurerequest.x,
+ event->xconfigurerequest.y,
+ event->xconfigurerequest.width,
+ event->xconfigurerequest.height);
+
+ /* Handle stacking. We only handle raises/lowers, mostly because
+ * stack.c really can't deal with anything else. I guess we'll fix
+ * that if a client turns up that really requires it. Only a very
+ * few clients even require the raise/lower (and in fact all client
+ * attempts to deal with stacking order are essentially broken,
+ * since they have no idea what other clients are involved or how
+ * the stack looks).
+ *
+ * I'm pretty sure no interesting client uses TopIf, BottomIf, or
+ * Opposite anyway, so the only possible missing thing is
+ * Above/Below with a sibling set. For now we just pretend there's
+ * never a sibling set and always do the full raise/lower instead of
+ * the raise-just-above/below-sibling.
+ */
+ if (event->xconfigurerequest.value_mask & CWStackMode)
+ {
+ MetaWindow *active_window;
+ active_window = window->display->focus_window;
+ if (meta_prefs_get_disable_workarounds ())
+ {
+ meta_topic (META_DEBUG_STACK,
+ "%s sent an xconfigure stacking request; this is "
+ "broken behavior and the request is being ignored.\n",
+ window->desc);
+ }
+ else if (active_window &&
+ !meta_window_same_application (window, active_window) &&
+ !meta_window_same_client (window, active_window) &&
+ XSERVER_TIME_IS_BEFORE (window->net_wm_user_time,
+ active_window->net_wm_user_time))
+ {
+ meta_topic (META_DEBUG_STACK,
+ "Ignoring xconfigure stacking request from %s (with "
+ "user_time %u); currently active application is %s (with "
+ "user_time %u).\n",
+ window->desc,
+ window->net_wm_user_time,
+ active_window->desc,
+ active_window->net_wm_user_time);
+ if (event->xconfigurerequest.detail == Above)
+ meta_window_set_demands_attention(window);
+ }
+ else
+ {
+ switch (event->xconfigurerequest.detail)
+ {
+ case Above:
+ meta_window_raise (window);
+ break;
+ case Below:
+ meta_window_lower (window);
+ break;
+ case TopIf:
+ case BottomIf:
+ case Opposite:
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+process_property_notify (MetaWindow *window,
+ XPropertyEvent *event)
+{
+ Window xid = window->xwindow;
+
+ if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */
+ {
+ char *property_name = XGetAtomName (window->display->xdisplay,
+ event->atom);
+
+ meta_verbose ("Property notify on %s for %s\n",
+ window->desc, property_name);
+ XFree (property_name);
+ }
+
+ if (event->atom == window->display->atom__NET_WM_USER_TIME &&
+ window->user_time_window)
+ {
+ xid = window->user_time_window;
+ }
+
+ meta_window_reload_property_from_xwindow (window, xid, event->atom, FALSE);
+
+ return TRUE;
+}
+
+gboolean
+meta_window_x11_property_notify (MetaWindow *window,
+ XEvent *event)
+{
+ return process_property_notify (window, &event->xproperty);
+}
+
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
+#define _NET_WM_MOVERESIZE_SIZE_TOP 1
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
+#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
+#define _NET_WM_MOVERESIZE_MOVE 8
+#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9
+#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10
+#define _NET_WM_MOVERESIZE_CANCEL 11
+
+static int
+query_pressed_buttons (MetaWindow *window)
+{
+ double x, y, query_root_x, query_root_y;
+ Window root, child;
+ XIButtonState buttons;
+ XIModifierState mods;
+ XIGroupState group;
+ int button = 0;
+
+ meta_error_trap_push (window->display);
+ XIQueryPointer (window->display->xdisplay,
+ META_VIRTUAL_CORE_POINTER_ID,
+ window->xwindow,
+ &root, &child,
+ &query_root_x, &query_root_y,
+ &x, &y,
+ &buttons, &mods, &group);
+
+ if (meta_error_trap_pop_with_return (window->display) != Success)
+ goto out;
+
+ if (XIMaskIsSet (buttons.mask, Button1))
+ button |= 1 << 1;
+ if (XIMaskIsSet (buttons.mask, Button2))
+ button |= 1 << 2;
+ if (XIMaskIsSet (buttons.mask, Button3))
+ button |= 1 << 3;
+
+ free (buttons.mask);
+
+ out:
+ return button;
+}
+
+gboolean
+meta_window_x11_client_message (MetaWindow *window,
+ XEvent *event)
+{
+ MetaDisplay *display;
+
+ display = window->display;
+
+ if (window->override_redirect)
+ {
+ /* Don't warn here: we could warn on any of the messages below,
+ * but we might also receive other client messages that are
+ * part of protocols we don't know anything about. So, silently
+ * ignoring is simplest.
+ */
+ return FALSE;
+ }
+
+ if (event->xclient.message_type ==
+ display->atom__NET_CLOSE_WINDOW)
+ {
+ guint32 timestamp;
+
+ if (event->xclient.data.l[0] != 0)
+ timestamp = event->xclient.data.l[0];
+ else
+ {
+ meta_warning ("Receiving a NET_CLOSE_WINDOW message for %s without "
+ "a timestamp! This means some buggy (outdated) "
+ "application is on the loose!\n",
+ window->desc);
+ timestamp = meta_display_get_current_time (window->display);
+ }
+
+ meta_window_delete (window, timestamp);
+
+ return TRUE;
+ }
+ else if (event->xclient.message_type ==
+ display->atom__NET_WM_DESKTOP)
+ {
+ int space;
+ MetaWorkspace *workspace;
+
+ space = event->xclient.data.l[0];
+
+ meta_verbose ("Request to move %s to workspace %d\n",
+ window->desc, space);
+
+ workspace =
+ meta_screen_get_workspace_by_index (window->screen,
+ space);
+
+ if (workspace)
+ {
+ if (window->on_all_workspaces_requested)
+ meta_window_unstick (window);
+ meta_window_change_workspace (window, workspace);
+ }
+ else if (space == (int) 0xFFFFFFFF)
+ {
+ meta_window_stick (window);
+ }
+ else
+ {
+ meta_verbose ("No such workspace %d for screen\n", space);
+ }
+
+ meta_verbose ("Window %s now on_all_workspaces = %d\n",
+ window->desc, window->on_all_workspaces);
+
+ return TRUE;
+ }
+ else if (event->xclient.message_type ==
+ display->atom__NET_WM_STATE)
+ {
+ gulong action;
+ Atom first;
+ Atom second;
+
+ action = event->xclient.data.l[0];
+ first = event->xclient.data.l[1];
+ second = event->xclient.data.l[2];
+
+ if (meta_is_verbose ())
+ {
+ char *str1;
+ char *str2;
+
+ meta_error_trap_push_with_return (display);
+ str1 = XGetAtomName (display->xdisplay, first);
+ if (meta_error_trap_pop_with_return (display) != Success)
+ str1 = NULL;
+
+ meta_error_trap_push_with_return (display);
+ str2 = XGetAtomName (display->xdisplay, second);
+ if (meta_error_trap_pop_with_return (display) != Success)
+ str2 = NULL;
+
+ meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n",
+ action,
+ str1 ? str1 : "(unknown)",
+ str2 ? str2 : "(unknown)");
+
+ meta_XFree (str1);
+ meta_XFree (str2);
+ }
+
+ if (first == display->atom__NET_WM_STATE_SHADED ||
+ second == display->atom__NET_WM_STATE_SHADED)
+ {
+ gboolean shade;
+ guint32 timestamp;
+
+ /* Stupid protocol has no timestamp; of course, shading
+ * sucks anyway so who really cares that we're forced to do
+ * a roundtrip here?
+ */
+ timestamp = meta_display_get_current_time_roundtrip (window->display);
+
+ shade = (action == _NET_WM_STATE_ADD ||
+ (action == _NET_WM_STATE_TOGGLE && !window->shaded));
+ if (shade && window->has_shade_func)
+ meta_window_shade (window, timestamp);
+ else
+ meta_window_unshade (window, timestamp);
+ }
+
+ if (first == display->atom__NET_WM_STATE_FULLSCREEN ||
+ second == display->atom__NET_WM_STATE_FULLSCREEN)
+ {
+ gboolean make_fullscreen;
+
+ make_fullscreen = (action == _NET_WM_STATE_ADD ||
+ (action == _NET_WM_STATE_TOGGLE && !window->fullscreen));
+ if (make_fullscreen && window->has_fullscreen_func)
+ meta_window_make_fullscreen (window);
+ else
+ meta_window_unmake_fullscreen (window);
+ }
+
+ if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
+ second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
+ first == display->atom__NET_WM_STATE_MAXIMIZED_VERT ||
+ second == display->atom__NET_WM_STATE_MAXIMIZED_VERT)
+ {
+ gboolean max;
+ MetaMaximizeFlags directions = 0;
+
+ max = (action == _NET_WM_STATE_ADD ||
+ (action == _NET_WM_STATE_TOGGLE &&
+ !window->maximized_horizontally));
+
+ if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
+ second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ)
+ directions |= META_MAXIMIZE_HORIZONTAL;
+
+ if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT ||
+ second == display->atom__NET_WM_STATE_MAXIMIZED_VERT)
+ directions |= META_MAXIMIZE_VERTICAL;
+
+ if (max && window->has_maximize_func)
+ {
+ if (meta_prefs_get_raise_on_click ())
+ meta_window_raise (window);
+ meta_window_maximize (window, directions);
+ }
+ else
+ {
+ if (meta_prefs_get_raise_on_click ())
+ meta_window_raise (window);
+ meta_window_unmaximize (window, directions);
+ }
+ }
+
+ if (first == display->atom__NET_WM_STATE_MODAL ||
+ second == display->atom__NET_WM_STATE_MODAL)
+ {
+ window->wm_state_modal =
+ (action == _NET_WM_STATE_ADD) ||
+ (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal);
+
+ meta_window_recalc_window_type (window);
+ meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
+ }
+
+ if (first == display->atom__NET_WM_STATE_SKIP_PAGER ||
+ second == display->atom__NET_WM_STATE_SKIP_PAGER)
+ {
+ window->wm_state_skip_pager =
+ (action == _NET_WM_STATE_ADD) ||
+ (action == _NET_WM_STATE_TOGGLE && !window->skip_pager);
+
+ meta_window_recalc_features (window);
+ meta_window_x11_set_net_wm_state (window);
+ }
+
+ if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR ||
+ second == display->atom__NET_WM_STATE_SKIP_TASKBAR)
+ {
+ window->wm_state_skip_taskbar =
+ (action == _NET_WM_STATE_ADD) ||
+ (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar);
+
+ meta_window_recalc_features (window);
+ meta_window_x11_set_net_wm_state (window);
+ }
+
+ if (first == display->atom__NET_WM_STATE_ABOVE ||
+ second == display->atom__NET_WM_STATE_ABOVE)
+ {
+ if ((action == _NET_WM_STATE_ADD) ||
+ (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention))
+ meta_window_make_above (window);
+ else
+ meta_window_unmake_above (window);
+ }
+
+ if (first == display->atom__NET_WM_STATE_BELOW ||
+ second == display->atom__NET_WM_STATE_BELOW)
+ {
+ window->wm_state_below =
+ (action == _NET_WM_STATE_ADD) ||
+ (action == _NET_WM_STATE_TOGGLE && !window->wm_state_below);
+
+ meta_window_update_layer (window);
+ meta_window_x11_set_net_wm_state (window);
+ }
+
+ if (first == display->atom__NET_WM_STATE_DEMANDS_ATTENTION ||
+ second == display->atom__NET_WM_STATE_DEMANDS_ATTENTION)
+ {
+ if ((action == _NET_WM_STATE_ADD) ||
+ (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention))
+ meta_window_set_demands_attention (window);
+ else
+ meta_window_unset_demands_attention (window);
+ }
+
+ if (first == display->atom__NET_WM_STATE_STICKY ||
+ second == display->atom__NET_WM_STATE_STICKY)
+ {
+ if ((action == _NET_WM_STATE_ADD) ||
+ (action == _NET_WM_STATE_TOGGLE && !window->on_all_workspaces_requested))
+ meta_window_stick (window);
+ else
+ meta_window_unstick (window);
+ }
+
+ return TRUE;
+ }
+ else if (event->xclient.message_type ==
+ display->atom_WM_CHANGE_STATE)
+ {
+ meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
+ event->xclient.data.l[0]);
+ if (event->xclient.data.l[0] == IconicState &&
+ window->has_minimize_func)
+ meta_window_minimize (window);
+
+ return TRUE;
+ }
+ else if (event->xclient.message_type ==
+ display->atom__NET_WM_MOVERESIZE)
+ {
+ int x_root;
+ int y_root;
+ int action;
+ MetaGrabOp op;
+ int button;
+ guint32 timestamp;
+
+ /* _NET_WM_MOVERESIZE messages are almost certainly going to come from
+ * clients when users click on the fake "frame" that the client has,
+ * thus we should also treat such messages as though it were a
+ * "frame action".
+ */
+ gboolean const frame_action = TRUE;
+
+ x_root = event->xclient.data.l[0];
+ y_root = event->xclient.data.l[1];
+ action = event->xclient.data.l[2];
+ button = event->xclient.data.l[3];
+
+ /* FIXME: What a braindead protocol; no timestamp?!? */
+ timestamp = meta_display_get_current_time_roundtrip (display);
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Received _NET_WM_MOVERESIZE message on %s, %d,%d action = %d, button %d\n",
+ window->desc,
+ x_root, y_root, action, button);
+
+ op = META_GRAB_OP_NONE;
+ switch (action)
+ {
+ case _NET_WM_MOVERESIZE_SIZE_TOPLEFT:
+ op = META_GRAB_OP_RESIZING_NW;
+ break;
+ case _NET_WM_MOVERESIZE_SIZE_TOP:
+ op = META_GRAB_OP_RESIZING_N;
+ break;
+ case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
+ op = META_GRAB_OP_RESIZING_NE;
+ break;
+ case _NET_WM_MOVERESIZE_SIZE_RIGHT:
+ op = META_GRAB_OP_RESIZING_E;
+ break;
+ case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
+ op = META_GRAB_OP_RESIZING_SE;
+ break;
+ case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
+ op = META_GRAB_OP_RESIZING_S;
+ break;
+ case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
+ op = META_GRAB_OP_RESIZING_SW;
+ break;
+ case _NET_WM_MOVERESIZE_SIZE_LEFT:
+ op = META_GRAB_OP_RESIZING_W;
+ break;
+ case _NET_WM_MOVERESIZE_MOVE:
+ op = META_GRAB_OP_MOVING;
+ break;
+ case _NET_WM_MOVERESIZE_SIZE_KEYBOARD:
+ op = META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN;
+ break;
+ case _NET_WM_MOVERESIZE_MOVE_KEYBOARD:
+ op = META_GRAB_OP_KEYBOARD_MOVING;
+ break;
+ case _NET_WM_MOVERESIZE_CANCEL:
+ /* handled below */
+ break;
+ default:
+ break;
+ }
+
+ if (action == _NET_WM_MOVERESIZE_CANCEL)
+ {
+ meta_display_end_grab_op (window->display, timestamp);
+ }
+ else if (op != META_GRAB_OP_NONE &&
+ ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) ||
+ (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN)))
+ {
+ meta_window_begin_grab_op (window, op, frame_action, timestamp);
+ }
+ else if (op != META_GRAB_OP_NONE &&
+ ((window->has_move_func && op == META_GRAB_OP_MOVING) ||
+ (window->has_resize_func &&
+ (op != META_GRAB_OP_MOVING &&
+ op != META_GRAB_OP_KEYBOARD_MOVING))))
+ {
+ int button_mask;
+
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Beginning move/resize with button = %d\n", button);
+ meta_display_begin_grab_op (window->display,
+ window->screen,
+ window,
+ op,
+ FALSE,
+ frame_action,
+ button, 0,
+ timestamp,
+ x_root,
+ y_root);
+
+ button_mask = query_pressed_buttons (window);
+
+ if (button == 0)
+ {
+ /*
+ * the button SHOULD already be included in the message
+ */
+ if ((button_mask & (1 << 1)) != 0)
+ button = 1;
+ else if ((button_mask & (1 << 2)) != 0)
+ button = 2;
+ else if ((button_mask & (1 << 3)) != 0)
+ button = 3;
+
+ if (button != 0)
+ window->display->grab_button = button;
+ else
+ meta_display_end_grab_op (window->display,
+ timestamp);
+ }
+ else
+ {
+ /* There is a potential race here. If the user presses and
+ * releases their mouse button very fast, it's possible for
+ * both the ButtonPress and ButtonRelease to be sent to the
+ * client before it can get a chance to send _NET_WM_MOVERESIZE
+ * to us. When that happens, we'll become stuck in a grab
+ * state, as we haven't received a ButtonRelease to cancel the
+ * grab.
+ *
+ * We can solve this by querying after we take the explicit
+ * pointer grab -- if the button isn't pressed, we cancel the
+ * drag immediately.
+ */
+
+ if ((button_mask & (1 << button)) == 0)
+ meta_display_end_grab_op (window->display, timestamp);
+ }
+ }
+
+ return TRUE;
+ }
+ else if (event->xclient.message_type ==
+ display->atom__NET_MOVERESIZE_WINDOW)
+ {
+ int gravity;
+ guint value_mask;
+
+ gravity = (event->xclient.data.l[0] & 0xff);
+ value_mask = (event->xclient.data.l[0] & 0xf00) >> 8;
+ /* source = (event->xclient.data.l[0] & 0xf000) >> 12; */
+
+ if (gravity == 0)
+ gravity = window->size_hints.win_gravity;
+
+ meta_window_move_resize_request(window,
+ value_mask,
+ gravity,
+ event->xclient.data.l[1], /* x */
+ event->xclient.data.l[2], /* y */
+ event->xclient.data.l[3], /* width */
+ event->xclient.data.l[4]); /* height */
+ }
+ else if (event->xclient.message_type ==
+ display->atom__NET_ACTIVE_WINDOW)
+ {
+ MetaClientType source_indication;
+ guint32 timestamp;
+
+ meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n",
+ window->desc);
+
+ source_indication = event->xclient.data.l[0];
+ timestamp = event->xclient.data.l[1];
+
+ if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED)
+ source_indication = META_CLIENT_TYPE_UNKNOWN;
+
+ if (timestamp == 0)
+ {
+ /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */
+ meta_warning ("Buggy client sent a _NET_ACTIVE_WINDOW message with a "
+ "timestamp of 0 for %s\n",
+ window->desc);
+ timestamp = meta_display_get_current_time (display);
+ }
+
+ meta_window_activate_full (window, timestamp, source_indication, NULL);
+ return TRUE;
+ }
+ else if (event->xclient.message_type ==
+ display->atom__NET_WM_FULLSCREEN_MONITORS)
+ {
+ gulong top, bottom, left, right;
+
+ meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n",
+ window->desc);
+
+ top = meta_screen_xinerama_index_to_monitor_index (window->screen,
+ event->xclient.data.l[0]);
+ bottom = meta_screen_xinerama_index_to_monitor_index (window->screen,
+ event->xclient.data.l[1]);
+ left = meta_screen_xinerama_index_to_monitor_index (window->screen,
+ event->xclient.data.l[2]);
+ right = meta_screen_xinerama_index_to_monitor_index (window->screen,
+ event->xclient.data.l[3]);
+ /* source_indication = event->xclient.data.l[4]; */
+
+ meta_window_update_fullscreen_monitors (window, top, bottom, left, right);
+ }
+
+ return FALSE;
+}
diff --git a/src/core/window-x11.h b/src/core/window-x11.h
new file mode 100644
index 000000000..aea216f0e
--- /dev/null
+++ b/src/core/window-x11.h
@@ -0,0 +1,44 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (C) 2003, 2004 Rob Adams
+ * Copyright (C) 2004-2006 Elijah Newren
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#ifndef META_WINDOW_X11_H
+#define META_WINDOW_X11_H
+
+#include
+#include
+
+void meta_window_x11_set_net_wm_state (MetaWindow *window);
+
+void meta_window_x11_update_role (MetaWindow *window);
+void meta_window_x11_update_net_wm_type (MetaWindow *window);
+void meta_window_x11_update_opaque_region (MetaWindow *window);
+void meta_window_x11_update_input_region (MetaWindow *window);
+void meta_window_x11_update_shape_region (MetaWindow *window);
+
+gboolean meta_window_x11_configure_request (MetaWindow *window,
+ XEvent *event);
+gboolean meta_window_x11_property_notify (MetaWindow *window,
+ XEvent *event);
+gboolean meta_window_x11_client_message (MetaWindow *window,
+ XEvent *event);
+
+#endif
diff --git a/src/core/window.c b/src/core/window.c
index e1455d2ce..db8fd4262 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -28,6 +28,7 @@
#include
#include "window-private.h"
+#include "window-x11.h"
#include "boxes-private.h"
#include "edge-resistance.h"
#include "util-private.h"
@@ -49,7 +50,6 @@
#include "core.h"
#include
-#include /* For display->resource_mask */
#include
#include
#include
@@ -105,17 +105,12 @@ static void meta_window_set_above (MetaWindow *window,
gboolean new_value);
static void send_configure_notify (MetaWindow *window);
-static gboolean process_property_notify (MetaWindow *window,
- XPropertyEvent *event);
static void meta_window_force_placement (MetaWindow *window);
static void meta_window_show (MetaWindow *window);
static void meta_window_hide (MetaWindow *window);
-static gboolean meta_window_same_client (MetaWindow *window,
- MetaWindow *other_window);
-
static void meta_window_save_rect (MetaWindow *window);
static void save_user_window_placement (MetaWindow *window);
static void force_save_user_window_placement (MetaWindow *window);
@@ -1031,8 +1026,8 @@ meta_window_new_shared (MetaDisplay *display,
if (client_type == META_WINDOW_CLIENT_TYPE_X11)
{
meta_display_register_x_window (display, &window->xwindow, window);
- meta_window_update_shape_region_x11 (window);
- meta_window_update_input_region_x11 (window);
+ meta_window_x11_update_shape_region (window);
+ meta_window_x11_update_input_region (window);
}
else
meta_display_register_wayland_window (display, window);
@@ -2112,105 +2107,8 @@ set_wm_state (MetaWindow *window,
static void
set_net_wm_state (MetaWindow *window)
{
- int i;
- unsigned long data[13];
-
- i = 0;
- if (window->shaded)
- {
- data[i] = window->display->atom__NET_WM_STATE_SHADED;
- ++i;
- }
- if (window->wm_state_modal)
- {
- data[i] = window->display->atom__NET_WM_STATE_MODAL;
- ++i;
- }
- if (window->skip_pager)
- {
- data[i] = window->display->atom__NET_WM_STATE_SKIP_PAGER;
- ++i;
- }
- if (window->skip_taskbar)
- {
- data[i] = window->display->atom__NET_WM_STATE_SKIP_TASKBAR;
- ++i;
- }
- if (window->maximized_horizontally)
- {
- data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ;
- ++i;
- }
- if (window->maximized_vertically)
- {
- data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_VERT;
- ++i;
- }
- if (window->fullscreen)
- {
- data[i] = window->display->atom__NET_WM_STATE_FULLSCREEN;
- ++i;
- }
- if (!meta_window_showing_on_its_workspace (window) || window->shaded)
- {
- data[i] = window->display->atom__NET_WM_STATE_HIDDEN;
- ++i;
- }
- if (window->wm_state_above)
- {
- data[i] = window->display->atom__NET_WM_STATE_ABOVE;
- ++i;
- }
- if (window->wm_state_below)
- {
- data[i] = window->display->atom__NET_WM_STATE_BELOW;
- ++i;
- }
- if (window->wm_state_demands_attention)
- {
- data[i] = window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION;
- ++i;
- }
- if (window->on_all_workspaces_requested)
- {
- data[i] = window->display->atom__NET_WM_STATE_STICKY;
- ++i;
- }
- if (meta_window_appears_focused (window))
- {
- data[i] = window->display->atom__NET_WM_STATE_FOCUSED;
- ++i;
- }
-
- meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i);
-
- meta_error_trap_push (window->display);
- XChangeProperty (window->display->xdisplay, window->xwindow,
- window->display->atom__NET_WM_STATE,
- XA_ATOM,
- 32, PropModeReplace, (guchar*) data, i);
- meta_error_trap_pop (window->display);
-
- if (window->fullscreen)
- {
- data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen,
- window->fullscreen_monitors[0]);
- data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen,
- window->fullscreen_monitors[1]);
- data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen,
- window->fullscreen_monitors[2]);
- data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen,
- window->fullscreen_monitors[3]);
-
- meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n");
- meta_error_trap_push (window->display);
- XChangeProperty (window->display->xdisplay,
- window->xwindow,
- window->display->atom__NET_WM_FULLSCREEN_MONITORS,
- XA_CARDINAL, 32, PropModeReplace,
- (guchar*) data, 4);
- meta_error_trap_pop (window->display);
- }
+ if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
+ meta_window_x11_set_net_wm_state (window);
}
/**
@@ -4374,11 +4272,11 @@ unminimize_window_and_all_transient_parents (MetaWindow *window)
meta_window_foreach_ancestor (window, unminimize_func, NULL);
}
-static void
-window_activate (MetaWindow *window,
- guint32 timestamp,
- MetaClientType source_indication,
- MetaWorkspace *workspace)
+void
+meta_window_activate_full (MetaWindow *window,
+ guint32 timestamp,
+ MetaClientType source_indication,
+ MetaWorkspace *workspace)
{
gboolean can_ignore_outdated_timestamps;
meta_topic (META_DEBUG_FOCUS,
@@ -4471,7 +4369,7 @@ meta_window_activate (MetaWindow *window,
* we were such. If we change the pager behavior later, we could revisit
* this and just add extra flags to window_activate.
*/
- window_activate (window, timestamp, META_CLIENT_TYPE_PAGER, NULL);
+ meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_PAGER, NULL);
}
void
@@ -4481,11 +4379,7 @@ meta_window_activate_with_workspace (MetaWindow *window,
{
g_return_if_fail (!window->override_redirect);
- /* We're not really a pager, but the behavior we want is the same as if
- * we were such. If we change the pager behavior later, we could revisit
- * this and just add extra flags to window_activate.
- */
- window_activate (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace);
+ meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace);
}
/* Manually fix all the weirdness explained in the big comment at the
@@ -6825,97 +6719,6 @@ meta_window_move_resize_request (MetaWindow *window,
save_user_window_placement (window);
}
-gboolean
-meta_window_configure_request (MetaWindow *window,
- XEvent *event)
-{
- /* Note that x, y is the corner of the window border,
- * and width, height is the size of the window inside
- * its border, but that we always deny border requests
- * and give windows a border of 0. But we save the
- * requested border here.
- */
- if (event->xconfigurerequest.value_mask & CWBorderWidth)
- window->border_width = event->xconfigurerequest.border_width;
-
- meta_window_move_resize_request(window,
- event->xconfigurerequest.value_mask,
- window->size_hints.win_gravity,
- event->xconfigurerequest.x,
- event->xconfigurerequest.y,
- event->xconfigurerequest.width,
- event->xconfigurerequest.height);
-
- /* Handle stacking. We only handle raises/lowers, mostly because
- * stack.c really can't deal with anything else. I guess we'll fix
- * that if a client turns up that really requires it. Only a very
- * few clients even require the raise/lower (and in fact all client
- * attempts to deal with stacking order are essentially broken,
- * since they have no idea what other clients are involved or how
- * the stack looks).
- *
- * I'm pretty sure no interesting client uses TopIf, BottomIf, or
- * Opposite anyway, so the only possible missing thing is
- * Above/Below with a sibling set. For now we just pretend there's
- * never a sibling set and always do the full raise/lower instead of
- * the raise-just-above/below-sibling.
- */
- if (event->xconfigurerequest.value_mask & CWStackMode)
- {
- MetaWindow *active_window;
- active_window = window->display->focus_window;
- if (meta_prefs_get_disable_workarounds ())
- {
- meta_topic (META_DEBUG_STACK,
- "%s sent an xconfigure stacking request; this is "
- "broken behavior and the request is being ignored.\n",
- window->desc);
- }
- else if (active_window &&
- !meta_window_same_application (window, active_window) &&
- !meta_window_same_client (window, active_window) &&
- XSERVER_TIME_IS_BEFORE (window->net_wm_user_time,
- active_window->net_wm_user_time))
- {
- meta_topic (META_DEBUG_STACK,
- "Ignoring xconfigure stacking request from %s (with "
- "user_time %u); currently active application is %s (with "
- "user_time %u).\n",
- window->desc,
- window->net_wm_user_time,
- active_window->desc,
- active_window->net_wm_user_time);
- if (event->xconfigurerequest.detail == Above)
- meta_window_set_demands_attention(window);
- }
- else
- {
- switch (event->xconfigurerequest.detail)
- {
- case Above:
- meta_window_raise (window);
- break;
- case Below:
- meta_window_lower (window);
- break;
- case TopIf:
- case BottomIf:
- case Opposite:
- break;
- }
- }
- }
-
- return TRUE;
-}
-
-gboolean
-meta_window_property_notify (MetaWindow *window,
- XEvent *event)
-{
- return process_property_notify (window, &event->xproperty);
-}
-
/*
* Move window to the requested workspace; append controls whether new WS
* should be created if one does not exist.
@@ -6953,531 +6756,6 @@ meta_window_change_workspace_by_index (MetaWindow *window,
}
}
-#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
-#define _NET_WM_MOVERESIZE_SIZE_TOP 1
-#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
-#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
-#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
-#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
-#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
-#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
-#define _NET_WM_MOVERESIZE_MOVE 8
-#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9
-#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10
-#define _NET_WM_MOVERESIZE_CANCEL 11
-
-static int
-query_pressed_buttons (MetaWindow *window)
-{
- double x, y, query_root_x, query_root_y;
- Window root, child;
- XIButtonState buttons;
- XIModifierState mods;
- XIGroupState group;
- int button = 0;
-
- meta_error_trap_push (window->display);
- XIQueryPointer (window->display->xdisplay,
- META_VIRTUAL_CORE_POINTER_ID,
- window->xwindow,
- &root, &child,
- &query_root_x, &query_root_y,
- &x, &y,
- &buttons, &mods, &group);
-
- if (meta_error_trap_pop_with_return (window->display) != Success)
- goto out;
-
- if (XIMaskIsSet (buttons.mask, Button1))
- button |= 1 << 1;
- if (XIMaskIsSet (buttons.mask, Button2))
- button |= 1 << 2;
- if (XIMaskIsSet (buttons.mask, Button3))
- button |= 1 << 3;
-
- free (buttons.mask);
-
- out:
- return button;
-}
-
-gboolean
-meta_window_client_message (MetaWindow *window,
- XEvent *event)
-{
- MetaDisplay *display;
-
- display = window->display;
-
- if (window->override_redirect)
- {
- /* Don't warn here: we could warn on any of the messages below,
- * but we might also receive other client messages that are
- * part of protocols we don't know anything about. So, silently
- * ignoring is simplest.
- */
- return FALSE;
- }
-
- if (event->xclient.message_type ==
- display->atom__NET_CLOSE_WINDOW)
- {
- guint32 timestamp;
-
- if (event->xclient.data.l[0] != 0)
- timestamp = event->xclient.data.l[0];
- else
- {
- meta_warning ("Receiving a NET_CLOSE_WINDOW message for %s without "
- "a timestamp! This means some buggy (outdated) "
- "application is on the loose!\n",
- window->desc);
- timestamp = meta_display_get_current_time (window->display);
- }
-
- meta_window_delete (window, timestamp);
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_WM_DESKTOP)
- {
- int space;
- MetaWorkspace *workspace;
-
- space = event->xclient.data.l[0];
-
- meta_verbose ("Request to move %s to workspace %d\n",
- window->desc, space);
-
- workspace =
- meta_screen_get_workspace_by_index (window->screen,
- space);
-
- if (workspace)
- {
- if (window->on_all_workspaces_requested)
- meta_window_unstick (window);
- meta_window_change_workspace (window, workspace);
- }
- else if (space == (int) 0xFFFFFFFF)
- {
- meta_window_stick (window);
- }
- else
- {
- meta_verbose ("No such workspace %d for screen\n", space);
- }
-
- meta_verbose ("Window %s now on_all_workspaces = %d\n",
- window->desc, window->on_all_workspaces);
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_WM_STATE)
- {
- gulong action;
- Atom first;
- Atom second;
-
- action = event->xclient.data.l[0];
- first = event->xclient.data.l[1];
- second = event->xclient.data.l[2];
-
- if (meta_is_verbose ())
- {
- char *str1;
- char *str2;
-
- meta_error_trap_push_with_return (display);
- str1 = XGetAtomName (display->xdisplay, first);
- if (meta_error_trap_pop_with_return (display) != Success)
- str1 = NULL;
-
- meta_error_trap_push_with_return (display);
- str2 = XGetAtomName (display->xdisplay, second);
- if (meta_error_trap_pop_with_return (display) != Success)
- str2 = NULL;
-
- meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n",
- action,
- str1 ? str1 : "(unknown)",
- str2 ? str2 : "(unknown)");
-
- meta_XFree (str1);
- meta_XFree (str2);
- }
-
- if (first == display->atom__NET_WM_STATE_SHADED ||
- second == display->atom__NET_WM_STATE_SHADED)
- {
- gboolean shade;
- guint32 timestamp;
-
- /* Stupid protocol has no timestamp; of course, shading
- * sucks anyway so who really cares that we're forced to do
- * a roundtrip here?
- */
- timestamp = meta_display_get_current_time_roundtrip (window->display);
-
- shade = (action == _NET_WM_STATE_ADD ||
- (action == _NET_WM_STATE_TOGGLE && !window->shaded));
- if (shade && window->has_shade_func)
- meta_window_shade (window, timestamp);
- else
- meta_window_unshade (window, timestamp);
- }
-
- if (first == display->atom__NET_WM_STATE_FULLSCREEN ||
- second == display->atom__NET_WM_STATE_FULLSCREEN)
- {
- gboolean make_fullscreen;
-
- make_fullscreen = (action == _NET_WM_STATE_ADD ||
- (action == _NET_WM_STATE_TOGGLE && !window->fullscreen));
- if (make_fullscreen && window->has_fullscreen_func)
- meta_window_make_fullscreen (window);
- else
- meta_window_unmake_fullscreen (window);
- }
-
- if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
- second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
- first == display->atom__NET_WM_STATE_MAXIMIZED_VERT ||
- second == display->atom__NET_WM_STATE_MAXIMIZED_VERT)
- {
- gboolean max;
- MetaMaximizeFlags directions = 0;
-
- max = (action == _NET_WM_STATE_ADD ||
- (action == _NET_WM_STATE_TOGGLE &&
- !window->maximized_horizontally));
-
- if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
- second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ)
- directions |= META_MAXIMIZE_HORIZONTAL;
-
- if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT ||
- second == display->atom__NET_WM_STATE_MAXIMIZED_VERT)
- directions |= META_MAXIMIZE_VERTICAL;
-
- if (max && window->has_maximize_func)
- {
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- meta_window_maximize (window, directions);
- }
- else
- {
- if (meta_prefs_get_raise_on_click ())
- meta_window_raise (window);
- meta_window_unmaximize (window, directions);
- }
- }
-
- if (first == display->atom__NET_WM_STATE_MODAL ||
- second == display->atom__NET_WM_STATE_MODAL)
- {
- window->wm_state_modal =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal);
-
- meta_window_recalc_window_type (window);
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
- }
-
- if (first == display->atom__NET_WM_STATE_SKIP_PAGER ||
- second == display->atom__NET_WM_STATE_SKIP_PAGER)
- {
- window->wm_state_skip_pager =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->skip_pager);
-
- meta_window_recalc_window_features (window);
- set_net_wm_state (window);
- }
-
- if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR ||
- second == display->atom__NET_WM_STATE_SKIP_TASKBAR)
- {
- window->wm_state_skip_taskbar =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar);
-
- meta_window_recalc_window_features (window);
- set_net_wm_state (window);
- }
-
- if (first == display->atom__NET_WM_STATE_ABOVE ||
- second == display->atom__NET_WM_STATE_ABOVE)
- {
- meta_window_set_above(window,
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->wm_state_above));
- }
-
- if (first == display->atom__NET_WM_STATE_BELOW ||
- second == display->atom__NET_WM_STATE_BELOW)
- {
- window->wm_state_below =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->wm_state_below);
-
- meta_window_update_layer (window);
- set_net_wm_state (window);
- }
-
- if (first == display->atom__NET_WM_STATE_DEMANDS_ATTENTION ||
- second == display->atom__NET_WM_STATE_DEMANDS_ATTENTION)
- {
- if ((action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention))
- meta_window_set_demands_attention (window);
- else
- meta_window_unset_demands_attention (window);
- }
-
- if (first == display->atom__NET_WM_STATE_STICKY ||
- second == display->atom__NET_WM_STATE_STICKY)
- {
- if ((action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->on_all_workspaces_requested))
- meta_window_stick (window);
- else
- meta_window_unstick (window);
- }
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom_WM_CHANGE_STATE)
- {
- meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
- event->xclient.data.l[0]);
- if (event->xclient.data.l[0] == IconicState &&
- window->has_minimize_func)
- meta_window_minimize (window);
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_WM_MOVERESIZE)
- {
- int x_root;
- int y_root;
- int action;
- MetaGrabOp op;
- int button;
- guint32 timestamp;
-
- /* _NET_WM_MOVERESIZE messages are almost certainly going to come from
- * clients when users click on the fake "frame" that the client has,
- * thus we should also treat such messages as though it were a
- * "frame action".
- */
- gboolean const frame_action = TRUE;
-
- x_root = event->xclient.data.l[0];
- y_root = event->xclient.data.l[1];
- action = event->xclient.data.l[2];
- button = event->xclient.data.l[3];
-
- /* FIXME: What a braindead protocol; no timestamp?!? */
- timestamp = meta_display_get_current_time_roundtrip (display);
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Received _NET_WM_MOVERESIZE message on %s, %d,%d action = %d, button %d\n",
- window->desc,
- x_root, y_root, action, button);
-
- op = META_GRAB_OP_NONE;
- switch (action)
- {
- case _NET_WM_MOVERESIZE_SIZE_TOPLEFT:
- op = META_GRAB_OP_RESIZING_NW;
- break;
- case _NET_WM_MOVERESIZE_SIZE_TOP:
- op = META_GRAB_OP_RESIZING_N;
- break;
- case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
- op = META_GRAB_OP_RESIZING_NE;
- break;
- case _NET_WM_MOVERESIZE_SIZE_RIGHT:
- op = META_GRAB_OP_RESIZING_E;
- break;
- case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
- op = META_GRAB_OP_RESIZING_SE;
- break;
- case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
- op = META_GRAB_OP_RESIZING_S;
- break;
- case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
- op = META_GRAB_OP_RESIZING_SW;
- break;
- case _NET_WM_MOVERESIZE_SIZE_LEFT:
- op = META_GRAB_OP_RESIZING_W;
- break;
- case _NET_WM_MOVERESIZE_MOVE:
- op = META_GRAB_OP_MOVING;
- break;
- case _NET_WM_MOVERESIZE_SIZE_KEYBOARD:
- op = META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN;
- break;
- case _NET_WM_MOVERESIZE_MOVE_KEYBOARD:
- op = META_GRAB_OP_KEYBOARD_MOVING;
- break;
- case _NET_WM_MOVERESIZE_CANCEL:
- /* handled below */
- break;
- default:
- break;
- }
-
- if (action == _NET_WM_MOVERESIZE_CANCEL)
- {
- meta_display_end_grab_op (window->display, timestamp);
- }
- else if (op != META_GRAB_OP_NONE &&
- ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) ||
- (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN)))
- {
- meta_window_begin_grab_op (window, op, frame_action, timestamp);
- }
- else if (op != META_GRAB_OP_NONE &&
- ((window->has_move_func && op == META_GRAB_OP_MOVING) ||
- (window->has_resize_func &&
- (op != META_GRAB_OP_MOVING &&
- op != META_GRAB_OP_KEYBOARD_MOVING))))
- {
- int button_mask;
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Beginning move/resize with button = %d\n", button);
- meta_display_begin_grab_op (window->display,
- window->screen,
- window,
- op,
- FALSE,
- frame_action,
- button, 0,
- timestamp,
- x_root,
- y_root);
-
- button_mask = query_pressed_buttons (window);
-
- if (button == 0)
- {
- /*
- * the button SHOULD already be included in the message
- */
- if ((button_mask & (1 << 1)) != 0)
- button = 1;
- else if ((button_mask & (1 << 2)) != 0)
- button = 2;
- else if ((button_mask & (1 << 3)) != 0)
- button = 3;
-
- if (button != 0)
- window->display->grab_button = button;
- else
- meta_display_end_grab_op (window->display,
- timestamp);
- }
- else
- {
- /* There is a potential race here. If the user presses and
- * releases their mouse button very fast, it's possible for
- * both the ButtonPress and ButtonRelease to be sent to the
- * client before it can get a chance to send _NET_WM_MOVERESIZE
- * to us. When that happens, we'll become stuck in a grab
- * state, as we haven't received a ButtonRelease to cancel the
- * grab.
- *
- * We can solve this by querying after we take the explicit
- * pointer grab -- if the button isn't pressed, we cancel the
- * drag immediately.
- */
-
- if ((button_mask & (1 << button)) == 0)
- meta_display_end_grab_op (window->display, timestamp);
- }
- }
-
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_MOVERESIZE_WINDOW)
- {
- int gravity;
- guint value_mask;
-
- gravity = (event->xclient.data.l[0] & 0xff);
- value_mask = (event->xclient.data.l[0] & 0xf00) >> 8;
- /* source = (event->xclient.data.l[0] & 0xf000) >> 12; */
-
- if (gravity == 0)
- gravity = window->size_hints.win_gravity;
-
- meta_window_move_resize_request(window,
- value_mask,
- gravity,
- event->xclient.data.l[1], /* x */
- event->xclient.data.l[2], /* y */
- event->xclient.data.l[3], /* width */
- event->xclient.data.l[4]); /* height */
- }
- else if (event->xclient.message_type ==
- display->atom__NET_ACTIVE_WINDOW)
- {
- MetaClientType source_indication;
- guint32 timestamp;
-
- meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n",
- window->desc);
-
- source_indication = event->xclient.data.l[0];
- timestamp = event->xclient.data.l[1];
-
- if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED)
- source_indication = META_CLIENT_TYPE_UNKNOWN;
-
- if (timestamp == 0)
- {
- /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */
- meta_warning ("Buggy client sent a _NET_ACTIVE_WINDOW message with a "
- "timestamp of 0 for %s\n",
- window->desc);
- timestamp = meta_display_get_current_time (display);
- }
-
- window_activate (window, timestamp, source_indication, NULL);
- return TRUE;
- }
- else if (event->xclient.message_type ==
- display->atom__NET_WM_FULLSCREEN_MONITORS)
- {
- gulong top, bottom, left, right;
-
- meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n",
- window->desc);
-
- top = meta_screen_xinerama_index_to_monitor_index (window->screen,
- event->xclient.data.l[0]);
- bottom = meta_screen_xinerama_index_to_monitor_index (window->screen,
- event->xclient.data.l[1]);
- left = meta_screen_xinerama_index_to_monitor_index (window->screen,
- event->xclient.data.l[2]);
- right = meta_screen_xinerama_index_to_monitor_index (window->screen,
- event->xclient.data.l[3]);
- /* source_indication = event->xclient.data.l[4]; */
-
- meta_window_update_fullscreen_monitors (window, top, bottom, left, right);
- }
-
- return FALSE;
-}
-
static void
meta_window_appears_focused_changed (MetaWindow *window)
{
@@ -7640,33 +6918,6 @@ meta_window_set_focused_internal (MetaWindow *window,
}
}
-static gboolean
-process_property_notify (MetaWindow *window,
- XPropertyEvent *event)
-{
- Window xid = window->xwindow;
-
- if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */
- {
- char *property_name = XGetAtomName (window->display->xdisplay,
- event->atom);
-
- meta_verbose ("Property notify on %s for %s\n",
- window->desc, property_name);
- XFree (property_name);
- }
-
- if (event->atom == window->display->atom__NET_WM_USER_TIME &&
- window->user_time_window)
- {
- xid = window->user_time_window;
- }
-
- meta_window_reload_property_from_xwindow (window, xid, event->atom, FALSE);
-
- return TRUE;
-}
-
static void
send_configure_notify (MetaWindow *window)
{
@@ -7872,347 +7123,6 @@ update_sm_hints (MetaWindow *window)
window->sm_client_id ? window->sm_client_id : "none");
}
-void
-meta_window_update_role (MetaWindow *window)
-{
- char *str;
-
- g_return_if_fail (!window->override_redirect);
-
- if (window->role)
- g_free (window->role);
- window->role = NULL;
-
- if (meta_prop_get_latin1_string (window->display, window->xwindow,
- window->display->atom_WM_WINDOW_ROLE,
- &str))
- {
- window->role = g_strdup (str);
- meta_XFree (str);
- }
-
- meta_verbose ("Updated role of %s to '%s'\n",
- window->desc, window->role ? window->role : "null");
-}
-
-void
-meta_window_update_net_wm_type (MetaWindow *window)
-{
- int n_atoms;
- Atom *atoms;
- int i;
-
- window->type_atom = None;
- n_atoms = 0;
- atoms = NULL;
-
- meta_prop_get_atom_list (window->display, window->xwindow,
- window->display->atom__NET_WM_WINDOW_TYPE,
- &atoms, &n_atoms);
-
- i = 0;
- while (i < n_atoms)
- {
- /* We break as soon as we find one we recognize,
- * supposed to prefer those near the front of the list
- */
- if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG ||
- atoms[i] ==
- window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP ||
- atoms[i] ==
- window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_COMBO ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND ||
- atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
- {
- window->type_atom = atoms[i];
- break;
- }
-
- ++i;
- }
-
- meta_XFree (atoms);
-
- if (meta_is_verbose ())
- {
- char *str;
-
- str = NULL;
- if (window->type_atom != None)
- {
- meta_error_trap_push (window->display);
- str = XGetAtomName (window->display->xdisplay, window->type_atom);
- meta_error_trap_pop (window->display);
- }
-
- meta_verbose ("Window %s type atom %s\n", window->desc,
- str ? str : "(none)");
-
- if (str)
- meta_XFree (str);
- }
-
- meta_window_recalc_window_type (window);
-}
-
-static void
-meta_window_set_opaque_region (MetaWindow *window,
- cairo_region_t *region)
-{
- g_clear_pointer (&window->opaque_region, cairo_region_destroy);
-
- if (region != NULL)
- window->opaque_region = cairo_region_reference (region);
-
- if (window->display->compositor)
- meta_compositor_window_shape_changed (window->display->compositor, window);
-}
-
-void
-meta_window_update_opaque_region_x11 (MetaWindow *window)
-{
- cairo_region_t *opaque_region = NULL;
- gulong *region = NULL;
- int nitems;
-
- if (meta_prop_get_cardinal_list (window->display,
- window->xwindow,
- window->display->atom__NET_WM_OPAQUE_REGION,
- ®ion, &nitems))
- {
- cairo_rectangle_int_t *rects;
- int i, rect_index, nrects;
-
- if (nitems % 4 != 0)
- {
- meta_verbose ("_NET_WM_OPAQUE_REGION does not have a list of 4-tuples.");
- goto out;
- }
-
- /* empty region */
- if (nitems == 0)
- goto out;
-
- nrects = nitems / 4;
-
- rects = g_new (cairo_rectangle_int_t, nrects);
-
- rect_index = 0;
- i = 0;
- while (i < nitems)
- {
- cairo_rectangle_int_t *rect = &rects[rect_index];
-
- rect->x = region[i++];
- rect->y = region[i++];
- rect->width = region[i++];
- rect->height = region[i++];
-
- rect_index++;
- }
-
- opaque_region = cairo_region_create_rectangles (rects, nrects);
-
- g_free (rects);
- }
-
- out:
- meta_XFree (region);
-
- meta_window_set_opaque_region (window, opaque_region);
- cairo_region_destroy (opaque_region);
-}
-
-static cairo_region_t *
-region_create_from_x_rectangles (const XRectangle *rects,
- int n_rects)
-{
- int i;
- cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects);
-
- for (i = 0; i < n_rects; i ++)
- {
- cairo_rects[i].x = rects[i].x;
- cairo_rects[i].y = rects[i].y;
- cairo_rects[i].width = rects[i].width;
- cairo_rects[i].height = rects[i].height;
- }
-
- return cairo_region_create_rectangles (cairo_rects, n_rects);
-}
-
-static void
-meta_window_set_input_region (MetaWindow *window,
- cairo_region_t *region)
-{
- g_clear_pointer (&window->input_region, cairo_region_destroy);
-
- if (region != NULL)
- window->input_region = cairo_region_reference (region);
-
- if (window->display->compositor)
- meta_compositor_window_shape_changed (window->display->compositor, window);
-}
-
-void
-meta_window_update_input_region_x11 (MetaWindow *window)
-{
- cairo_region_t *region = NULL;
-
-#ifdef HAVE_SHAPE
- if (META_DISPLAY_HAS_SHAPE (window->display))
- {
- /* Translate the set of XShape rectangles that we
- * get from the X server to a cairo_region. */
- XRectangle *rects = NULL;
- int n_rects, ordering;
-
- int x_bounding, y_bounding, x_clip, y_clip;
- unsigned w_bounding, h_bounding, w_clip, h_clip;
- int bounding_shaped, clip_shaped;
-
- meta_error_trap_push (window->display);
- XShapeQueryExtents (window->display->xdisplay, window->xwindow,
- &bounding_shaped, &x_bounding, &y_bounding,
- &w_bounding, &h_bounding,
- &clip_shaped, &x_clip, &y_clip,
- &w_clip, &h_clip);
-
- rects = XShapeGetRectangles (window->display->xdisplay,
- window->xwindow,
- ShapeInput,
- &n_rects,
- &ordering);
- meta_error_trap_pop (window->display);
-
- /* XXX: The x shape extension doesn't provide a way to only test if an
- * input shape has been specified, so we have to query and throw away the
- * rectangles. */
- if (rects)
- {
- if (n_rects > 1 ||
- (n_rects == 1 &&
- (rects[0].x != x_bounding ||
- rects[1].y != y_bounding ||
- rects[2].width != w_bounding ||
- rects[3].height != h_bounding)))
- region = region_create_from_x_rectangles (rects, n_rects);
-
- XFree (rects);
- }
- }
-#endif /* HAVE_SHAPE */
-
- if (region != NULL)
- {
- cairo_rectangle_int_t client_area;
-
- client_area.x = 0;
- client_area.y = 0;
- client_area.width = window->rect.width;
- client_area.height = window->rect.height;
-
- /* The shape we get back from the client may have coordinates
- * outside of the frame. The X SHAPE Extension requires that
- * the overall shape the client provides never exceeds the
- * "bounding rectangle" of the window -- the shape that the
- * window would have gotten if it was unshaped. In our case,
- * this is simply the client area.
- */
- cairo_region_intersect_rectangle (region, &client_area);
- }
-
- meta_window_set_input_region (window, region);
- cairo_region_destroy (region);
-}
-
-static void
-meta_window_set_shape_region (MetaWindow *window,
- cairo_region_t *region)
-{
- g_clear_pointer (&window->shape_region, cairo_region_destroy);
-
- if (region != NULL)
- window->shape_region = cairo_region_reference (region);
-
- if (window->display->compositor)
- meta_compositor_window_shape_changed (window->display->compositor, window);
-}
-
-void
-meta_window_update_shape_region_x11 (MetaWindow *window)
-{
- cairo_region_t *region = NULL;
-
-#ifdef HAVE_SHAPE
- if (META_DISPLAY_HAS_SHAPE (window->display))
- {
- /* Translate the set of XShape rectangles that we
- * get from the X server to a cairo_region. */
- XRectangle *rects = NULL;
- int n_rects, ordering;
-
- int x_bounding, y_bounding, x_clip, y_clip;
- unsigned w_bounding, h_bounding, w_clip, h_clip;
- int bounding_shaped, clip_shaped;
-
- meta_error_trap_push (window->display);
- XShapeQueryExtents (window->display->xdisplay, window->xwindow,
- &bounding_shaped, &x_bounding, &y_bounding,
- &w_bounding, &h_bounding,
- &clip_shaped, &x_clip, &y_clip,
- &w_clip, &h_clip);
-
- if (bounding_shaped)
- {
- rects = XShapeGetRectangles (window->display->xdisplay,
- window->xwindow,
- ShapeBounding,
- &n_rects,
- &ordering);
- }
- meta_error_trap_pop (window->display);
-
- if (rects)
- {
- region = region_create_from_x_rectangles (rects, n_rects);
- XFree (rects);
- }
- }
-#endif /* HAVE_SHAPE */
-
- if (region != NULL)
- {
- cairo_rectangle_int_t client_area;
-
- client_area.x = 0;
- client_area.y = 0;
- client_area.width = window->rect.width;
- client_area.height = window->rect.height;
-
- /* The shape we get back from the client may have coordinates
- * outside of the frame. The X SHAPE Extension requires that
- * the overall shape the client provides never exceeds the
- * "bounding rectangle" of the window -- the shape that the
- * window would have gotten if it was unshaped. In our case,
- * this is simply the client area.
- */
- cairo_region_intersect_rectangle (region, &client_area);
- }
-
- meta_window_set_shape_region (window, region);
- cairo_region_destroy (region);
-}
-
static void
redraw_icon (MetaWindow *window)
{
@@ -10483,23 +9393,6 @@ meta_window_same_application (MetaWindow *window,
group==other_group;
}
-/* Generally meta_window_same_application() is a better idea
- * of "sameness", since it handles the case where multiple apps
- * want to look like the same app or the same app wants to look
- * like multiple apps, but in the case of workarounds for legacy
- * applications (which likely aren't setting the group properly
- * anyways), it may be desirable to check this as well.
- */
-static gboolean
-meta_window_same_client (MetaWindow *window,
- MetaWindow *other_window)
-{
- int resource_mask = window->display->xdisplay->resource_mask;
-
- return ((window->xwindow & ~resource_mask) ==
- (other_window->xwindow & ~resource_mask));
-}
-
void
meta_window_refresh_resize_popup (MetaWindow *window)
{