Compare commits

..

1 Commits

Author SHA1 Message Date
Ignacio Casal Quinteiro
f1484fa6c2 Add dcvviewer to xwayland_grab_default_access_rules
dcvviewer does not have native wayland support yet

https://gitlab.gnome.org/GNOME/mutter/merge_requests/587
2019-05-22 14:55:03 +00:00
47 changed files with 839 additions and 1137 deletions

View File

@@ -35,17 +35,15 @@ test-mutter:
variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
G_SLICE: "always-malloc"
MALLOC_CHECK_: "3"
NO_AT_BRIDGE: "1"
MALLOC_PERTURB_: "123"
script:
- dconf update
- mkdir -m 700 $XDG_RUNTIME_DIR
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
- >
env MALLOC_PERTURB_="$((RANDOM % 256 + 1))"
dbus-run-session -- xvfb-run -s '+iglx -noreset'
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --print-errorlogs --wrap catchsegv
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --wrap catchsegv
only:
- merge_requests
- /^.*$/

15
NEWS
View File

@@ -1,18 +1,3 @@
3.33.2
======
* Fix rendering lag on Xorg [Daniel; !520, !281]
* Misc. bug fixes and cleanups [Carlos, Marco, Jonas D., Florian, Niels,
Daniel, Benjamin, Jonas Å., Ignacio, Vasilis; #598, !576, !547, !578,
!583, !582, !469, !524, !119, !571, !584, !585, !586, #425]
Contributors:
Jonas Ådahl, Benjamin Berg, Jonas Dreßler, Carlos Garnacho, Niels De Graef,
Vasilis Liaskovitis, Florian Müllner, Ignacio Casal Quinteiro,
Marco Trevisan (Treviño), Daniel van Vugt
Translators:
Daniel Mustieles [es]
3.33.1
======
* Remove unused APIs and outdated driver support

View File

@@ -1975,7 +1975,6 @@ selection_paint (ClutterText *self,
else
{
/* Paint selection background first */
CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline);
PangoLayout *layout = clutter_text_get_layout (self);
CoglPath *selection_path = cogl_path_new ();
CoglColor cogl_color = { 0, };
@@ -1988,19 +1987,11 @@ selection_paint (ClutterText *self,
else
color = &priv->text_color;
cogl_color_init_from_4ub (&cogl_color,
color->red,
color->green,
color->blue,
paint_opacity * color->alpha / 255);
cogl_color_premultiply (&cogl_color);
cogl_pipeline_set_color (color_pipeline, &cogl_color);
clutter_text_foreach_selection_rectangle_prescaled (self,
add_selection_rectangle_to_path,
selection_path);
cogl_framebuffer_fill_path (fb, color_pipeline, selection_path);
cogl_path_fill (selection_path);
/* Paint selected text */
cogl_framebuffer_push_path_clip (fb, selection_path);

View File

@@ -114,12 +114,11 @@ test_destroy_destroy (ClutterActor *self)
test->tex = NULL;
}
g_assert_nonnull (test->children);
g_list_free_full (test->children, (GDestroyNotify) clutter_actor_destroy);
test->children = NULL;
if (CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy)
CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy (self);
g_assert_null (test->children);
}
static void

View File

@@ -460,7 +460,9 @@ cogl_path_fill (CoglPath *path);
* use while filling a path.</note>
*
* Stability: unstable
* Deprecated: 1.16: Use cogl_path_fill() instead
*/
COGL_DEPRECATED_FOR (cogl_path_fill)
void
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -490,7 +492,9 @@ cogl_path_stroke (CoglPath *path);
* regardless of the current transformation matrix.
*
* Stability: unstable
* Deprecated: 1.16: Use cogl_path_stroke() instead
*/
COGL_DEPRECATED_FOR (cogl_path_stroke)
void
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -525,7 +529,9 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
*
* Since: 1.8
* Stability: Unstable
* Deprecated: 1.16: Use cogl_framebuffer_push_path_clip() instead
*/
COGL_DEPRECATED_FOR (cogl_framebuffer_push_path_clip)
void
cogl_clip_push_from_path (CoglPath *path);

View File

@@ -1504,6 +1504,7 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
COGL_FRAMEBUFFER_STATE_CLIP;
}
/* XXX: deprecated */
void
cogl_clip_push_from_path (CoglPath *path)
{
@@ -1574,6 +1575,7 @@ _cogl_path_build_stroke_attribute_buffer (CoglPath *path)
data->stroke_n_attributes = n_attributes;
}
/* XXX: deprecated */
void
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -1586,6 +1588,7 @@ cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
_cogl_path_fill_nodes (path, framebuffer, pipeline, 0 /* flags */);
}
/* XXX: deprecated */
void
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,

View File

@@ -452,6 +452,9 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
_cogl_bitmask_destroy (&uniforms_state->changed_mask);
}
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
g_slice_free (CoglPipelineBigState, pipeline->big_state);
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
g_list_free_full (pipeline->layer_differences, cogl_object_unref);
@@ -461,9 +464,6 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
_cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets);
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
g_slice_free (CoglPipelineBigState, pipeline->big_state);
g_list_free (pipeline->deprecated_get_layers_list);
recursively_free_layer_caches (pipeline);

View File

@@ -29,7 +29,6 @@
*/
#include "cogl-config.h"
#include "cogl-defines.h"
#include <string.h>
#include <math.h>
@@ -309,66 +308,3 @@ cogl_pixel_format_to_string (CoglPixelFormat format)
g_assert_not_reached ();
}
#ifdef COGL_HAS_LIBDRM
typedef struct _PixelFormatMap {
uint32_t drm_format;
CoglPixelFormat cogl_format;
CoglTextureComponents cogl_components;
} PixelFormatMap;
static const PixelFormatMap pixel_format_map[] = {
/* DRM formats are defined as little-endian, not machine endian. */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
{ DRM_FORMAT_RGB565, COGL_PIXEL_FORMAT_RGB_565, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_ABGR8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_XBGR8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_ARGB8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_XRGB8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_BGRA8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_BGRX8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_RGBA8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_RGBX8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
#elif G_BYTE_ORDER == G_BIG_ENDIAN
/* DRM_FORMAT_RGB565 cannot be expressed. */
{ DRM_FORMAT_ABGR8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_XBGR8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_ARGB8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_XRGB8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_BGRA8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_BGRX8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_RGBA8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_RGBX8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
#else
#error "unexpected G_BYTE_ORDER"
#endif
};
gboolean
cogl_pixel_format_from_drm_format (uint32_t drm_format,
CoglPixelFormat *out_format,
CoglTextureComponents *out_components)
{
const size_t n = G_N_ELEMENTS (pixel_format_map);
size_t i;
for (i = 0; i < n; i++)
{
if (pixel_format_map[i].drm_format == drm_format)
break;
}
if (i == n)
return FALSE;
if (out_format)
*out_format = pixel_format_map[i].cogl_format;
if (out_components)
*out_components = pixel_format_map[i].cogl_components;
return TRUE;
}
#endif

View File

@@ -38,10 +38,6 @@
#include <stdint.h>
#include <stddef.h>
#ifdef COGL_HAS_LIBDRM
#include <drm_fourcc.h>
#endif
#include <cogl/cogl-defines.h>
#include <glib.h>
@@ -62,9 +58,6 @@ G_BEGIN_DECLS
*
* Other examples of factors that can influence the layout in memory are the
* system's endianness.
*
* This file also contains methods to map Linux DRM 4CC codes to
* CoglPixelFormats.
*/
#define COGL_A_BIT (1 << 4)
@@ -302,34 +295,6 @@ _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format);
const char *
cogl_pixel_format_to_string (CoglPixelFormat format);
#ifdef COGL_HAS_LIBDRM
/* added in libdrm 2.4.95 */
#ifndef DRM_FORMAT_INVALID
#define DRM_FORMAT_INVALID 0
#endif
/**
* cogl_pixel_format_from_drm_format:
* @drm_format: The DRM 4CC code (as specified in drm_fourcc.h)
* @out_format: (optional): The corresponding #CoglPixelFormat (if successful)
* @out_components: (optional): The corresponding #CoglTextureComponents (if
* sucessful)
*
* Does an internal lookup to find a #CoglPixelFormat that matches the given
* DRM 4CC code. If no such format could be found, this function will return
* %FALSE and the output parameters will stay untouched.
*
* Returns: %TRUE if a #CoglPixelFormat corresponding to the 4CC code exists,
* %FALSE otherwise.
*/
gboolean
cogl_pixel_format_from_drm_format (uint32_t drm_format,
CoglPixelFormat *out_format,
CoglTextureComponents *out_components);
#endif
G_END_DECLS
#endif /* __COGL_PIXEL_FORMAT_H__ */

View File

@@ -54,27 +54,41 @@ static char *_cogl_x11_display_name = NULL;
static GList *_cogl_xlib_renderers = NULL;
static void
_xlib_renderer_data_free (CoglXlibRenderer *data)
destroy_xlib_renderer_data (void *user_data)
{
CoglXlibRenderer *data = user_data;
if (data->xvisinfo)
XFree (data->xvisinfo);
g_slice_free (CoglXlibRenderer, data);
g_slice_free (CoglXlibRenderer, user_data);
}
CoglXlibRenderer *
_cogl_xlib_renderer_get_data (CoglRenderer *renderer)
{
static CoglUserDataKey key;
CoglXlibRenderer *data;
/* Constructs a CoglXlibRenderer struct on demand and attaches it to
the object using user data. It's done this way instead of using a
subclassing hierarchy in the winsys data because all EGL winsys's
need the EGL winsys data but only one of them wants the Xlib
data. */
if (!renderer->custom_winsys_user_data)
renderer->custom_winsys_user_data = g_slice_new0 (CoglXlibRenderer);
data = cogl_object_get_user_data (COGL_OBJECT (renderer), &key);
return renderer->custom_winsys_user_data;
if (data == NULL)
{
data = g_slice_new0 (CoglXlibRenderer);
cogl_object_set_user_data (COGL_OBJECT (renderer),
&key,
data,
destroy_xlib_renderer_data);
}
return data;
}
static void
@@ -556,8 +570,6 @@ _cogl_xlib_renderer_disconnect (CoglRenderer *renderer)
if (!renderer->foreign_xdpy && xlib_renderer->xdpy)
XCloseDisplay (xlib_renderer->xdpy);
g_clear_pointer (&renderer->custom_winsys_user_data, _xlib_renderer_data_free);
unregister_xlib_renderer (renderer);
}

View File

@@ -12,9 +12,6 @@ cdata.set('COGL_HAS_X11', have_x11)
cdata.set('COGL_HAS_X11_SUPPORT', have_x11)
cdata.set('COGL_HAS_XLIB', have_x11)
cdata.set('COGL_HAS_XLIB_SUPPORT', have_x11)
if have_native_backend
cdata.set('COGL_HAS_LIBDRM', libdrm_dep.found())
endif
cogl_defines_h = configure_file(
input: 'cogl-defines.h.meson',

View File

@@ -1,5 +1,5 @@
project('mutter', 'c',
version: '3.33.2',
version: '3.33.1',
meson_version: '>= 0.50.0',
license: 'GPLv2+'
)

View File

@@ -143,6 +143,6 @@ option('xwayland_path',
option('xwayland_grab_default_access_rules',
type: 'string',
value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr',
description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland'
value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr,dcvviewer',
description: 'Comma delimited list of applications resources or class allowed to issue X11 grabs in Xwayland'
)

View File

@@ -353,7 +353,7 @@ find_builtin_output (MetaInputMapper *mapper,
return panel != NULL;
}
static void
static gboolean
guess_candidates (MetaInputMapper *mapper,
MetaMapperInputInfo *input,
DeviceCandidates *info)
@@ -387,7 +387,15 @@ guess_candidates (MetaInputMapper *mapper,
find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]);
}
info->best = best;
if (best < N_OUTPUT_MATCHES)
{
info->best = best;
return TRUE;
}
else
{
return FALSE;
}
}
static void
@@ -400,7 +408,8 @@ mapping_helper_add (MappingHelper *helper,
info.input = input;
guess_candidates (mapper, input, &info);
if (!guess_candidates (mapper, input, &info))
return;
for (i = 0; i < helper->device_maps->len; i++)
{

View File

@@ -823,7 +823,6 @@ static void
cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
{
g_hash_table_destroy (cursor_priv->gpu_states);
g_free (cursor_priv);
}
static MetaCursorNativePrivate *

View File

@@ -73,6 +73,11 @@
#define EGL_DRM_MASTER_FD_EXT 0x333C
#endif
/* added in libdrm 2.4.95 */
#ifndef DRM_FORMAT_INVALID
#define DRM_FORMAT_INVALID 0
#endif
enum
{
PROP_0,
@@ -247,6 +252,11 @@ static void
free_next_secondary_bo (MetaGpuKms *gpu_kms,
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state);
static gboolean
cogl_pixel_format_from_drm_format (uint32_t drm_format,
CoglPixelFormat *out_format,
CoglTextureComponents *out_components);
static MetaBackend *
backend_from_renderer_native (MetaRendererNative *renderer_native)
{
@@ -2116,6 +2126,65 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
}
}
typedef struct _PixelFormatMap {
uint32_t drm_format;
CoglPixelFormat cogl_format;
CoglTextureComponents cogl_components;
} PixelFormatMap;
static const PixelFormatMap pixel_format_map[] = {
/* DRM formats are defined as little-endian, not machine endian. */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
{ DRM_FORMAT_RGB565, COGL_PIXEL_FORMAT_RGB_565, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_ABGR8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_XBGR8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_ARGB8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_XRGB8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_BGRA8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_BGRX8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_RGBA8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_RGBX8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
#elif G_BYTE_ORDER == G_BIG_ENDIAN
/* DRM_FORMAT_RGB565 cannot be expressed. */
{ DRM_FORMAT_ABGR8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_XBGR8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_ARGB8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_XRGB8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_BGRA8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_BGRX8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
{ DRM_FORMAT_RGBA8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA },
{ DRM_FORMAT_RGBX8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB },
#else
#error "unexpected G_BYTE_ORDER"
#endif
};
static gboolean
cogl_pixel_format_from_drm_format (uint32_t drm_format,
CoglPixelFormat *out_format,
CoglTextureComponents *out_components)
{
const size_t n = G_N_ELEMENTS (pixel_format_map);
size_t i;
for (i = 0; i < n; i++)
{
if (pixel_format_map[i].drm_format == drm_format)
break;
}
if (i == n)
return FALSE;
if (out_format)
*out_format = pixel_format_map[i].cogl_format;
if (out_components)
*out_components = pixel_format_map[i].cogl_components;
return TRUE;
}
static void
copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,

View File

@@ -357,6 +357,7 @@ handle_host_xevent (MetaBackend *backend,
{
switch (xkb_ev->any.xkb_type)
{
case XkbNewKeyboardNotify:
case XkbMapNotify:
keymap_changed (backend);
break;

View File

@@ -203,7 +203,7 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
height = logical_monitor->rect.height;
}
width = roundf (width * view_scale);
height = roundf (height * view_scale);
height = roundf (width * view_scale);
fake_onscreen = create_offscreen (cogl_context, width, height);

View File

@@ -692,8 +692,11 @@ meta_compositor_add_window (MetaCompositor *compositor,
{
MetaWindowActor *window_actor;
ClutterActor *window_group;
MetaDisplay *display = compositor->display;
GType window_actor_type = G_TYPE_INVALID;
meta_x11_error_trap_push (display->x11_display);
switch (window->client_type)
{
case META_WINDOW_CLIENT_TYPE_X11:
@@ -721,6 +724,8 @@ meta_compositor_add_window (MetaCompositor *compositor,
*/
compositor->windows = g_list_append (compositor->windows, window_actor);
sync_actor_stacking (compositor);
meta_x11_error_trap_pop (display->x11_display);
}
void

View File

@@ -55,8 +55,17 @@ meta_rectangle_free (MetaRectangle *rect)
g_free (rect);
}
G_DEFINE_BOXED_TYPE (MetaRectangle, meta_rectangle,
meta_rectangle_copy, meta_rectangle_free);
GType
meta_rectangle_get_type (void)
{
static GType type_id = 0;
if (!type_id)
type_id = g_boxed_type_register_static (g_intern_static_string ("MetaRectangle"),
(GBoxedCopyFunc) meta_rectangle_copy,
(GBoxedFreeFunc) meta_rectangle_free);
return type_id;
}
char*
meta_rectangle_to_string (const MetaRectangle *rect,

View File

@@ -140,6 +140,14 @@ struct _MetaDisplay
*/
guint allow_terminal_deactivation : 1;
/* If true, server->focus_serial refers to us changing the focus; in
* this case, we can ignore focus events that have exactly focus_serial,
* since we take care to make another request immediately afterwards.
* But if focus is being changed by another client, we have to accept
* multiple events with the same serial.
*/
guint focused_by_us : 1;
/*< private-ish >*/
GHashTable *stamps;
GHashTable *wayland_windows;
@@ -195,6 +203,10 @@ struct _MetaDisplay
MetaEdgeResistanceData *grab_edge_resistance_data;
unsigned int grab_last_user_action_was_snap;
/* we use property updates as sentinels for certain window focus events
* to avoid some race conditions on EnterNotify events
*/
int sentinel_counter;
int grab_resize_timeout_id;
MetaKeyBindingManager key_binding_manager;
@@ -351,6 +363,10 @@ gboolean meta_grab_op_is_resizing (MetaGrabOp op);
gboolean meta_grab_op_is_mouse (MetaGrabOp op);
gboolean meta_grab_op_is_keyboard (MetaGrabOp op);
void meta_display_increment_focus_sentinel (MetaDisplay *display);
void meta_display_decrement_focus_sentinel (MetaDisplay *display);
gboolean meta_display_focus_sentinel_clear (MetaDisplay *display);
void meta_display_queue_autoraise_callback (MetaDisplay *display,
MetaWindow *window);
void meta_display_remove_autoraise_callback (MetaDisplay *display);
@@ -363,7 +379,10 @@ gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);
void meta_display_sync_wayland_input_focus (MetaDisplay *display);
void meta_display_update_focus_window (MetaDisplay *display,
MetaWindow *window);
MetaWindow *window,
Window xwindow,
gulong serial,
gboolean focused_by_us);
void meta_display_sanity_check_timestamps (MetaDisplay *display,
guint32 timestamp);
@@ -427,8 +446,4 @@ MetaWindow *meta_display_get_window_from_id (MetaDisplay *display,
uint64_t window_id);
uint64_t meta_display_generate_window_id (MetaDisplay *display);
gboolean meta_display_init_x11 (MetaDisplay *display,
GError **error);
void meta_display_shutdown_x11 (MetaDisplay *display);
#endif

View File

@@ -49,7 +49,6 @@
#include "backends/meta-logical-monitor.h"
#include "backends/meta-stage-private.h"
#include "backends/x11/meta-backend-x11.h"
#include "backends/x11/cm/meta-backend-x11-cm.h"
#include "clutter/x11/clutter-x11.h"
#include "core/bell.h"
#include "core/boxes-private.h"
@@ -631,39 +630,6 @@ on_ui_scaling_factor_changed (MetaSettings *settings,
meta_display_reload_cursor (display);
}
gboolean
meta_display_init_x11 (MetaDisplay *display,
GError **error)
{
MetaX11Display *x11_display;
g_assert (display->x11_display == NULL);
x11_display = meta_x11_display_new (display, error);
if (!x11_display)
return FALSE;
display->x11_display = x11_display;
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
meta_x11_display_create_guard_window (x11_display);
if (!display->display_opening)
meta_display_manage_all_windows (display);
return TRUE;
}
void
meta_display_shutdown_x11 (MetaDisplay *display)
{
if (!display->x11_display)
return;
g_signal_emit (display, display_signals[X11_DISPLAY_CLOSING], 0);
g_object_run_dispose (G_OBJECT (display->x11_display));
g_clear_object (&display->x11_display);
}
/**
* meta_display_open:
*
@@ -679,6 +645,7 @@ meta_display_open (void)
{
GError *error = NULL;
MetaDisplay *display;
MetaX11Display *x11_display;
int i;
guint32 timestamp;
Window old_active_xwindow = None;
@@ -716,6 +683,7 @@ meta_display_open (void)
}
display->current_time = META_CURRENT_TIME;
display->sentinel_counter = 0;
display->grab_resize_timeout_id = 0;
display->grab_have_keyboard = FALSE;
@@ -725,7 +693,7 @@ meta_display_open (void)
display->grab_tile_mode = META_TILE_NONE;
display->grab_tile_monitor_number = -1;
meta_display_cleanup_edges (display);
display->grab_edge_resistance_data = NULL;
meta_display_init_keys (display);
@@ -762,8 +730,10 @@ meta_display_open (void)
if (meta_should_autostart_x11_display ())
{
if (!meta_display_init_x11 (display, &error))
g_error ("Failed to start Xwayland: %s", error->message);
x11_display = meta_x11_display_new (display, &error);
g_assert (x11_display != NULL); /* Required, for now */
display->x11_display = x11_display;
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
timestamp = display->x11_display->timestamp;
}
@@ -809,12 +779,10 @@ meta_display_open (void)
if (old_active_window)
meta_window_focus (old_active_window, timestamp);
else
meta_display_unset_input_focus (display, timestamp);
}
else
{
meta_display_unset_input_focus (display, timestamp);
meta_x11_display_focus_the_no_focus_window (display->x11_display, timestamp);
}
else if (display->x11_display)
meta_x11_display_focus_the_no_focus_window (display->x11_display, timestamp);
meta_idle_monitor_init_dbus ();
@@ -956,7 +924,7 @@ meta_display_close (MetaDisplay *display,
g_clear_object (&display->gesture_tracker);
g_clear_object (&display->stack);
g_clear_pointer (&display->stack, meta_stack_free);
g_clear_pointer (&display->stack_tracker,
meta_stack_tracker_free);
@@ -985,7 +953,12 @@ meta_display_close (MetaDisplay *display,
if (display->compositor)
meta_compositor_destroy (display->compositor);
meta_display_shutdown_x11 (display);
if (display->x11_display)
{
g_signal_emit (display, display_signals[X11_DISPLAY_CLOSING], 0);
g_object_run_dispose (G_OBJECT (display->x11_display));
g_clear_object (&display->x11_display);
}
meta_display_shutdown_keys (display);
@@ -1265,9 +1238,16 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
void
meta_display_update_focus_window (MetaDisplay *display,
MetaWindow *window)
MetaWindow *window,
Window xwindow,
gulong serial,
gboolean focused_by_us)
{
if (display->focus_window == window)
display->x11_display->focus_serial = serial;
display->focused_by_us = focused_by_us;
if (display->x11_display->focus_xwindow == xwindow &&
display->focus_window == window)
return;
if (display->focus_window)
@@ -1284,25 +1264,28 @@ meta_display_update_focus_window (MetaDisplay *display,
*/
previous = display->focus_window;
display->focus_window = NULL;
display->x11_display->focus_xwindow = None;
meta_window_set_focused_internal (previous, FALSE);
}
display->focus_window = window;
display->x11_display->focus_xwindow = xwindow;
if (display->focus_window)
{
meta_topic (META_DEBUG_FOCUS, "* Focus --> %s\n",
display->focus_window->desc);
meta_topic (META_DEBUG_FOCUS, "* Focus --> %s with serial %lu\n",
display->focus_window->desc, serial);
meta_window_set_focused_internal (display->focus_window, TRUE);
}
else
meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL\n");
meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial);
if (meta_is_wayland_compositor ())
meta_display_sync_wayland_input_focus (display);
g_object_notify (G_OBJECT (display), "focus-window");
meta_x11_display_update_active_window_hint (display->x11_display);
}
gboolean
@@ -1334,51 +1317,6 @@ meta_display_timestamp_too_old (MetaDisplay *display,
return FALSE;
}
void
meta_display_set_input_focus (MetaDisplay *display,
MetaWindow *window,
gboolean focus_frame,
guint32 timestamp)
{
if (meta_display_timestamp_too_old (display, &timestamp))
return;
if (display->x11_display)
{
MetaX11Display *x11_display = display->x11_display;
Window xwindow;
gulong serial;
meta_x11_error_trap_push (x11_display);
if (window)
xwindow = focus_frame ? window->frame->xwindow : window->xwindow;
else
xwindow = x11_display->no_focus_window;
meta_x11_display_set_input_focus (x11_display, xwindow, timestamp);
serial = XNextRequest (x11_display->xdisplay);
meta_x11_display_update_focus_window (x11_display, xwindow, serial, TRUE);
meta_x11_error_trap_pop (display->x11_display);
}
meta_display_update_focus_window (display, window);
display->last_focus_time = timestamp;
if (window == NULL || window != display->autoraise_window)
meta_display_remove_autoraise_callback (display);
}
void
meta_display_unset_input_focus (MetaDisplay *display,
guint32 timestamp)
{
meta_display_set_input_focus (display, NULL, FALSE, timestamp);
}
void
meta_display_register_wayland_window (MetaDisplay *display,
MetaWindow *window)
@@ -1740,17 +1678,14 @@ meta_display_begin_grab_op (MetaDisplay *display,
if (pointer_already_grabbed)
display->grab_have_pointer = TRUE;
if (META_IS_BACKEND_X11 (meta_get_backend ()) && display->x11_display)
{
/* Since grab operations often happen as a result of implicit
* pointer operations on the display X11 connection, we need
* to ungrab here to ensure that the backend's X11 can take
* the device grab. */
XIUngrabDevice (display->x11_display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
timestamp);
XSync (display->x11_display->xdisplay, False);
}
/* Since grab operations often happen as a result of implicit
* pointer operations on the display X11 connection, we need
* to ungrab here to ensure that the backend's X11 can take
* the device grab. */
XIUngrabDevice (display->x11_display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
timestamp);
XSync (display->x11_display->xdisplay, False);
if (meta_backend_grab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp))
display->grab_have_pointer = TRUE;
@@ -2555,6 +2490,37 @@ prefs_changed_callback (MetaPreference pref,
}
}
void
meta_display_increment_focus_sentinel (MetaDisplay *display)
{
unsigned long data[1];
data[0] = meta_display_get_current_time (display);
XChangeProperty (display->x11_display->xdisplay,
display->x11_display->xroot,
display->x11_display->atom__MUTTER_SENTINEL,
XA_CARDINAL,
32, PropModeReplace, (guchar*) data, 1);
display->sentinel_counter += 1;
}
void
meta_display_decrement_focus_sentinel (MetaDisplay *display)
{
display->sentinel_counter -= 1;
if (display->sentinel_counter < 0)
display->sentinel_counter = 0;
}
gboolean
meta_display_focus_sentinel_clear (MetaDisplay *display)
{
return (display->sentinel_counter == 0);
}
void
meta_display_sanity_check_timestamps (MetaDisplay *display,
guint32 timestamp)
@@ -2660,14 +2626,13 @@ meta_display_supports_extended_barriers (MetaDisplay *display)
return TRUE;
#endif
if (META_IS_BACKEND_X11_CM (meta_get_backend ()))
if (META_IS_BACKEND_X11 (meta_get_backend ()))
{
if (meta_is_wayland_compositor())
return FALSE;
return META_X11_DISPLAY_HAS_XINPUT_23 (display->x11_display);
return (META_X11_DISPLAY_HAS_XINPUT_23 (display->x11_display) &&
!meta_is_wayland_compositor());
}
g_assert_not_reached ();
return FALSE;
}

View File

@@ -606,6 +606,22 @@ meta_init (void)
meta_fatal ("Can't specify both SM save file and SM client id\n");
meta_main_loop = g_main_loop_new (NULL, FALSE);
/*
* We need to make sure the first client connecting to the X server
* (e.g. Xwayland started from meta_wayland_init() above) is a permanent one,
* so prepare the GDK X11 connection now already. Without doing this, if
* there are any functionality that relies on X11 after here before
* meta_display_open(), the X server will terminate itself when such a client
* disconnects before the permanent GDK client connects.
*/
if (meta_should_autostart_x11_display ())
{
GError *error = NULL;
if (!meta_x11_init_gdk_display (&error))
g_error ("Failed to open X11 display: %s", error->message);
}
}
/**

View File

@@ -600,6 +600,8 @@ meta_workspace_manager_calc_workspace_layout (MetaWorkspaceManager *workspace_ma
grid = g_new (int, grid_area);
current_row = -1;
current_col = -1;
i = 0;
switch (workspace_manager->starting_corner)

View File

@@ -29,13 +29,18 @@
#include "core/stack.h"
#include <X11/Xatom.h>
#include "backends/meta-logical-monitor.h"
#include "core/frame.h"
#include "core/meta-workspace-manager-private.h"
#include "core/window-private.h"
#include "meta/group.h"
#include "meta/meta-x11-errors.h"
#include "meta/prefs.h"
#include "meta/workspace.h"
#include "x11/group-private.h"
#include "x11/meta-x11-display-private.h"
#define WINDOW_HAS_TRANSIENT_TYPE(w) \
(w->type == META_WINDOW_DIALOG || \
@@ -47,141 +52,51 @@
#define WINDOW_TRANSIENT_FOR_WHOLE_GROUP(w) \
(WINDOW_HAS_TRANSIENT_TYPE (w) && w->transient_for == NULL)
static void stack_sync_to_xserver (MetaStack *stack);
static void meta_window_set_stack_position_no_sync (MetaWindow *window,
int position);
static void stack_do_window_deletions (MetaStack *stack);
static void stack_do_window_additions (MetaStack *stack);
static void stack_do_relayer (MetaStack *stack);
static void stack_do_constrain (MetaStack *stack);
static void stack_do_resort (MetaStack *stack);
static void stack_ensure_sorted (MetaStack *stack);
enum
{
PROP_DISPLAY = 1,
N_PROPS
};
enum
{
CHANGED,
WINDOW_ADDED,
WINDOW_REMOVED,
N_SIGNALS
};
static GParamSpec *pspecs[N_PROPS] = { 0 };
static guint signals[N_SIGNALS] = { 0 };
G_DEFINE_TYPE (MetaStack, meta_stack, G_TYPE_OBJECT)
static void
meta_stack_init (MetaStack *stack)
{
}
static void
meta_stack_finalize (GObject *object)
{
MetaStack *stack = META_STACK (object);
g_list_free (stack->sorted);
G_OBJECT_CLASS (meta_stack_parent_class)->finalize (object);
}
static void
meta_stack_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaStack *stack = META_STACK (object);
switch (prop_id)
{
case PROP_DISPLAY:
stack->display = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
meta_stack_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaStack *stack = META_STACK (object);
switch (prop_id)
{
case PROP_DISPLAY:
g_value_set_object (value, stack->display);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
meta_stack_class_init (MetaStackClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = meta_stack_set_property;
object_class->get_property = meta_stack_get_property;
object_class->finalize = meta_stack_finalize;
signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[WINDOW_ADDED] =
g_signal_new ("window-added",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, META_TYPE_WINDOW);
signals[WINDOW_REMOVED] =
g_signal_new ("window-removed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, META_TYPE_WINDOW);
pspecs[PROP_DISPLAY] =
g_param_spec_object ("display",
"Display",
"Display",
META_TYPE_DISPLAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, N_PROPS, pspecs);
}
MetaStack *
meta_stack_new (MetaDisplay *display)
{
return g_object_new (META_TYPE_STACK,
"display", display,
NULL);
MetaStack *stack;
stack = g_new (MetaStack, 1);
stack->display = display;
stack->xwindows = g_array_new (FALSE, FALSE, sizeof (Window));
stack->sorted = NULL;
stack->added = NULL;
stack->removed = NULL;
stack->freeze_count = 0;
stack->n_positions = 0;
stack->need_resort = FALSE;
stack->need_relayer = FALSE;
stack->need_constrain = FALSE;
return stack;
}
static void
meta_stack_changed (MetaStack *stack)
void
meta_stack_free (MetaStack *stack)
{
/* Bail out if frozen */
if (stack->freeze_count > 0)
return;
g_array_free (stack->xwindows, TRUE);
stack_ensure_sorted (stack);
g_signal_emit (stack, signals[CHANGED], 0);
g_list_free (stack->sorted);
g_list_free (stack->added);
g_list_free (stack->removed);
g_free (stack);
}
void
@@ -197,12 +112,7 @@ meta_stack_add (MetaStack *stack,
if (meta_window_is_in_stack (window))
meta_bug ("Window %s had stack position already\n", window->desc);
stack->sorted = g_list_prepend (stack->sorted, window);
stack->need_resort = TRUE; /* may not be needed as we add to top */
stack->need_constrain = TRUE;
stack->need_relayer = TRUE;
g_signal_emit (stack, signals[WINDOW_ADDED], 0, window);
stack->added = g_list_prepend (stack->added, window);
window->stack_position = stack->n_positions;
stack->n_positions += 1;
@@ -210,7 +120,7 @@ meta_stack_add (MetaStack *stack,
"Window %s has stack_position initialized to %d\n",
window->desc, window->stack_position);
meta_stack_changed (stack);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
}
@@ -230,11 +140,25 @@ meta_stack_remove (MetaStack *stack,
window->stack_position = -1;
stack->n_positions -= 1;
/* We don't know if it's been moved from "added" to "stack" yet */
stack->added = g_list_remove (stack->added, window);
stack->sorted = g_list_remove (stack->sorted, window);
g_signal_emit (stack, signals[WINDOW_REMOVED], 0, window);
/* stack->removed is only used to update stack->xwindows */
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
{
/* Remember the window ID to remove it from the stack array.
* The macro is safe to use: Window is guaranteed to be 32 bits, and
* GUINT_TO_POINTER says it only works on 32 bits.
*/
stack->removed = g_list_prepend (stack->removed,
GUINT_TO_POINTER (window->xwindow));
if (window->frame)
stack->removed = g_list_prepend (stack->removed,
GUINT_TO_POINTER (window->frame->xwindow));
}
meta_stack_changed (stack);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
}
@@ -245,7 +169,7 @@ meta_stack_update_layer (MetaStack *stack,
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
stack->need_relayer = TRUE;
meta_stack_changed (stack);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
}
@@ -256,7 +180,7 @@ meta_stack_update_transient (MetaStack *stack,
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
stack->need_constrain = TRUE;
meta_stack_changed (stack);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
}
@@ -286,7 +210,7 @@ meta_stack_raise (MetaStack *stack,
meta_window_set_stack_position_no_sync (window, max_stack_position);
meta_stack_changed (stack);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
}
@@ -315,7 +239,7 @@ meta_stack_lower (MetaStack *stack,
meta_window_set_stack_position_no_sync (window, min_stack_position);
meta_stack_changed (stack);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
}
@@ -331,7 +255,7 @@ meta_stack_thaw (MetaStack *stack)
g_return_if_fail (stack->freeze_count > 0);
stack->freeze_count -= 1;
meta_stack_changed (stack);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, NULL);
}
@@ -847,6 +771,99 @@ apply_constraints (Constraint **constraints,
g_slist_free (heads);
}
/**
* stack_do_window_deletions:
*
* Go through "deleted" and take the matching windows
* out of "windows".
*/
static void
stack_do_window_deletions (MetaStack *stack)
{
/* Do removals before adds, with paranoid idea that we might re-add
* the same window IDs.
*/
GList *tmp;
int i;
tmp = stack->removed;
while (tmp != NULL)
{
Window xwindow;
xwindow = GPOINTER_TO_UINT (tmp->data);
/* We go from the end figuring removals are more
* likely to be recent.
*/
i = stack->xwindows->len;
while (i > 0)
{
--i;
/* there's no guarantee we'll actually find windows to
* remove, e.g. the same xwindow could have been
* added/removed before we ever synced, and we put
* both the window->xwindow and window->frame->xwindow
* in the removal list.
*/
if (xwindow == g_array_index (stack->xwindows, Window, i))
{
g_array_remove_index (stack->xwindows, i);
goto next;
}
}
next:
tmp = tmp->next;
}
g_list_free (stack->removed);
stack->removed = NULL;
}
static void
stack_do_window_additions (MetaStack *stack)
{
GList *tmp;
gint n_added;
n_added = g_list_length (stack->added);
if (n_added > 0)
{
meta_topic (META_DEBUG_STACK,
"Adding %d windows to sorted list\n",
n_added);
/* stack->added has the most recent additions at the
* front of the list, so we need to reverse it
*/
stack->added = g_list_reverse (stack->added);
tmp = stack->added;
while (tmp != NULL)
{
MetaWindow *w;
w = tmp->data;
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
g_array_append_val (stack->xwindows, w->xwindow);
/* add to the main list */
stack->sorted = g_list_prepend (stack->sorted, w);
tmp = tmp->next;
}
stack->need_resort = TRUE; /* may not be needed as we add to top */
stack->need_constrain = TRUE;
stack->need_relayer = TRUE;
}
g_list_free (stack->added);
stack->added = NULL;
}
/**
* stack_do_relayer:
*
@@ -964,11 +981,131 @@ stack_do_resort (MetaStack *stack)
static void
stack_ensure_sorted (MetaStack *stack)
{
stack_do_window_deletions (stack);
stack_do_window_additions (stack);
stack_do_relayer (stack);
stack_do_constrain (stack);
stack_do_resort (stack);
}
/**
* stack_sync_to_server:
*
* Order the windows on the X server to be the same as in our structure.
* We do this using XRestackWindows if we don't know the previous order,
* or XConfigureWindow on a few particular windows if we do and can figure
* out the minimum set of changes. After that, we set __NET_CLIENT_LIST
* and __NET_CLIENT_LIST_STACKING.
*
* FIXME: Now that we have a good view of the stacking order on the server
* with MetaStackTracker it should be possible to do a simpler and better
* job of computing the minimal set of stacking requests needed.
*/
static void
stack_sync_to_xserver (MetaStack *stack)
{
GArray *x11_stacked;
GArray *all_root_children_stacked; /* wayland OR x11 */
GList *tmp;
GArray *hidden_stack_ids;
/* Bail out if frozen */
if (stack->freeze_count > 0)
return;
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
stack_ensure_sorted (stack);
/* Create stacked xwindow arrays, in bottom-to-top order
*/
x11_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (guint64));
hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (guint64));
meta_topic (META_DEBUG_STACK, "Bottom to top: ");
meta_push_no_msg_prefix ();
for (tmp = g_list_last(stack->sorted); tmp != NULL; tmp = tmp->prev)
{
MetaWindow *w = tmp->data;
guint64 top_level_window;
guint64 stack_id;
if (w->unmanaging)
continue;
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
w->layer, w->stack_position, w->desc);
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
g_array_append_val (x11_stacked, w->xwindow);
if (w->frame)
top_level_window = w->frame->xwindow;
else
top_level_window = w->xwindow;
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
stack_id = top_level_window;
else
stack_id = w->stamp;
/* We don't restack hidden windows along with the rest, though they are
* reflected in the _NET hints. Hidden windows all get pushed below
* the screens fullscreen guard_window. */
if (w->hidden)
{
g_array_append_val (hidden_stack_ids, stack_id);
continue;
}
g_array_append_val (all_root_children_stacked, stack_id);
}
meta_topic (META_DEBUG_STACK, "\n");
meta_pop_no_msg_prefix ();
/* The screen guard window sits above all hidden windows and acts as
* a barrier to input reaching these windows. */
guint64 guard_window_id = stack->display->x11_display->guard_window;
g_array_append_val (hidden_stack_ids, guard_window_id);
/* Sync to server */
meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
all_root_children_stacked->len);
meta_stack_tracker_restack_managed (stack->display->stack_tracker,
(guint64 *)all_root_children_stacked->data,
all_root_children_stacked->len);
meta_stack_tracker_restack_at_bottom (stack->display->stack_tracker,
(guint64 *)hidden_stack_ids->data,
hidden_stack_ids->len);
/* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */
XChangeProperty (stack->display->x11_display->xdisplay,
stack->display->x11_display->xroot,
stack->display->x11_display->atom__NET_CLIENT_LIST,
XA_WINDOW,
32, PropModeReplace,
(unsigned char *)stack->xwindows->data,
stack->xwindows->len);
XChangeProperty (stack->display->x11_display->xdisplay,
stack->display->x11_display->xroot,
stack->display->x11_display->atom__NET_CLIENT_LIST_STACKING,
XA_WINDOW,
32, PropModeReplace,
(unsigned char *)x11_stacked->data,
x11_stacked->len);
g_array_free (x11_stacked, TRUE);
g_array_free (hidden_stack_ids, TRUE);
g_array_free (all_root_children_stacked, TRUE);
}
MetaWindow*
meta_stack_get_top (MetaStack *stack)
{
@@ -1278,7 +1415,7 @@ meta_stack_set_positions (MetaStack *stack,
meta_topic (META_DEBUG_STACK,
"Reset the stack positions of (nearly) all windows\n");
meta_stack_changed (stack);
stack_sync_to_xserver (stack);
meta_stack_update_window_tile_matches (stack, NULL);
}
@@ -1343,7 +1480,7 @@ meta_window_set_stack_position (MetaWindow *window,
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
meta_window_set_stack_position_no_sync (window, position);
meta_stack_changed (window->display->stack);
stack_sync_to_xserver (window->display->stack);
meta_stack_update_window_tile_matches (window->display->stack,
workspace_manager->active_workspace);
}

View File

@@ -51,14 +51,38 @@
*/
struct _MetaStack
{
GObject parent;
/** The MetaDisplay containing this stack. */
MetaDisplay *display;
/**
* A sequence of all the Windows (X handles, not MetaWindows) of the windows
* we manage, sorted in order. Suitable to be passed into _NET_CLIENT_LIST.
*/
GArray *xwindows;
/** The MetaWindows of the windows we manage, sorted in order. */
GList *sorted;
/**
* MetaWindows waiting to be added to the "sorted" and "windows" list, after
* being added by meta_stack_add() and before being assimilated by
* stack_ensure_sorted().
*
* The order of the elements in this list is not important; what is important
* is the stack_position element of each window.
*/
GList *added;
/**
* Windows (X handles, not MetaWindows) waiting to be removed from the
* "windows" list, after being removed by meta_stack_remove() and before
* being assimilated by stack_ensure_sorted(). (We already removed them
* from the "sorted" list.)
*
* The order of the elements in this list is not important.
*/
GList *removed;
/**
* If this is zero, the local stack oughtn't to be brought up to date with
* the X server's stack, because it is in the middle of being updated.
@@ -97,9 +121,6 @@ struct _MetaStack
unsigned int need_constrain : 1;
};
#define META_TYPE_STACK (meta_stack_get_type ())
G_DECLARE_FINAL_TYPE (MetaStack, meta_stack, META, STACK, GObject)
/**
* meta_stack_new:
* @display: The MetaDisplay which will be the parent of this stack.
@@ -110,6 +131,14 @@ G_DECLARE_FINAL_TYPE (MetaStack, meta_stack, META, STACK, GObject)
*/
MetaStack *meta_stack_new (MetaDisplay *display);
/**
* meta_stack_free:
* @stack: The stack to destroy.
*
* Destroys and frees a MetaStack.
*/
void meta_stack_free (MetaStack *stack);
/**
* meta_stack_add:
* @stack: The stack to add it to

View File

@@ -581,9 +581,6 @@ struct _MetaWindowClass
gboolean (*is_stackable) (MetaWindow *window);
gboolean (*can_ping) (MetaWindow *window);
gboolean (*are_updates_frozen) (MetaWindow *window);
void (* map) (MetaWindow *window);
void (* unmap) (MetaWindow *window);
};
/* These differ from window->has_foo_func in that they consider

View File

@@ -809,10 +809,17 @@ sync_client_window_mapped (MetaWindow *window)
window->mapped = should_be_mapped;
if (window->mapped)
META_WINDOW_GET_CLASS (window)->map (window);
meta_x11_error_trap_push (window->display->x11_display);
if (should_be_mapped)
{
XMapWindow (window->display->x11_display->xdisplay, window->xwindow);
}
else
META_WINDOW_GET_CLASS (window)->unmap (window);
{
XUnmapWindow (window->display->x11_display->xdisplay, window->xwindow);
window->unmaps_pending ++;
}
meta_x11_error_trap_pop (window->display->x11_display);
}
static gboolean
@@ -1932,10 +1939,9 @@ idle_calc_showing (gpointer data)
while (tmp != NULL)
{
MetaWindow *window = tmp->data;
MetaDisplay *display = window->display;
if (display->x11_display && !display->mouse_mode)
meta_x11_display_increment_focus_sentinel (display->x11_display);
if (!window->display->mouse_mode)
meta_display_increment_focus_sentinel (window->display);
tmp = tmp->next;
}
@@ -2405,7 +2411,6 @@ meta_window_show (MetaWindow *window)
gboolean needs_stacking_adjustment;
MetaWindow *focus_window;
gboolean notify_demands_attention = FALSE;
MetaDisplay *display = window->display;
meta_topic (META_DEBUG_WINDOW_STATE,
"Showing window %s, shaded: %d iconic: %d placed: %d\n",
@@ -2572,7 +2577,7 @@ meta_window_show (MetaWindow *window)
meta_window_focus (window, timestamp);
}
else if (display->x11_display)
else
{
/* Prevent EnterNotify events in sloppy/mouse focus from
* erroneously focusing the window that had been denied
@@ -2580,7 +2585,7 @@ meta_window_show (MetaWindow *window)
* ideas for a better way to accomplish the same thing, but
* they're more involved so do it this way for now.
*/
meta_x11_display_increment_focus_sentinel (display->x11_display);
meta_display_increment_focus_sentinel (window->display);
}
}
@@ -3807,13 +3812,13 @@ maybe_move_attached_window (MetaWindow *window,
void *data)
{
if (window->hidden)
return G_SOURCE_CONTINUE;
return FALSE;
if (meta_window_is_attached_dialog (window) ||
meta_window_get_placement_rule (window))
meta_window_reposition (window);
return G_SOURCE_CONTINUE;
return FALSE;
}
/**
@@ -5373,6 +5378,50 @@ redraw_icon (MetaWindow *window)
meta_frame_queue_draw (window->frame);
}
static cairo_surface_t *
load_default_window_icon (int size)
{
GtkIconTheme *theme = gtk_icon_theme_get_default ();
g_autoptr (GdkPixbuf) pixbuf = NULL;
const char *icon_name;
if (gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME))
icon_name = META_DEFAULT_ICON_NAME;
else
icon_name = "image-missing";
pixbuf = gtk_icon_theme_load_icon (theme, icon_name, size, 0, NULL);
return gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
}
static cairo_surface_t *
get_default_window_icon (void)
{
static cairo_surface_t *default_icon = NULL;
if (default_icon == NULL)
{
default_icon = load_default_window_icon (META_ICON_WIDTH);
g_assert (default_icon);
}
return cairo_surface_reference (default_icon);
}
static cairo_surface_t *
get_default_mini_icon (void)
{
static cairo_surface_t *default_icon = NULL;
if (default_icon == NULL)
{
default_icon = load_default_window_icon (META_MINI_ICON_WIDTH);
g_assert (default_icon);
}
return cairo_surface_reference (default_icon);
}
static void
meta_window_update_icon_now (MetaWindow *window,
gboolean force)
@@ -5389,11 +5438,17 @@ meta_window_update_icon_now (MetaWindow *window,
{
if (window->icon)
cairo_surface_destroy (window->icon);
window->icon = icon;
if (icon)
window->icon = icon;
else
window->icon = get_default_window_icon ();
if (window->mini_icon)
cairo_surface_destroy (window->mini_icon);
window->mini_icon = mini_icon;
if (mini_icon)
window->mini_icon = mini_icon;
else
window->mini_icon = get_default_mini_icon ();
g_object_freeze_notify (G_OBJECT (window));
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_ICON]);
@@ -5402,6 +5457,9 @@ meta_window_update_icon_now (MetaWindow *window,
redraw_icon (window);
}
g_assert (window->icon);
g_assert (window->mini_icon);
}
static gboolean
@@ -8088,7 +8146,8 @@ mouse_mode_focus (MetaWindow *window,
"Unsetting focus from %s due to mouse entering "
"the DESKTOP window\n",
display->focus_window->desc);
meta_display_unset_input_focus (display, timestamp);
meta_x11_display_focus_the_no_focus_window (display->x11_display,
timestamp);
}
}
}

View File

@@ -1308,7 +1308,8 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
meta_topic (META_DEBUG_FOCUS,
"Setting focus to no_focus_window, since no valid "
"window to focus found.\n");
meta_display_unset_input_focus (workspace->display, timestamp);
meta_x11_display_focus_the_no_focus_window (workspace->display->x11_display,
timestamp);
}
}
}
@@ -1380,7 +1381,8 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
else
{
meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n");
meta_display_unset_input_focus (workspace->display, timestamp);
meta_x11_display_focus_the_no_focus_window (workspace->display->x11_display,
timestamp);
}
}

View File

@@ -392,8 +392,6 @@ mutter_sources = [
'x11/meta-x11-selection-input-stream-private.h',
'x11/meta-x11-selection-output-stream.c',
'x11/meta-x11-selection-output-stream-private.h',
'x11/meta-x11-stack.c',
'x11/meta-x11-stack-private.h',
'x11/mutter-Xatomtype.h',
'x11/session.c',
'x11/session.h',

View File

@@ -297,13 +297,4 @@ MetaSoundPlayer * meta_display_get_sound_player (MetaDisplay *display);
META_EXPORT
MetaSelection * meta_display_get_selection (MetaDisplay *display);
META_EXPORT
void meta_display_set_input_focus (MetaDisplay *display,
MetaWindow *window,
gboolean focus_frame,
guint32 timestamp);
META_EXPORT
void meta_display_unset_input_focus (MetaDisplay *display,
guint32 timestamp);
#endif

View File

@@ -63,4 +63,27 @@ META_EXPORT
gboolean meta_x11_display_xwindow_is_a_no_focus_window (MetaX11Display *x11_display,
Window xwindow);
/* meta_x11_display_set_input_focus_window is like XSetInputFocus, except
* that (a) it can't detect timestamps later than the current time,
* since Mutter isn't part of the XServer, and thus gives erroneous
* behavior in this circumstance (so don't do it), (b) it uses
* display->last_focus_time since we don't have access to the true
* Xserver one, (c) it makes use of display->user_time since checking
* whether a window should be allowed to be focused should depend
* on user_time events (see bug 167358, comment 15 in particular)
*/
META_EXPORT
void meta_x11_display_set_input_focus_window (MetaX11Display *x11_display,
MetaWindow *window,
gboolean focus_frame,
guint32 timestamp);
/* meta_x11_display_focus_the_no_focus_window is called when the
* designated no_focus_window should be focused, but is otherwise the
* same as meta_display_set_input_focus_window
*/
META_EXPORT
void meta_x11_display_focus_the_no_focus_window (MetaX11Display *x11_display,
guint32 timestamp);
#endif /* META_X11_DISPLAY_H */

View File

@@ -32,7 +32,6 @@
#include "wayland/meta-wayland.h"
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
#define FRAME_WARNING "Frame has assigned frame counter but no frame drawn time"
static gboolean
run_tests (gpointer data)
@@ -41,8 +40,6 @@ run_tests (gpointer data)
MetaSettings *settings = meta_backend_get_settings (backend);
gboolean ret;
g_test_log_set_fatal_handler (NULL, NULL);
meta_settings_override_experimental_features (settings);
meta_settings_enable_experimental_feature (
@@ -56,20 +53,6 @@ run_tests (gpointer data)
return FALSE;
}
static gboolean
ignore_frame_counter_warning (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
{
if ((log_level & G_LOG_LEVEL_WARNING) &&
g_strcmp0 (log_domain, "mutter") == 0 &&
g_str_has_suffix (message, FRAME_WARNING))
return FALSE;
return TRUE;
}
static void
meta_test_headless_start (void)
{
@@ -210,8 +193,6 @@ main (int argc, char *argv[])
meta_init ();
meta_register_with_session ();
g_test_log_set_fatal_handler (ignore_frame_counter_warning, NULL);
g_idle_add (run_tests, NULL);
return meta_run ();

View File

@@ -385,9 +385,6 @@ test_case_do (TestCase *test,
argc == 3 ? argv[2] : NULL,
NULL))
return FALSE;
if (!test_client_wait (client, error))
return FALSE;
}
else if (strcmp (argv[0], "set_parent") == 0 ||
strcmp (argv[0], "set_parent_exported") == 0)

View File

@@ -31,6 +31,8 @@
#include "meta/prefs.h"
#include "ui/frames.h"
#define DEBUG_FILL_STRUCT(s) memset ((s), 0xef, sizeof (*(s)))
static void scale_border (GtkBorder *border, double factor);
static MetaFrameLayout *
@@ -56,6 +58,7 @@ meta_frame_layout_free (MetaFrameLayout *layout)
{
g_return_if_fail (layout != NULL);
DEBUG_FILL_STRUCT (layout);
g_free (layout);
}
@@ -964,6 +967,7 @@ meta_theme_free (MetaTheme *theme)
if (theme->layouts[i])
meta_frame_layout_free (theme->layouts[i]);
DEBUG_FILL_STRUCT (theme);
g_free (theme);
}

View File

@@ -43,6 +43,10 @@
#include "linux-dmabuf-unstable-v1-server-protocol.h"
#ifndef DRM_FORMAT_MOD_INVALID
#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
#endif
#define META_WAYLAND_DMA_BUF_MAX_FDS 4
struct _MetaWaylandDmaBufBuffer
@@ -80,15 +84,28 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
if (buffer->dma_buf.texture)
return TRUE;
/*
* NOTE: The cogl_format here is only used for texture color channel
* swizzling as compared to COGL_PIXEL_FORMAT_ARGB. It is *not* used
* for accessing the buffer memory. EGL will access the buffer
* memory according to the DRM fourcc code. Cogl will not mmap
* and access the buffer memory at all.
*/
if (!cogl_pixel_format_from_drm_format (dma_buf->drm_format, &cogl_format, NULL))
switch (dma_buf->drm_format)
{
/*
* NOTE: The cogl_format here is only used for texture color channel
* swizzling as compared to COGL_PIXEL_FORMAT_ARGB. It is *not* used
* for accessing the buffer memory. EGL will access the buffer
* memory according to the DRM fourcc code. Cogl will not mmap
* and access the buffer memory at all.
*/
case DRM_FORMAT_XRGB8888:
cogl_format = COGL_PIXEL_FORMAT_RGB_888;
break;
case DRM_FORMAT_ARGB8888:
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
break;
case DRM_FORMAT_ARGB2101010:
cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
break;
case DRM_FORMAT_RGB565:
cogl_format = COGL_PIXEL_FORMAT_RGB_565;
break;
default:
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
"Unsupported buffer format %d", dma_buf->drm_format);

View File

@@ -862,19 +862,6 @@ init_pointer_constraint (struct wl_resource *resource,
return;
}
switch (lifetime)
{
case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT:
case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT:
break;
default:
wl_resource_post_error (resource,
WL_DISPLAY_ERROR_INVALID_OBJECT,
"Invalid constraint lifetime");
return;
}
constraint = meta_wayland_pointer_constraint_new (surface, seat,
region,
lifetime,

View File

@@ -48,7 +48,6 @@ typedef struct
char *lock_file;
int abstract_fd;
int unix_fd;
struct wl_display *wayland_display;
struct wl_client *client;
struct wl_resource *xserver_resource;
char *display_name;

View File

@@ -266,7 +266,7 @@ meta_wayland_seat_free (MetaWaylandSeat *seat)
meta_wayland_gtk_text_input_destroy (seat->gtk_text_input);
meta_wayland_text_input_destroy (seat->text_input);
g_free (seat);
g_slice_free (MetaWaylandSeat, seat);
}
static gboolean

View File

@@ -142,12 +142,10 @@ meta_window_wayland_focus (MetaWindow *window,
guint32 timestamp)
{
if (meta_window_is_focusable (window))
{
meta_display_set_input_focus (window->display,
window,
FALSE,
timestamp);
}
meta_x11_display_set_input_focus_window (window->display->x11_display,
window,
FALSE,
timestamp);
}
static void
@@ -613,16 +611,6 @@ meta_window_wayland_are_updates_frozen (MetaWindow *window)
return !wl_window->has_been_shown;
}
static void
meta_window_wayland_map (MetaWindow *window)
{
}
static void
meta_window_wayland_unmap (MetaWindow *window)
{
}
static void
meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
{
@@ -646,8 +634,6 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
window_class->is_stackable = meta_window_wayland_is_stackable;
window_class->can_ping = meta_window_wayland_can_ping;
window_class->are_updates_frozen = meta_window_wayland_are_updates_frozen;
window_class->map = meta_window_wayland_map;
window_class->unmap = meta_window_wayland_unmap;
}
MetaWindow *
@@ -655,6 +641,7 @@ meta_window_wayland_new (MetaDisplay *display,
MetaWaylandSurface *surface)
{
XWindowAttributes attrs = { 0 };
MetaWindow *window;
/*
* Set attributes used by _meta_window_shared_new, don't bother trying to fake
@@ -669,13 +656,26 @@ meta_window_wayland_new (MetaDisplay *display,
attrs.map_state = IsUnmapped;
attrs.override_redirect = False;
return _meta_window_shared_new (display,
META_WINDOW_CLIENT_TYPE_WAYLAND,
surface,
None,
WithdrawnState,
META_COMP_EFFECT_CREATE,
&attrs);
/* XXX: Note: In the Wayland case we currently still trap X errors while
* creating a MetaWindow because we will still be making various redundant
* X requests (passing a window xid of None) until we thoroughly audit all
* the code to make sure it knows about non X based clients...
*/
meta_x11_error_trap_push (display->x11_display); /* Push a trap over all of window
* creation, to reduce XSync() calls
*/
window = _meta_window_shared_new (display,
META_WINDOW_CLIENT_TYPE_WAYLAND,
surface,
None,
WithdrawnState,
META_COMP_EFFECT_CREATE,
&attrs);
meta_x11_error_trap_pop (display->x11_display); /* pop the XSync()-reducing trap */
return window;
}
static gboolean

View File

@@ -465,27 +465,32 @@ on_displayfd_ready (int fd,
return G_SOURCE_REMOVE;
}
static gboolean
meta_xwayland_init_xserver (MetaXWaylandManager *manager)
gboolean
meta_xwayland_start (MetaXWaylandManager *manager,
struct wl_display *wl_display)
{
int xwayland_client_fd[2];
int displayfd[2];
gboolean started = FALSE;
g_autoptr(GSubprocessLauncher) launcher = NULL;
GSubprocessFlags flags;
GError *error = NULL;
if (!choose_xdisplay (manager))
goto out;
/* We want xwayland to be a wayland client so we make a socketpair to setup a
* wayland protocol connection. */
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, xwayland_client_fd) < 0)
{
g_warning ("xwayland_client_fd socketpair failed\n");
return FALSE;
goto out;
}
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, displayfd) < 0)
{
g_warning ("displayfd socketpair failed\n");
return FALSE;
goto out;
}
/* xwayland, please. */
@@ -506,10 +511,16 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
/* Use the -terminate parameter to ensure that Xwayland exits cleanly
* after the last client disconnects. Fortunately that includes the window
* manager so it won't exit prematurely either. This ensures that Xwayland
* won't try to reconnect and crash, leaving uninteresting core dumps. We do
* want core dumps from Xwayland but only if a real bug occurs...
*/
manager->proc = g_subprocess_launcher_spawn (launcher, &error,
XWAYLAND_PATH, manager->display_name,
"-rootless",
"-noreset",
"-terminate",
"-accessx",
"-core",
"-listen", "4",
@@ -519,15 +530,14 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
if (!manager->proc)
{
g_error ("Failed to spawn Xwayland: %s", error->message);
return FALSE;
goto out;
}
manager->xserver_died_cancellable = g_cancellable_new ();
g_subprocess_wait_async (manager->proc, manager->xserver_died_cancellable,
xserver_died, NULL);
g_unix_fd_add (displayfd[0], G_IO_IN, on_displayfd_ready, manager);
manager->client = wl_client_create (manager->wayland_display,
xwayland_client_fd[0]);
manager->client = wl_client_create (wl_display, xwayland_client_fd[0]);
/* We need to run a mainloop until we know xwayland has a binding
* for our xserver interface at which point we can assume it's
@@ -535,18 +545,15 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
manager->init_loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (manager->init_loop);
return TRUE;
}
started = TRUE;
gboolean
meta_xwayland_start (MetaXWaylandManager *manager,
struct wl_display *wl_display)
{
if (!choose_xdisplay (manager))
return FALSE;
manager->wayland_display = wl_display;
return meta_xwayland_init_xserver (manager);
out:
if (!started)
{
unlink (manager->lock_file);
g_clear_pointer (&manager->lock_file, g_free);
}
return started;
}
static void

View File

@@ -803,15 +803,14 @@ handle_window_focus_event (MetaX11Display *x11_display,
* multiple focus events with the same serial.
*/
if (x11_display->server_focus_serial > x11_display->focus_serial ||
(!x11_display->focused_by_us &&
(!display->focused_by_us &&
x11_display->server_focus_serial == x11_display->focus_serial))
{
meta_display_update_focus_window (display, focus_window);
meta_x11_display_update_focus_window (x11_display,
focus_window ?
focus_window->xwindow : None,
x11_display->server_focus_serial,
FALSE);
meta_display_update_focus_window (display,
focus_window,
focus_window ? focus_window->xwindow : None,
x11_display->server_focus_serial,
FALSE);
return TRUE;
}
else
@@ -883,7 +882,7 @@ handle_input_xevent (MetaX11Display *x11_display,
enter_event->mode != XINotifyGrab &&
enter_event->mode != XINotifyUngrab &&
enter_event->detail != XINotifyInferior &&
meta_x11_display_focus_sentinel_clear (x11_display))
meta_display_focus_sentinel_clear (display))
{
meta_window_handle_enter (window,
enter_event->time,
@@ -1526,7 +1525,7 @@ handle_other_xevent (MetaX11Display *x11_display,
if (event->xproperty.atom ==
x11_display->atom__MUTTER_SENTINEL)
{
meta_x11_display_decrement_focus_sentinel (x11_display);
meta_display_decrement_focus_sentinel (display);
}
}
}
@@ -1793,7 +1792,7 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display,
if (META_IS_BACKEND_X11 (backend))
meta_backend_x11_handle_event (META_BACKEND_X11 (backend), event);
if (x11_display->focused_by_us &&
if (display->focused_by_us &&
event->xany.serial > x11_display->focus_serial &&
display->focus_window &&
!window_has_xwindow (display->focus_window, x11_display->server_focus_window))
@@ -1802,11 +1801,10 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display,
display->focus_window->desc);
meta_display_update_focus_window (display,
meta_x11_display_lookup_x_window (x11_display,
x11_display->server_focus_window));
meta_x11_display_update_focus_window (x11_display,
x11_display->server_focus_window,
x11_display->server_focus_serial,
FALSE);
x11_display->server_focus_window),
x11_display->server_focus_window,
x11_display->server_focus_serial,
FALSE);
}
if (event->xany.window == x11_display->xroot)

View File

@@ -35,7 +35,6 @@
#include "meta/types.h"
#include "meta/meta-x11-display.h"
#include "meta-startup-notification-x11.h"
#include "meta-x11-stack-private.h"
#include "ui/ui.h"
typedef struct _MetaGroupPropHooks MetaGroupPropHooks;
@@ -134,21 +133,8 @@ struct _MetaX11Display
GList *output_streams;
} selection;
/* If true, server->focus_serial refers to us changing the focus; in
* this case, we can ignore focus events that have exactly focus_serial,
* since we take care to make another request immediately afterwards.
* But if focus is being changed by another client, we have to accept
* multiple events with the same serial.
*/
guint focused_by_us : 1;
guint keys_grabbed : 1;
/* we use property updates as sentinels for certain window focus events
* to avoid some race conditions on EnterNotify events
*/
int sentinel_counter;
int composite_event_base;
int composite_error_base;
int composite_major_version;
@@ -176,7 +162,6 @@ struct _MetaX11Display
#define META_X11_DISPLAY_HAS_XINPUT_23(x11_display) ((x11_display)->have_xinput_23)
MetaX11StartupNotification *startup_notification;
MetaX11Stack *x11_stack;
};
MetaX11Display *meta_x11_display_new (MetaDisplay *display, GError **error);
@@ -237,16 +222,4 @@ MetaLogicalMonitor *meta_x11_display_xinerama_index_to_logical_monitor (MetaX11D
void meta_x11_display_update_workspace_layout (MetaX11Display *x11_display);
void meta_x11_display_update_workspace_names (MetaX11Display *x11_display);
void meta_x11_display_increment_focus_sentinel (MetaX11Display *x11_display);
void meta_x11_display_decrement_focus_sentinel (MetaX11Display *x11_display);
gboolean meta_x11_display_focus_sentinel_clear (MetaX11Display *x11_display);
void meta_x11_display_update_focus_window (MetaX11Display *x11_display,
Window xwindow,
gulong serial,
gboolean focused_by_us);
void meta_x11_display_set_input_focus (MetaX11Display *x11_display,
Window xwindow,
guint32 timestamp);
#endif /* META_X11_DISPLAY_PRIVATE_H */

View File

@@ -95,27 +95,6 @@ static void unset_wm_check_hint (MetaX11Display *x11_display);
static void prefs_changed_callback (MetaPreference pref,
void *data);
static void
meta_x11_display_unmanage_windows (MetaX11Display *x11_display)
{
GList *windows, *l;
MetaWindow *window;
if (!x11_display->xids)
return;
windows = g_hash_table_get_values (x11_display->xids);
g_list_foreach (windows, (GFunc) g_object_ref, NULL);
for (l = windows; l; l = l->next)
{
window = l->data;
if (!window->unmanaging)
meta_window_unmanage (window, META_CURRENT_TIME);
}
g_list_free_full (windows, g_object_unref);
}
static void
meta_x11_display_dispose (GObject *object)
{
@@ -128,9 +107,6 @@ meta_x11_display_dispose (GObject *object)
meta_x11_display_ungrab_keys (x11_display);
meta_x11_selection_shutdown (x11_display);
meta_x11_display_unmanage_windows (x11_display);
g_clear_object (&x11_display->x11_stack);
if (x11_display->ui)
{
@@ -490,13 +466,6 @@ init_x11_bell (MetaX11Display *x11_display)
&mask);
}
}
/* We are playing sounds using libcanberra support, we handle the
* bell whether its an audible bell or a visible bell */
XkbChangeEnabledControls (x11_display->xdisplay,
XkbUseCoreKbd,
XkbAudibleBellMask,
0);
}
/*
@@ -514,6 +483,32 @@ shutdown_x11_bell (MetaX11Display *x11_display)
XkbAudibleBellMask);
}
/*
* Turns the bell to audible or visual. This tells X what to do, but
* not Mutter; you will need to set the "visual bell" pref for that.
*/
static void
set_x11_bell_is_audible (MetaX11Display *x11_display,
gboolean is_audible)
{
/* When we are playing sounds using libcanberra support, we handle the
* bell whether its an audible bell or a visible bell */
gboolean enable_system_bell = FALSE;
XkbChangeEnabledControls (x11_display->xdisplay,
XkbUseCoreKbd,
XkbAudibleBellMask,
enable_system_bell ? XkbAudibleBellMask : 0);
}
static void
on_is_audible_changed (MetaBell *bell,
gboolean is_audible,
MetaX11Display *x11_display)
{
set_x11_bell_is_audible (x11_display, is_audible);
}
static void
set_desktop_geometry_hint (MetaX11Display *x11_display)
{
@@ -1091,9 +1086,6 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
};
Atom atoms[G_N_ELEMENTS(atom_names)];
if (!meta_x11_init_gdk_display (error))
return NULL;
g_assert (prepared_gdk_display);
gdk_display = g_steal_pointer (&prepared_gdk_display);
@@ -1278,7 +1270,6 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
set_desktop_geometry_hint (x11_display);
x11_display->ui = meta_ui_new (x11_display);
x11_display->x11_stack = meta_x11_stack_new (x11_display);
x11_display->keys_grabbed = FALSE;
meta_x11_display_grab_keys (x11_display);
@@ -1332,6 +1323,12 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
init_x11_bell (x11_display);
g_signal_connect_object (display->bell, "is-audible-changed",
G_CALLBACK (on_is_audible_changed),
x11_display, 0);
set_x11_bell_is_audible (x11_display, meta_prefs_bell_is_audible ());
meta_x11_startup_notification_init (x11_display);
meta_x11_selection_init (x11_display);
@@ -1822,27 +1819,17 @@ meta_x11_display_update_active_window_hint (MetaX11Display *x11_display)
meta_x11_error_trap_pop (x11_display);
}
void
meta_x11_display_update_focus_window (MetaX11Display *x11_display,
Window xwindow,
gulong serial,
gboolean focused_by_us)
static void
request_xserver_input_focus_change (MetaX11Display *x11_display,
MetaWindow *meta_window,
Window xwindow,
guint32 timestamp)
{
x11_display->focus_serial = serial;
x11_display->focused_by_us = !!focused_by_us;
gulong serial;
if (x11_display->focus_xwindow == xwindow)
if (meta_display_timestamp_too_old (x11_display->display, &timestamp))
return;
x11_display->focus_xwindow = xwindow;
meta_x11_display_update_active_window_hint (x11_display);
}
void
meta_x11_display_set_input_focus (MetaX11Display *x11_display,
Window xwindow,
guint32 timestamp)
{
meta_x11_error_trap_push (x11_display);
/* In order for mutter to know that the focus request succeeded, we track
@@ -1855,6 +1842,8 @@ meta_x11_display_set_input_focus (MetaX11Display *x11_display,
*/
XGrabServer (x11_display->xdisplay);
serial = XNextRequest (x11_display->xdisplay);
XSetInputFocus (x11_display->xdisplay,
xwindow,
RevertToPointerRoot,
@@ -1868,7 +1857,30 @@ meta_x11_display_set_input_focus (MetaX11Display *x11_display,
XUngrabServer (x11_display->xdisplay);
XFlush (x11_display->xdisplay);
meta_display_update_focus_window (x11_display->display,
meta_window,
xwindow,
serial,
TRUE);
meta_x11_error_trap_pop (x11_display);
x11_display->display->last_focus_time = timestamp;
if (meta_window == NULL || meta_window != x11_display->display->autoraise_window)
meta_display_remove_autoraise_callback (x11_display->display);
}
void
meta_x11_display_set_input_focus_window (MetaX11Display *x11_display,
MetaWindow *window,
gboolean focus_frame,
guint32 timestamp)
{
request_xserver_input_focus_change (x11_display,
window,
focus_frame ? window->frame->xwindow : window->xwindow,
timestamp);
}
void
@@ -1876,12 +1888,20 @@ meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display,
Window window,
guint32 timestamp)
{
gulong serial;
request_xserver_input_focus_change (x11_display,
NULL,
window,
timestamp);
}
meta_display_unset_input_focus (x11_display->display, timestamp);
serial = XNextRequest (x11_display->xdisplay);
meta_x11_display_set_input_focus (x11_display, window, timestamp);
meta_x11_display_update_focus_window (x11_display, window, serial, TRUE);
void
meta_x11_display_focus_the_no_focus_window (MetaX11Display *x11_display,
guint32 timestamp)
{
request_xserver_input_focus_change (x11_display,
NULL,
x11_display->no_focus_window,
timestamp);
}
static MetaX11DisplayLogicalMonitorData *
@@ -2157,34 +2177,3 @@ prefs_changed_callback (MetaPreference pref,
set_workspace_names (x11_display);
}
}
void
meta_x11_display_increment_focus_sentinel (MetaX11Display *x11_display)
{
unsigned long data[1];
data[0] = meta_display_get_current_time (x11_display->display);
XChangeProperty (x11_display->xdisplay,
x11_display->xroot,
x11_display->atom__MUTTER_SENTINEL,
XA_CARDINAL,
32, PropModeReplace, (guchar*) data, 1);
x11_display->sentinel_counter += 1;
}
void
meta_x11_display_decrement_focus_sentinel (MetaX11Display *x11_display)
{
x11_display->sentinel_counter -= 1;
if (x11_display->sentinel_counter < 0)
x11_display->sentinel_counter = 0;
}
gboolean
meta_x11_display_focus_sentinel_clear (MetaX11Display *x11_display)
{
return (x11_display->sentinel_counter == 0);
}

View File

@@ -1,33 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2019 Red Hat, Inc
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef META_X11_STACK_H
#define META_X11_STACK_H
#include <glib-object.h>
#include "meta/types.h"
#define META_TYPE_X11_STACK (meta_x11_stack_get_type ())
G_DECLARE_FINAL_TYPE (MetaX11Stack, meta_x11_stack, META, X11_STACK, GObject)
typedef struct _MetaX11Stack MetaX11Stack;
MetaX11Stack * meta_x11_stack_new (MetaX11Display *x11_display);
#endif /* META_X11_STACK_H */

View File

@@ -1,413 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2019 Red Hat, Inc
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "core/frame.h"
#include "core/stack.h"
#include "core/window-private.h"
#include "x11/meta-x11-display-private.h"
#include "x11/meta-x11-stack-private.h"
struct _MetaX11Stack
{
GObject parent;
MetaX11Display *x11_display;
/*
* A sequence of all the Windows (X handles, not MetaWindows) of the windows
* we manage, sorted in order. Suitable to be passed into _NET_CLIENT_LIST.
*/
GArray *xwindows;
/*
* MetaWindows waiting to be added to the xwindows list, after
* being added to the MetaStack.
*
* The order of the elements in this list is not important; what is important
* is the stack_position element of each window.
*/
GList *added;
/*
* Windows (X handles, not MetaWindows) waiting to be removed from the
* xwindows list, after being removed from the MetaStack.
*
* The order of the elements in this list is not important.
*/
GList *removed;
};
enum
{
PROP_DISPLAY = 1,
N_PROPS
};
static GParamSpec *pspecs[N_PROPS] = { 0 };
G_DEFINE_TYPE (MetaX11Stack, meta_x11_stack, G_TYPE_OBJECT)
static void
meta_x11_stack_init (MetaX11Stack *x11_stack)
{
x11_stack->xwindows = g_array_new (FALSE, FALSE, sizeof (Window));
}
static void
meta_x11_stack_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaX11Stack *x11_stack = META_X11_STACK (object);
switch (prop_id)
{
case PROP_DISPLAY:
x11_stack->x11_display = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
meta_x11_stack_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaX11Stack *x11_stack = META_X11_STACK (object);
switch (prop_id)
{
case PROP_DISPLAY:
g_value_set_object (value, x11_stack->x11_display);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
stack_window_added_cb (MetaStack *stack,
MetaWindow *window,
MetaX11Stack *x11_stack)
{
if (window->client_type != META_WINDOW_CLIENT_TYPE_X11)
return;
x11_stack->added = g_list_prepend (x11_stack->added, window);
}
static void
stack_window_removed_cb (MetaStack *stack,
MetaWindow *window,
MetaX11Stack *x11_stack)
{
if (window->client_type != META_WINDOW_CLIENT_TYPE_X11)
return;
x11_stack->added = g_list_remove (x11_stack->added, window);
x11_stack->removed = g_list_prepend (x11_stack->removed,
GUINT_TO_POINTER (window->xwindow));
if (window->frame)
{
x11_stack->removed = g_list_prepend (x11_stack->removed,
GUINT_TO_POINTER (window->frame->xwindow));
}
}
/**
* stack_do_window_deletions:
*
* Go through "deleted" and take the matching windows
* out of "windows".
*/
static void
x11_stack_do_window_deletions (MetaX11Stack *x11_stack)
{
GList *tmp;
int i;
tmp = x11_stack->removed;
while (tmp != NULL)
{
Window xwindow;
xwindow = GPOINTER_TO_UINT (tmp->data);
/* We go from the end figuring removals are more
* likely to be recent.
*/
i = x11_stack->xwindows->len;
while (i > 0)
{
--i;
/* there's no guarantee we'll actually find windows to
* remove, e.g. the same xwindow could have been
* added/removed before we ever synced, and we put
* both the window->xwindow and window->frame->xwindow
* in the removal list.
*/
if (xwindow == g_array_index (x11_stack->xwindows, Window, i))
{
g_array_remove_index (x11_stack->xwindows, i);
goto next;
}
}
next:
tmp = tmp->next;
}
g_clear_pointer (&x11_stack->removed, g_list_free);
}
static void
x11_stack_do_window_additions (MetaX11Stack *x11_stack)
{
GList *tmp;
gint n_added;
n_added = g_list_length (x11_stack->added);
if (n_added > 0)
{
meta_topic (META_DEBUG_STACK,
"Adding %d windows to sorted list\n",
n_added);
/* stack->added has the most recent additions at the
* front of the list, so we need to reverse it
*/
x11_stack->added = g_list_reverse (x11_stack->added);
tmp = x11_stack->added;
while (tmp != NULL)
{
MetaWindow *w;
w = tmp->data;
g_array_append_val (x11_stack->xwindows, w->xwindow);
tmp = tmp->next;
}
}
g_clear_pointer (&x11_stack->added, g_list_free);
}
/**
* x11_stack_sync_to_server:
*
* Order the windows on the X server to be the same as in our structure.
* We do this using XRestackWindows if we don't know the previous order,
* or XConfigureWindow on a few particular windows if we do and can figure
* out the minimum set of changes. After that, we set __NET_CLIENT_LIST
* and __NET_CLIENT_LIST_STACKING.
*
* FIXME: Now that we have a good view of the stacking order on the server
* with MetaStackTracker it should be possible to do a simpler and better
* job of computing the minimal set of stacking requests needed.
*/
static void
x11_stack_sync_to_xserver (MetaX11Stack *x11_stack)
{
MetaX11Display *x11_display = x11_stack->x11_display;
MetaStack *stack = x11_display->display->stack;
GArray *x11_stacked;
GArray *all_root_children_stacked; /* wayland OR x11 */
GList *tmp;
GArray *hidden_stack_ids;
uint64_t guard_window_id;
GList *sorted;
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
/* Create stacked xwindow arrays, in bottom-to-top order
*/
x11_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (guint64));
hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (guint64));
meta_topic (META_DEBUG_STACK, "Bottom to top: ");
meta_push_no_msg_prefix ();
sorted = meta_stack_list_windows (stack, NULL);
for (tmp = sorted; tmp; tmp = tmp->next)
{
MetaWindow *w = tmp->data;
guint64 top_level_window;
guint64 stack_id;
if (w->unmanaging)
continue;
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
w->layer, w->stack_position, w->desc);
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
g_array_append_val (x11_stacked, w->xwindow);
if (w->frame)
top_level_window = w->frame->xwindow;
else
top_level_window = w->xwindow;
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
stack_id = top_level_window;
else
stack_id = w->stamp;
/* We don't restack hidden windows along with the rest, though they are
* reflected in the _NET hints. Hidden windows all get pushed below
* the screens fullscreen guard_window. */
if (w->hidden)
{
g_array_append_val (hidden_stack_ids, stack_id);
continue;
}
g_array_append_val (all_root_children_stacked, stack_id);
}
meta_topic (META_DEBUG_STACK, "\n");
meta_pop_no_msg_prefix ();
/* The screen guard window sits above all hidden windows and acts as
* a barrier to input reaching these windows. */
guard_window_id = x11_stack->x11_display->guard_window;
g_array_append_val (hidden_stack_ids, guard_window_id);
/* Sync to server */
meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
all_root_children_stacked->len);
meta_stack_tracker_restack_managed (x11_display->display->stack_tracker,
(guint64 *)all_root_children_stacked->data,
all_root_children_stacked->len);
meta_stack_tracker_restack_at_bottom (x11_display->display->stack_tracker,
(guint64 *)hidden_stack_ids->data,
hidden_stack_ids->len);
/* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */
XChangeProperty (x11_stack->x11_display->xdisplay,
x11_stack->x11_display->xroot,
x11_stack->x11_display->atom__NET_CLIENT_LIST,
XA_WINDOW,
32, PropModeReplace,
(unsigned char *) x11_stack->xwindows->data,
x11_stack->xwindows->len);
XChangeProperty (x11_stack->x11_display->xdisplay,
x11_stack->x11_display->xroot,
x11_stack->x11_display->atom__NET_CLIENT_LIST_STACKING,
XA_WINDOW,
32, PropModeReplace,
(unsigned char *) x11_stacked->data,
x11_stacked->len);
g_array_free (x11_stacked, TRUE);
g_array_free (hidden_stack_ids, TRUE);
g_array_free (all_root_children_stacked, TRUE);
g_list_free (sorted);
}
static void
stack_changed_cb (MetaX11Stack *x11_stack)
{
/* Do removals before adds, with paranoid idea that we might re-add
* the same window IDs.
*/
x11_stack_do_window_deletions (x11_stack);
x11_stack_do_window_additions (x11_stack);
x11_stack_sync_to_xserver (x11_stack);
}
static void
meta_x11_stack_constructed (GObject *object)
{
MetaX11Stack *x11_stack = META_X11_STACK (object);
MetaX11Display *x11_display = x11_stack->x11_display;
G_OBJECT_CLASS (meta_x11_stack_parent_class)->constructed (object);
g_signal_connect (x11_display->display->stack,
"window-added",
G_CALLBACK (stack_window_added_cb),
x11_stack);
g_signal_connect (x11_display->display->stack,
"window-removed",
G_CALLBACK (stack_window_removed_cb),
x11_stack);
g_signal_connect_swapped (x11_display->display->stack,
"changed",
G_CALLBACK (stack_changed_cb),
x11_stack);
}
static void
meta_x11_stack_finalize (GObject *object)
{
MetaX11Stack *x11_stack = META_X11_STACK (object);
MetaX11Display *x11_display = x11_stack->x11_display;
if (x11_display->display && x11_display->display->stack)
{
g_signal_handlers_disconnect_by_data (x11_display->display->stack,
x11_stack);
}
g_array_free (x11_stack->xwindows, TRUE);
g_list_free (x11_stack->added);
g_list_free (x11_stack->removed);
G_OBJECT_CLASS (meta_x11_stack_parent_class)->finalize (object);
}
static void
meta_x11_stack_class_init (MetaX11StackClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = meta_x11_stack_set_property;
object_class->get_property = meta_x11_stack_get_property;
object_class->constructed = meta_x11_stack_constructed;
object_class->finalize = meta_x11_stack_finalize;
pspecs[PROP_DISPLAY] =
g_param_spec_object ("display",
"Display",
"Display",
META_TYPE_X11_DISPLAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, N_PROPS, pspecs);
}
MetaX11Stack *
meta_x11_stack_new (MetaX11Display *x11_display)
{
return g_object_new (META_TYPE_X11_STACK,
"display", x11_display,
NULL);
}

View File

@@ -794,10 +794,10 @@ meta_window_x11_focus (MetaWindow *window,
{
meta_topic (META_DEBUG_FOCUS,
"Focusing frame of %s\n", window->desc);
meta_display_set_input_focus (window->display,
window,
TRUE,
timestamp);
meta_x11_display_set_input_focus_window (window->display->x11_display,
window,
TRUE,
timestamp);
}
else
{
@@ -806,10 +806,10 @@ meta_window_x11_focus (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS,
"Setting input focus on %s since input = true\n",
window->desc);
meta_display_set_input_focus (window->display,
window,
FALSE,
timestamp);
meta_x11_display_set_input_focus_window (window->display->x11_display,
window,
FALSE,
timestamp);
}
if (priv->wm_take_focus)
@@ -832,7 +832,8 @@ meta_window_x11_focus (MetaWindow *window,
*/
if (window->display->focus_window != NULL &&
window->display->focus_window->unmanaging)
meta_display_unset_input_focus (window->display, timestamp);
meta_x11_display_focus_the_no_focus_window (window->display->x11_display,
timestamp);
}
request_take_focus (window, timestamp);
@@ -1705,27 +1706,6 @@ meta_window_x11_are_updates_frozen (MetaWindow *window)
return FALSE;
}
static void
meta_window_x11_map (MetaWindow *window)
{
MetaX11Display *x11_display = window->display->x11_display;
meta_x11_error_trap_push (x11_display);
XMapWindow (x11_display->xdisplay, window->xwindow);
meta_x11_error_trap_pop (x11_display);
}
static void
meta_window_x11_unmap (MetaWindow *window)
{
MetaX11Display *x11_display = window->display->x11_display;
meta_x11_error_trap_push (x11_display);
XUnmapWindow (x11_display->xdisplay, window->xwindow);
meta_x11_error_trap_pop (x11_display);
window->unmaps_pending ++;
}
static void
meta_window_x11_class_init (MetaWindowX11Class *klass)
{
@@ -1753,8 +1733,6 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
window_class->is_stackable = meta_window_x11_is_stackable;
window_class->can_ping = meta_window_x11_can_ping;
window_class->are_updates_frozen = meta_window_x11_are_updates_frozen;
window_class->map = meta_window_x11_map;
window_class->unmap = meta_window_x11_unmap;
}
void