window-x11: Move meta_window_new to window-x11.c and rename
This commit is contained in:
parent
b09e1399c0
commit
8905bd2280
@ -2817,15 +2817,15 @@ handle_other_xevent (MetaDisplay *display,
|
|||||||
if (display->compositor && window == NULL
|
if (display->compositor && window == NULL
|
||||||
&& meta_display_screen_for_root (display, event->xmap.event))
|
&& meta_display_screen_for_root (display, event->xmap.event))
|
||||||
{
|
{
|
||||||
window = meta_window_new (display, event->xmap.window,
|
window = meta_window_x11_new (display, event->xmap.window,
|
||||||
FALSE, META_COMP_EFFECT_CREATE);
|
FALSE, META_COMP_EFFECT_CREATE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MapRequest:
|
case MapRequest:
|
||||||
if (window == NULL)
|
if (window == NULL)
|
||||||
{
|
{
|
||||||
window = meta_window_new (display, event->xmaprequest.window,
|
window = meta_window_x11_new (display, event->xmaprequest.window,
|
||||||
FALSE, META_COMP_EFFECT_CREATE);
|
FALSE, META_COMP_EFFECT_CREATE);
|
||||||
}
|
}
|
||||||
/* if frame was receiver it's some malicious send event or something */
|
/* if frame was receiver it's some malicious send event or something */
|
||||||
else if (!frame_was_receiver && window)
|
else if (!frame_was_receiver && window)
|
||||||
|
@ -896,8 +896,8 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
|||||||
|
|
||||||
for (i = 0; i < n_children; ++i)
|
for (i = 0; i < n_children; ++i)
|
||||||
{
|
{
|
||||||
meta_window_new (screen->display, children[i].x11.xwindow, TRUE,
|
meta_window_x11_new (screen->display, children[i].x11.xwindow, TRUE,
|
||||||
META_COMP_EFFECT_NONE);
|
META_COMP_EFFECT_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (children);
|
g_free (children);
|
||||||
|
@ -506,12 +506,22 @@ 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_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)
|
#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_new (MetaDisplay *display,
|
MetaWindow * _meta_window_shared_new (MetaDisplay *display,
|
||||||
Window xwindow,
|
MetaScreen *screen,
|
||||||
gboolean must_be_viewable,
|
MetaWindowClientType client_type,
|
||||||
MetaCompEffect effect);
|
MetaWaylandSurface *surface,
|
||||||
MetaWindow *meta_window_new_for_wayland (MetaDisplay *display,
|
Window xwindow,
|
||||||
|
gulong existing_wm_state,
|
||||||
|
MetaCompEffect effect,
|
||||||
|
XWindowAttributes *attrs);
|
||||||
|
|
||||||
|
MetaWindow * meta_window_x11_new (MetaDisplay *display,
|
||||||
|
Window xwindow,
|
||||||
|
gboolean must_be_viewable,
|
||||||
|
MetaCompEffect effect);
|
||||||
|
MetaWindow * meta_window_wayland_new (MetaDisplay *display,
|
||||||
MetaWaylandSurface *surface);
|
MetaWaylandSurface *surface);
|
||||||
|
|
||||||
void meta_window_unmanage (MetaWindow *window,
|
void meta_window_unmanage (MetaWindow *window,
|
||||||
guint32 timestamp);
|
guint32 timestamp);
|
||||||
void meta_window_calc_showing (MetaWindow *window);
|
void meta_window_calc_showing (MetaWindow *window);
|
||||||
|
@ -846,7 +846,7 @@ reload_mwm_hints (MetaWindow *window,
|
|||||||
|
|
||||||
meta_window_recalc_features (window);
|
meta_window_recalc_features (window);
|
||||||
|
|
||||||
/* We do all this anyhow at the end of meta_window_new() */
|
/* We do all this anyhow at the end of meta_window_x11_new() */
|
||||||
if (!window->constructing)
|
if (!window->constructing)
|
||||||
{
|
{
|
||||||
if (window->decorated)
|
if (window->decorated)
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <X11/extensions/Xcomposite.h>
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
#include <meta/common.h>
|
#include <meta/common.h>
|
||||||
#include <meta/errors.h>
|
#include <meta/errors.h>
|
||||||
#include <meta/prefs.h>
|
#include <meta/prefs.h>
|
||||||
@ -1146,3 +1149,343 @@ meta_window_x11_client_message (MetaWindow *window,
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_wm_state_on_xwindow (MetaDisplay *display,
|
||||||
|
Window xwindow,
|
||||||
|
int state)
|
||||||
|
{
|
||||||
|
unsigned long data[2];
|
||||||
|
|
||||||
|
/* Mutter doesn't use icon windows, so data[1] should be None
|
||||||
|
* according to the ICCCM 2.0 Section 4.1.3.1.
|
||||||
|
*/
|
||||||
|
data[0] = state;
|
||||||
|
data[1] = None;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
XChangeProperty (display->xdisplay, xwindow,
|
||||||
|
display->atom_WM_STATE,
|
||||||
|
display->atom_WM_STATE,
|
||||||
|
32, PropModeReplace, (guchar*) data, 2);
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_x11_set_wm_state (MetaWindow *window)
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
|
||||||
|
if (window->withdrawn)
|
||||||
|
state = WithdrawnState;
|
||||||
|
else if (window->iconic)
|
||||||
|
state = IconicState;
|
||||||
|
else
|
||||||
|
state = NormalState;
|
||||||
|
|
||||||
|
set_wm_state_on_xwindow (window->display, window->xwindow, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The MUTTER_WM_CLASS_FILTER environment variable is designed for
|
||||||
|
* performance and regression testing environments where we want to do
|
||||||
|
* tests with only a limited set of windows and ignore all other windows
|
||||||
|
*
|
||||||
|
* When it is set to a comma separated list of WM_CLASS class names, all
|
||||||
|
* windows not matching the list will be ignored.
|
||||||
|
*
|
||||||
|
* Returns TRUE if window has been filtered out and should be ignored.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
maybe_filter_xwindow (MetaDisplay *display,
|
||||||
|
Window xwindow,
|
||||||
|
gboolean must_be_viewable,
|
||||||
|
XWindowAttributes *attrs)
|
||||||
|
{
|
||||||
|
static char **filter_wm_classes = NULL;
|
||||||
|
static gboolean initialized = FALSE;
|
||||||
|
XClassHint class_hint;
|
||||||
|
gboolean filtered;
|
||||||
|
Status success;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
const char *filter_string = g_getenv ("MUTTER_WM_CLASS_FILTER");
|
||||||
|
if (filter_string)
|
||||||
|
filter_wm_classes = g_strsplit (filter_string, ",", -1);
|
||||||
|
initialized = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filter_wm_classes || !filter_wm_classes[0])
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
filtered = TRUE;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
success = XGetClassHint (display->xdisplay, xwindow, &class_hint);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
for (i = 0; filter_wm_classes[i]; i++)
|
||||||
|
{
|
||||||
|
if (strcmp (class_hint.res_class, filter_wm_classes[i]) == 0)
|
||||||
|
{
|
||||||
|
filtered = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree (class_hint.res_name);
|
||||||
|
XFree (class_hint.res_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filtered)
|
||||||
|
{
|
||||||
|
/* We want to try and get the window managed by the next WM that come along,
|
||||||
|
* so we need to make sure that windows that are requested to be mapped while
|
||||||
|
* Mutter is running (!must_be_viewable), or windows already viewable at startup
|
||||||
|
* get a non-withdrawn WM_STATE property. Previously unmapped windows are left
|
||||||
|
* with whatever WM_STATE property they had.
|
||||||
|
*/
|
||||||
|
if (!must_be_viewable || attrs->map_state == IsViewable)
|
||||||
|
{
|
||||||
|
gulong old_state;
|
||||||
|
|
||||||
|
if (!meta_prop_get_cardinal_with_atom_type (display, xwindow,
|
||||||
|
display->atom_WM_STATE,
|
||||||
|
display->atom_WM_STATE,
|
||||||
|
&old_state))
|
||||||
|
old_state = WithdrawnState;
|
||||||
|
|
||||||
|
if (old_state == WithdrawnState)
|
||||||
|
set_wm_state_on_xwindow (display, xwindow, NormalState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure filtered windows are hidden from view */
|
||||||
|
XUnmapWindow (display->xdisplay, xwindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_our_xwindow (MetaDisplay *display,
|
||||||
|
MetaScreen *screen,
|
||||||
|
Window xwindow,
|
||||||
|
XWindowAttributes *attrs)
|
||||||
|
{
|
||||||
|
if (xwindow == screen->no_focus_window)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (xwindow == screen->flash_window)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (xwindow == screen->wm_sn_selection_window)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (xwindow == screen->wm_cm_selection_window)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (xwindow == screen->guard_window)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (display->compositor && xwindow == XCompositeGetOverlayWindow (display->xdisplay, screen->xroot))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Any windows created via meta_create_offscreen_window */
|
||||||
|
if (attrs->override_redirect && attrs->x == -100 && attrs->height == -100 && attrs->width == 1 && attrs->height == 1)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_VERBOSE_MODE
|
||||||
|
static const char*
|
||||||
|
wm_state_to_string (int state)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case NormalState:
|
||||||
|
return "NormalState";
|
||||||
|
case IconicState:
|
||||||
|
return "IconicState";
|
||||||
|
case WithdrawnState:
|
||||||
|
return "WithdrawnState";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MetaWindow *
|
||||||
|
meta_window_x11_new (MetaDisplay *display,
|
||||||
|
Window xwindow,
|
||||||
|
gboolean must_be_viewable,
|
||||||
|
MetaCompEffect effect)
|
||||||
|
{
|
||||||
|
XWindowAttributes attrs;
|
||||||
|
MetaScreen *screen = NULL;
|
||||||
|
GSList *tmp;
|
||||||
|
gulong existing_wm_state;
|
||||||
|
MetaWindow *window = NULL;
|
||||||
|
gulong event_mask;
|
||||||
|
|
||||||
|
meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
|
||||||
|
|
||||||
|
if (meta_display_xwindow_is_a_no_focus_window (display, xwindow))
|
||||||
|
{
|
||||||
|
meta_verbose ("Not managing no_focus_window 0x%lx\n",
|
||||||
|
xwindow);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_error_trap_push (display); /* Push a trap over all of window
|
||||||
|
* creation, to reduce XSync() calls
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This function executes without any server grabs held. This means that
|
||||||
|
* the window could have already gone away, or could go away at any point,
|
||||||
|
* so we must be careful with X error handling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!XGetWindowAttributes (display->xdisplay, xwindow, &attrs))
|
||||||
|
{
|
||||||
|
meta_verbose ("Failed to get attributes for window 0x%lx\n",
|
||||||
|
xwindow);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (tmp = display->screens; tmp != NULL; tmp = tmp->next)
|
||||||
|
{
|
||||||
|
MetaScreen *scr = tmp->data;
|
||||||
|
|
||||||
|
if (scr->xroot == attrs.root)
|
||||||
|
{
|
||||||
|
screen = tmp->data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (screen);
|
||||||
|
|
||||||
|
if (is_our_xwindow (display, screen, xwindow, &attrs))
|
||||||
|
{
|
||||||
|
meta_verbose ("Not managing our own windows\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe_filter_xwindow (display, xwindow, must_be_viewable, &attrs))
|
||||||
|
{
|
||||||
|
meta_verbose ("Not managing filtered window\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
existing_wm_state = WithdrawnState;
|
||||||
|
if (must_be_viewable && attrs.map_state != IsViewable)
|
||||||
|
{
|
||||||
|
/* Only manage if WM_STATE is IconicState or NormalState */
|
||||||
|
gulong state;
|
||||||
|
|
||||||
|
/* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */
|
||||||
|
if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow,
|
||||||
|
display->atom_WM_STATE,
|
||||||
|
display->atom_WM_STATE,
|
||||||
|
&state) &&
|
||||||
|
(state == IconicState || state == NormalState)))
|
||||||
|
{
|
||||||
|
meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
existing_wm_state = state;
|
||||||
|
meta_verbose ("WM_STATE of %lx = %s\n", xwindow,
|
||||||
|
wm_state_to_string (existing_wm_state));
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_error_trap_push_with_return (display);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XAddToSaveSet can only be called on windows created by a different
|
||||||
|
* client. with Mutter we want to be able to create manageable windows
|
||||||
|
* from within the process (such as a dummy desktop window). As we do not
|
||||||
|
* want this call failing to prevent the window from being managed, we
|
||||||
|
* call this before creating the return-checked error trap.
|
||||||
|
*/
|
||||||
|
XAddToSaveSet (display->xdisplay, xwindow);
|
||||||
|
|
||||||
|
meta_error_trap_push_with_return (display);
|
||||||
|
|
||||||
|
event_mask = PropertyChangeMask | ColormapChangeMask;
|
||||||
|
if (attrs.override_redirect)
|
||||||
|
event_mask |= StructureNotifyMask;
|
||||||
|
|
||||||
|
/* If the window is from this client (a menu, say) we need to augment
|
||||||
|
* the event mask, not replace it. For windows from other clients,
|
||||||
|
* attrs.your_event_mask will be empty at this point.
|
||||||
|
*/
|
||||||
|
XSelectInput (display->xdisplay, xwindow, attrs.your_event_mask | event_mask);
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||||
|
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||||
|
|
||||||
|
meta_core_add_old_event_mask (display->xdisplay, xwindow, &mask);
|
||||||
|
|
||||||
|
XISetMask (mask.mask, XI_Enter);
|
||||||
|
XISetMask (mask.mask, XI_Leave);
|
||||||
|
XISetMask (mask.mask, XI_FocusIn);
|
||||||
|
XISetMask (mask.mask, XI_FocusOut);
|
||||||
|
|
||||||
|
XISelectEvents (display->xdisplay, xwindow, &mask, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get rid of any borders */
|
||||||
|
if (attrs.border_width != 0)
|
||||||
|
XSetWindowBorderWidth (display->xdisplay, xwindow, 0);
|
||||||
|
|
||||||
|
/* Get rid of weird gravities */
|
||||||
|
if (attrs.win_gravity != NorthWestGravity)
|
||||||
|
{
|
||||||
|
XSetWindowAttributes set_attrs;
|
||||||
|
|
||||||
|
set_attrs.win_gravity = NorthWestGravity;
|
||||||
|
|
||||||
|
XChangeWindowAttributes (display->xdisplay,
|
||||||
|
xwindow,
|
||||||
|
CWWinGravity,
|
||||||
|
&set_attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meta_error_trap_pop_with_return (display) != Success)
|
||||||
|
{
|
||||||
|
meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n",
|
||||||
|
xwindow);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
window = _meta_window_shared_new (display,
|
||||||
|
screen,
|
||||||
|
META_WINDOW_CLIENT_TYPE_X11,
|
||||||
|
NULL,
|
||||||
|
xwindow,
|
||||||
|
existing_wm_state,
|
||||||
|
effect,
|
||||||
|
&attrs);
|
||||||
|
|
||||||
|
/* When running as an X compositor, we can simply show the window now.
|
||||||
|
*
|
||||||
|
* When running as a Wayland compositor, we need to wait until we see
|
||||||
|
* the Wayland surface appear. We will later call meta_window_set_surface_mapped()
|
||||||
|
* to show the window in our in our set_surface_id implementation */
|
||||||
|
if (!meta_is_wayland_compositor ())
|
||||||
|
meta_window_set_surface_mapped (window, TRUE);
|
||||||
|
|
||||||
|
meta_error_trap_pop (display); /* pop the XSync()-reducing trap */
|
||||||
|
return window;
|
||||||
|
|
||||||
|
error:
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -26,13 +26,14 @@
|
|||||||
#include <meta/window.h>
|
#include <meta/window.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
void meta_window_x11_set_net_wm_state (MetaWindow *window);
|
void meta_window_x11_set_net_wm_state (MetaWindow *window);
|
||||||
|
void meta_window_x11_set_wm_state (MetaWindow *window);
|
||||||
|
|
||||||
void meta_window_x11_update_role (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_net_wm_type (MetaWindow *window);
|
||||||
void meta_window_x11_update_opaque_region (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_input_region (MetaWindow *window);
|
||||||
void meta_window_x11_update_shape_region (MetaWindow *window);
|
void meta_window_x11_update_shape_region (MetaWindow *window);
|
||||||
|
|
||||||
gboolean meta_window_x11_configure_request (MetaWindow *window,
|
gboolean meta_window_x11_configure_request (MetaWindow *window,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
@ -58,8 +58,6 @@
|
|||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <X11/extensions/Xcomposite.h>
|
|
||||||
|
|
||||||
#include "meta-wayland-private.h"
|
#include "meta-wayland-private.h"
|
||||||
#include "meta/compositor-mutter.h"
|
#include "meta/compositor-mutter.h"
|
||||||
|
|
||||||
@ -95,9 +93,6 @@ static void ping_data_free (MetaPingData *ping_data);
|
|||||||
static void update_sm_hints (MetaWindow *window);
|
static void update_sm_hints (MetaWindow *window);
|
||||||
static void update_net_frame_extents (MetaWindow *window);
|
static void update_net_frame_extents (MetaWindow *window);
|
||||||
static void invalidate_work_areas (MetaWindow *window);
|
static void invalidate_work_areas (MetaWindow *window);
|
||||||
static void set_wm_state_on_xwindow (MetaDisplay *display,
|
|
||||||
Window xwindow,
|
|
||||||
int state);
|
|
||||||
static void set_wm_state (MetaWindow *window);
|
static void set_wm_state (MetaWindow *window);
|
||||||
static void set_net_wm_state (MetaWindow *window);
|
static void set_net_wm_state (MetaWindow *window);
|
||||||
static void meta_window_set_above (MetaWindow *window,
|
static void meta_window_set_above (MetaWindow *window,
|
||||||
@ -622,24 +617,6 @@ meta_window_init (MetaWindow *self)
|
|||||||
meta_prefs_add_listener (prefs_changed_callback, self);
|
meta_prefs_add_listener (prefs_changed_callback, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_VERBOSE_MODE
|
|
||||||
static const char*
|
|
||||||
wm_state_to_string (int state)
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case NormalState:
|
|
||||||
return "NormalState";
|
|
||||||
case IconicState:
|
|
||||||
return "IconicState";
|
|
||||||
case WithdrawnState:
|
|
||||||
return "WithdrawnState";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_desktop_or_dock_foreach (MetaWindow *window,
|
is_desktop_or_dock_foreach (MetaWindow *window,
|
||||||
void *data)
|
void *data)
|
||||||
@ -686,121 +663,6 @@ maybe_leave_show_desktop_mode (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The MUTTER_WM_CLASS_FILTER environment variable is designed for
|
|
||||||
* performance and regression testing environments where we want to do
|
|
||||||
* tests with only a limited set of windows and ignore all other windows
|
|
||||||
*
|
|
||||||
* When it is set to a comma separated list of WM_CLASS class names, all
|
|
||||||
* windows not matching the list will be ignored.
|
|
||||||
*
|
|
||||||
* Returns TRUE if window has been filtered out and should be ignored.
|
|
||||||
*/
|
|
||||||
static gboolean
|
|
||||||
maybe_filter_xwindow (MetaDisplay *display,
|
|
||||||
Window xwindow,
|
|
||||||
gboolean must_be_viewable,
|
|
||||||
XWindowAttributes *attrs)
|
|
||||||
{
|
|
||||||
static char **filter_wm_classes = NULL;
|
|
||||||
static gboolean initialized = FALSE;
|
|
||||||
XClassHint class_hint;
|
|
||||||
gboolean filtered;
|
|
||||||
Status success;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!initialized)
|
|
||||||
{
|
|
||||||
const char *filter_string = g_getenv ("MUTTER_WM_CLASS_FILTER");
|
|
||||||
if (filter_string)
|
|
||||||
filter_wm_classes = g_strsplit (filter_string, ",", -1);
|
|
||||||
initialized = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filter_wm_classes || !filter_wm_classes[0])
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
filtered = TRUE;
|
|
||||||
|
|
||||||
meta_error_trap_push (display);
|
|
||||||
success = XGetClassHint (display->xdisplay, xwindow, &class_hint);
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
for (i = 0; filter_wm_classes[i]; i++)
|
|
||||||
{
|
|
||||||
if (strcmp (class_hint.res_class, filter_wm_classes[i]) == 0)
|
|
||||||
{
|
|
||||||
filtered = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree (class_hint.res_name);
|
|
||||||
XFree (class_hint.res_class);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filtered)
|
|
||||||
{
|
|
||||||
/* We want to try and get the window managed by the next WM that come along,
|
|
||||||
* so we need to make sure that windows that are requested to be mapped while
|
|
||||||
* Mutter is running (!must_be_viewable), or windows already viewable at startup
|
|
||||||
* get a non-withdrawn WM_STATE property. Previously unmapped windows are left
|
|
||||||
* with whatever WM_STATE property they had.
|
|
||||||
*/
|
|
||||||
if (!must_be_viewable || attrs->map_state == IsViewable)
|
|
||||||
{
|
|
||||||
gulong old_state;
|
|
||||||
|
|
||||||
if (!meta_prop_get_cardinal_with_atom_type (display, xwindow,
|
|
||||||
display->atom_WM_STATE,
|
|
||||||
display->atom_WM_STATE,
|
|
||||||
&old_state))
|
|
||||||
old_state = WithdrawnState;
|
|
||||||
|
|
||||||
if (old_state == WithdrawnState)
|
|
||||||
set_wm_state_on_xwindow (display, xwindow, NormalState);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure filtered windows are hidden from view */
|
|
||||||
XUnmapWindow (display->xdisplay, xwindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_error_trap_pop (display);
|
|
||||||
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
is_our_xwindow (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
Window xwindow,
|
|
||||||
XWindowAttributes *attrs)
|
|
||||||
{
|
|
||||||
if (xwindow == screen->no_focus_window)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (xwindow == screen->flash_window)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (xwindow == screen->wm_sn_selection_window)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (xwindow == screen->wm_cm_selection_window)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (xwindow == screen->guard_window)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (display->compositor && xwindow == XCompositeGetOverlayWindow (display->xdisplay, screen->xroot))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* Any windows created via meta_create_offscreen_window */
|
|
||||||
if (attrs->override_redirect && attrs->x == -100 && attrs->height == -100 && attrs->width == 1 && attrs->height == 1)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_window_should_attach_to_parent (MetaWindow *window)
|
meta_window_should_attach_to_parent (MetaWindow *window)
|
||||||
{
|
{
|
||||||
@ -826,15 +688,15 @@ meta_window_should_attach_to_parent (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaWindow*
|
MetaWindow *
|
||||||
meta_window_new_shared (MetaDisplay *display,
|
_meta_window_shared_new (MetaDisplay *display,
|
||||||
MetaScreen *screen,
|
MetaScreen *screen,
|
||||||
MetaWindowClientType client_type,
|
MetaWindowClientType client_type,
|
||||||
MetaWaylandSurface *surface,
|
MetaWaylandSurface *surface,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
gulong existing_wm_state,
|
gulong existing_wm_state,
|
||||||
MetaCompEffect effect,
|
MetaCompEffect effect,
|
||||||
XWindowAttributes *attrs)
|
XWindowAttributes *attrs)
|
||||||
{
|
{
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MetaWorkspace *space;
|
MetaWorkspace *space;
|
||||||
@ -1365,8 +1227,8 @@ meta_window_new_shared (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MetaWindow *
|
MetaWindow *
|
||||||
meta_window_new_for_wayland (MetaDisplay *display,
|
meta_window_wayland_new (MetaDisplay *display,
|
||||||
MetaWaylandSurface *surface)
|
MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
XWindowAttributes attrs;
|
XWindowAttributes attrs;
|
||||||
MetaScreen *scr = display->screens->data;
|
MetaScreen *scr = display->screens->data;
|
||||||
@ -1406,14 +1268,14 @@ meta_window_new_for_wayland (MetaDisplay *display,
|
|||||||
* creation, to reduce XSync() calls
|
* creation, to reduce XSync() calls
|
||||||
*/
|
*/
|
||||||
|
|
||||||
window = meta_window_new_shared (display,
|
window = _meta_window_shared_new (display,
|
||||||
scr,
|
scr,
|
||||||
META_WINDOW_CLIENT_TYPE_WAYLAND,
|
META_WINDOW_CLIENT_TYPE_WAYLAND,
|
||||||
surface,
|
surface,
|
||||||
None,
|
None,
|
||||||
WithdrawnState,
|
WithdrawnState,
|
||||||
META_COMP_EFFECT_CREATE,
|
META_COMP_EFFECT_CREATE,
|
||||||
&attrs);
|
&attrs);
|
||||||
|
|
||||||
meta_error_trap_pop (display); /* pop the XSync()-reducing trap */
|
meta_error_trap_pop (display); /* pop the XSync()-reducing trap */
|
||||||
|
|
||||||
@ -1426,179 +1288,6 @@ meta_window_new_for_wayland (MetaDisplay *display,
|
|||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaWindow*
|
|
||||||
meta_window_new (MetaDisplay *display,
|
|
||||||
Window xwindow,
|
|
||||||
gboolean must_be_viewable,
|
|
||||||
MetaCompEffect effect)
|
|
||||||
{
|
|
||||||
XWindowAttributes attrs;
|
|
||||||
MetaScreen *screen = NULL;
|
|
||||||
GSList *tmp;
|
|
||||||
gulong existing_wm_state;
|
|
||||||
MetaWindow *window;
|
|
||||||
gulong event_mask;
|
|
||||||
|
|
||||||
meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
|
|
||||||
|
|
||||||
if (meta_display_xwindow_is_a_no_focus_window (display, xwindow))
|
|
||||||
{
|
|
||||||
meta_verbose ("Not managing no_focus_window 0x%lx\n",
|
|
||||||
xwindow);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_error_trap_push (display); /* Push a trap over all of window
|
|
||||||
* creation, to reduce XSync() calls
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This function executes without any server grabs held. This means that
|
|
||||||
* the window could have already gone away, or could go away at any point,
|
|
||||||
* so we must be careful with X error handling.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!XGetWindowAttributes (display->xdisplay, xwindow, &attrs))
|
|
||||||
{
|
|
||||||
meta_verbose ("Failed to get attributes for window 0x%lx\n",
|
|
||||||
xwindow);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (tmp = display->screens; tmp != NULL; tmp = tmp->next)
|
|
||||||
{
|
|
||||||
MetaScreen *scr = tmp->data;
|
|
||||||
|
|
||||||
if (scr->xroot == attrs.root)
|
|
||||||
{
|
|
||||||
screen = tmp->data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_assert (screen);
|
|
||||||
|
|
||||||
if (is_our_xwindow (display, screen, xwindow, &attrs))
|
|
||||||
{
|
|
||||||
meta_verbose ("Not managing our own windows\n");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maybe_filter_xwindow (display, xwindow, must_be_viewable, &attrs))
|
|
||||||
{
|
|
||||||
meta_verbose ("Not managing filtered window\n");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
existing_wm_state = WithdrawnState;
|
|
||||||
if (must_be_viewable && attrs.map_state != IsViewable)
|
|
||||||
{
|
|
||||||
/* Only manage if WM_STATE is IconicState or NormalState */
|
|
||||||
gulong state;
|
|
||||||
|
|
||||||
/* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */
|
|
||||||
if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow,
|
|
||||||
display->atom_WM_STATE,
|
|
||||||
display->atom_WM_STATE,
|
|
||||||
&state) &&
|
|
||||||
(state == IconicState || state == NormalState)))
|
|
||||||
{
|
|
||||||
meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
existing_wm_state = state;
|
|
||||||
meta_verbose ("WM_STATE of %lx = %s\n", xwindow,
|
|
||||||
wm_state_to_string (existing_wm_state));
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_error_trap_push_with_return (display);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XAddToSaveSet can only be called on windows created by a different
|
|
||||||
* client. with Mutter we want to be able to create manageable windows
|
|
||||||
* from within the process (such as a dummy desktop window). As we do not
|
|
||||||
* want this call failing to prevent the window from being managed, we
|
|
||||||
* call this before creating the return-checked error trap.
|
|
||||||
*/
|
|
||||||
XAddToSaveSet (display->xdisplay, xwindow);
|
|
||||||
|
|
||||||
meta_error_trap_push_with_return (display);
|
|
||||||
|
|
||||||
event_mask = PropertyChangeMask | ColormapChangeMask;
|
|
||||||
if (attrs.override_redirect)
|
|
||||||
event_mask |= StructureNotifyMask;
|
|
||||||
|
|
||||||
/* If the window is from this client (a menu, say) we need to augment
|
|
||||||
* the event mask, not replace it. For windows from other clients,
|
|
||||||
* attrs.your_event_mask will be empty at this point.
|
|
||||||
*/
|
|
||||||
XSelectInput (display->xdisplay, xwindow, attrs.your_event_mask | event_mask);
|
|
||||||
|
|
||||||
{
|
|
||||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
|
||||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
|
||||||
|
|
||||||
meta_core_add_old_event_mask (display->xdisplay, xwindow, &mask);
|
|
||||||
|
|
||||||
XISetMask (mask.mask, XI_Enter);
|
|
||||||
XISetMask (mask.mask, XI_Leave);
|
|
||||||
XISetMask (mask.mask, XI_FocusIn);
|
|
||||||
XISetMask (mask.mask, XI_FocusOut);
|
|
||||||
|
|
||||||
XISelectEvents (display->xdisplay, xwindow, &mask, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get rid of any borders */
|
|
||||||
if (attrs.border_width != 0)
|
|
||||||
XSetWindowBorderWidth (display->xdisplay, xwindow, 0);
|
|
||||||
|
|
||||||
/* Get rid of weird gravities */
|
|
||||||
if (attrs.win_gravity != NorthWestGravity)
|
|
||||||
{
|
|
||||||
XSetWindowAttributes set_attrs;
|
|
||||||
|
|
||||||
set_attrs.win_gravity = NorthWestGravity;
|
|
||||||
|
|
||||||
XChangeWindowAttributes (display->xdisplay,
|
|
||||||
xwindow,
|
|
||||||
CWWinGravity,
|
|
||||||
&set_attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta_error_trap_pop_with_return (display) != Success)
|
|
||||||
{
|
|
||||||
meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n",
|
|
||||||
xwindow);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
window = meta_window_new_shared (display,
|
|
||||||
screen,
|
|
||||||
META_WINDOW_CLIENT_TYPE_X11,
|
|
||||||
NULL,
|
|
||||||
xwindow,
|
|
||||||
TRUE,
|
|
||||||
existing_wm_state,
|
|
||||||
effect,
|
|
||||||
&attrs);
|
|
||||||
|
|
||||||
/* When running as an X compositor, we can simply show the window now.
|
|
||||||
*
|
|
||||||
* When running as a Wayland compositor, we need to wait until we see
|
|
||||||
* the Wayland surface appear. We will later call meta_window_set_surface_mapped()
|
|
||||||
* to show the window in our in our set_surface_id implementation */
|
|
||||||
if (!meta_is_wayland_compositor ())
|
|
||||||
meta_window_set_surface_mapped (window, TRUE);
|
|
||||||
|
|
||||||
meta_error_trap_pop (display); /* pop the XSync()-reducing trap */
|
|
||||||
|
|
||||||
return window;
|
|
||||||
|
|
||||||
error:
|
|
||||||
meta_error_trap_pop (display);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function should only be called from the end of meta_window_new_with_attrs () */
|
/* This function should only be called from the end of meta_window_new_with_attrs () */
|
||||||
static void
|
static void
|
||||||
meta_window_apply_session_info (MetaWindow *window,
|
meta_window_apply_session_info (MetaWindow *window,
|
||||||
@ -2094,40 +1783,11 @@ meta_window_update_on_all_workspaces (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
set_wm_state_on_xwindow (MetaDisplay *display,
|
|
||||||
Window xwindow,
|
|
||||||
int state)
|
|
||||||
{
|
|
||||||
unsigned long data[2];
|
|
||||||
|
|
||||||
/* Mutter doesn't use icon windows, so data[1] should be None
|
|
||||||
* according to the ICCCM 2.0 Section 4.1.3.1.
|
|
||||||
*/
|
|
||||||
data[0] = state;
|
|
||||||
data[1] = None;
|
|
||||||
|
|
||||||
meta_error_trap_push (display);
|
|
||||||
XChangeProperty (display->xdisplay, xwindow,
|
|
||||||
display->atom_WM_STATE,
|
|
||||||
display->atom_WM_STATE,
|
|
||||||
32, PropModeReplace, (guchar*) data, 2);
|
|
||||||
meta_error_trap_pop (display);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_wm_state (MetaWindow *window)
|
set_wm_state (MetaWindow *window)
|
||||||
{
|
{
|
||||||
int state;
|
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
|
meta_window_x11_set_wm_state (window);
|
||||||
if (window->withdrawn)
|
|
||||||
state = WithdrawnState;
|
|
||||||
else if (window->iconic)
|
|
||||||
state = IconicState;
|
|
||||||
else
|
|
||||||
state = NormalState;
|
|
||||||
|
|
||||||
set_wm_state_on_xwindow (window->display, window->xwindow, state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -928,7 +928,7 @@ get_xdg_surface (struct wl_client *client,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->window = meta_window_new_for_wayland (meta_get_display (), surface);
|
surface->window = meta_window_wayland_new (meta_get_display (), surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -998,7 +998,7 @@ get_xdg_popup (struct wl_client *client,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->window = meta_window_new_for_wayland (meta_get_display (), surface);
|
surface->window = meta_window_wayland_new (meta_get_display (), surface);
|
||||||
surface->window->rect.x = parent_rect.x + x;
|
surface->window->rect.x = parent_rect.x + x;
|
||||||
surface->window->rect.y = parent_rect.y + y;
|
surface->window->rect.y = parent_rect.y + y;
|
||||||
surface->window->showing_for_first_time = FALSE;
|
surface->window->showing_for_first_time = FALSE;
|
||||||
|
Loading…
Reference in New Issue
Block a user