compositor: Move out X11 compositing code into sub type
Introduce MetaCompositorX11, dealing with being a X11 compositor, and MetaCompositorServer, being a compositor while also being the display server itself, e.g. a Wayland display server. https://gitlab.gnome.org/GNOME/mutter/merge_requests/727
This commit is contained in:
parent
9af90bf9c1
commit
984aad4b86
@ -24,11 +24,12 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
|
#include "compositor/meta-compositor-x11.h"
|
||||||
|
|
||||||
gboolean meta_dnd_handle_xdnd_event (MetaBackend *backend,
|
gboolean meta_dnd_handle_xdnd_event (MetaBackend *backend,
|
||||||
MetaCompositor *compositor,
|
MetaCompositorX11 *compositor_x11,
|
||||||
Display *xdisplay,
|
Display *xdisplay,
|
||||||
XEvent *xev);
|
XEvent *xev);
|
||||||
|
|
||||||
void meta_dnd_init_xdnd (MetaX11Display *x11_display);
|
void meta_dnd_init_xdnd (MetaX11Display *x11_display);
|
||||||
|
|
||||||
|
@ -27,11 +27,14 @@
|
|||||||
#include <xkbcommon/xkbcommon-x11.h>
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
|
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
|
#include "backends/meta-dnd-private.h"
|
||||||
#include "backends/x11/meta-cursor-renderer-x11.h"
|
#include "backends/x11/meta-cursor-renderer-x11.h"
|
||||||
#include "backends/x11/meta-gpu-xrandr.h"
|
#include "backends/x11/meta-gpu-xrandr.h"
|
||||||
#include "backends/x11/meta-input-settings-x11.h"
|
#include "backends/x11/meta-input-settings-x11.h"
|
||||||
#include "backends/x11/meta-monitor-manager-xrandr.h"
|
#include "backends/x11/meta-monitor-manager-xrandr.h"
|
||||||
#include "backends/x11/cm/meta-renderer-x11-cm.h"
|
#include "backends/x11/cm/meta-renderer-x11-cm.h"
|
||||||
|
#include "compositor/meta-compositor-x11.h"
|
||||||
|
#include "core/display-private.h"
|
||||||
|
|
||||||
struct _MetaBackendX11Cm
|
struct _MetaBackendX11Cm
|
||||||
{
|
{
|
||||||
@ -328,6 +331,20 @@ meta_backend_x11_cm_handle_host_xevent (MetaBackendX11 *backend_x11,
|
|||||||
MetaMonitorManagerXrandr *monitor_manager_xrandr =
|
MetaMonitorManagerXrandr *monitor_manager_xrandr =
|
||||||
META_MONITOR_MANAGER_XRANDR (monitor_manager);
|
META_MONITOR_MANAGER_XRANDR (monitor_manager);
|
||||||
Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
|
Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
|
||||||
|
gboolean bypass_clutter = FALSE;
|
||||||
|
MetaDisplay *display;
|
||||||
|
|
||||||
|
display = meta_get_display ();
|
||||||
|
if (display)
|
||||||
|
{
|
||||||
|
MetaCompositor *compositor = display->compositor;
|
||||||
|
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
|
||||||
|
Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
|
||||||
|
|
||||||
|
if (meta_dnd_handle_xdnd_event (backend, compositor_x11,
|
||||||
|
xdisplay, event))
|
||||||
|
bypass_clutter = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (event->type == meta_backend_x11_get_xkb_event_base (x11))
|
if (event->type == meta_backend_x11_get_xkb_event_base (x11))
|
||||||
{
|
{
|
||||||
@ -351,8 +368,10 @@ meta_backend_x11_cm_handle_host_xevent (MetaBackendX11 *backend_x11,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return meta_monitor_manager_xrandr_handle_xevent (monitor_manager_xrandr,
|
bypass_clutter |=
|
||||||
event);
|
meta_monitor_manager_xrandr_handle_xevent (monitor_manager_xrandr, event);
|
||||||
|
|
||||||
|
return bypass_clutter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <xkbcommon/xkbcommon-x11.h>
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
|
|
||||||
#include "backends/meta-dnd-private.h"
|
|
||||||
#include "backends/meta-idle-monitor-private.h"
|
#include "backends/meta-idle-monitor-private.h"
|
||||||
#include "backends/meta-stage-private.h"
|
#include "backends/meta-stage-private.h"
|
||||||
#include "backends/x11/meta-clutter-backend-x11.h"
|
#include "backends/x11/meta-clutter-backend-x11.h"
|
||||||
@ -326,25 +325,20 @@ handle_host_xevent (MetaBackend *backend,
|
|||||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
gboolean bypass_clutter = FALSE;
|
gboolean bypass_clutter = FALSE;
|
||||||
|
MetaDisplay *display;
|
||||||
|
|
||||||
XGetEventData (priv->xdisplay, &event->xcookie);
|
XGetEventData (priv->xdisplay, &event->xcookie);
|
||||||
|
|
||||||
{
|
display = meta_get_display ();
|
||||||
MetaDisplay *display = meta_get_display ();
|
if (display)
|
||||||
|
{
|
||||||
|
MetaCompositor *compositor = display->compositor;
|
||||||
|
MetaPluginManager *plugin_mgr =
|
||||||
|
meta_compositor_get_plugin_manager (compositor);
|
||||||
|
|
||||||
if (display)
|
if (meta_plugin_manager_xevent_filter (plugin_mgr, event))
|
||||||
{
|
bypass_clutter = TRUE;
|
||||||
MetaCompositor *compositor = display->compositor;
|
}
|
||||||
MetaPluginManager *plugin_mgr =
|
|
||||||
meta_compositor_get_plugin_manager (compositor);
|
|
||||||
|
|
||||||
if (meta_plugin_manager_xevent_filter (plugin_mgr, event))
|
|
||||||
bypass_clutter = TRUE;
|
|
||||||
|
|
||||||
if (meta_dnd_handle_xdnd_event (backend, compositor, priv->xdisplay, event))
|
|
||||||
bypass_clutter = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bypass_clutter = (meta_backend_x11_handle_host_xevent (x11, event) ||
|
bypass_clutter = (meta_backend_x11_handle_host_xevent (x11, event) ||
|
||||||
bypass_clutter);
|
bypass_clutter);
|
||||||
|
@ -17,6 +17,13 @@
|
|||||||
struct _MetaCompositorClass
|
struct _MetaCompositorClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
void (* manage) (MetaCompositor *compositor);
|
||||||
|
void (* unmanage) (MetaCompositor *compositor);
|
||||||
|
void (* pre_paint) (MetaCompositor *compositor);
|
||||||
|
void (* post_paint) (MetaCompositor *compositor);
|
||||||
|
void (* remove_window) (MetaCompositor *compositor,
|
||||||
|
MetaWindow *window);
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_compositor_remove_window_actor (MetaCompositor *compositor,
|
void meta_compositor_remove_window_actor (MetaCompositor *compositor,
|
||||||
@ -50,9 +57,11 @@ void meta_compositor_locate_pointer (MetaCompositor *compositor);
|
|||||||
|
|
||||||
void meta_compositor_redirect_x11_windows (MetaCompositor *compositor);
|
void meta_compositor_redirect_x11_windows (MetaCompositor *compositor);
|
||||||
|
|
||||||
|
gboolean meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor);
|
||||||
|
|
||||||
MetaDisplay * meta_compositor_get_display (MetaCompositor *compositor);
|
MetaDisplay * meta_compositor_get_display (MetaCompositor *compositor);
|
||||||
|
|
||||||
Window meta_compositor_get_output_xwindow (MetaCompositor *compositor);
|
MetaWindowActor * meta_compositor_get_top_window_actor (MetaCompositor *compositor);
|
||||||
|
|
||||||
ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor);
|
ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor);
|
||||||
|
|
||||||
|
@ -54,14 +54,11 @@
|
|||||||
|
|
||||||
#include "compositor/compositor-private.h"
|
#include "compositor/compositor-private.h"
|
||||||
|
|
||||||
#include <X11/extensions/shape.h>
|
|
||||||
#include <X11/extensions/Xcomposite.h>
|
#include <X11/extensions/Xcomposite.h>
|
||||||
|
|
||||||
#include "backends/meta-dnd-private.h"
|
#include "backends/meta-dnd-private.h"
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
|
||||||
#include "clutter/clutter-mutter.h"
|
#include "clutter/clutter-mutter.h"
|
||||||
#include "clutter/x11/clutter-x11.h"
|
#include "compositor/meta-compositor-x11.h"
|
||||||
#include "compositor/meta-sync-ring.h"
|
|
||||||
#include "compositor/meta-window-actor-x11.h"
|
#include "compositor/meta-window-actor-x11.h"
|
||||||
#include "compositor/meta-window-actor-wayland.h"
|
#include "compositor/meta-window-actor-wayland.h"
|
||||||
#include "compositor/meta-window-actor-private.h"
|
#include "compositor/meta-window-actor-private.h"
|
||||||
@ -83,6 +80,7 @@
|
|||||||
#include "x11/meta-x11-display-private.h"
|
#include "x11/meta-x11-display-private.h"
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND
|
#ifdef HAVE_WAYLAND
|
||||||
|
#include "compositor/meta-compositor-server.h"
|
||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -110,26 +108,21 @@ typedef struct _MetaCompositorPrivate
|
|||||||
ClutterActor *feedback_group;
|
ClutterActor *feedback_group;
|
||||||
|
|
||||||
GList *windows;
|
GList *windows;
|
||||||
Window output;
|
|
||||||
|
|
||||||
CoglContext *context;
|
CoglContext *context;
|
||||||
|
|
||||||
MetaWindowActor *top_window_actor;
|
MetaWindowActor *top_window_actor;
|
||||||
gulong top_window_actor_destroy_id;
|
gulong top_window_actor_destroy_id;
|
||||||
|
|
||||||
/* Used for unredirecting fullscreen windows */
|
|
||||||
int disable_unredirect_count;
|
int disable_unredirect_count;
|
||||||
MetaWindow *unredirected_window;
|
|
||||||
|
|
||||||
int switch_workspace_in_progress;
|
int switch_workspace_in_progress;
|
||||||
|
|
||||||
MetaPluginManager *plugin_mgr;
|
MetaPluginManager *plugin_mgr;
|
||||||
|
|
||||||
gboolean frame_has_updated_xsurfaces;
|
|
||||||
gboolean have_x11_sync_object;
|
|
||||||
} MetaCompositorPrivate;
|
} MetaCompositorPrivate;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCompositor, meta_compositor, G_TYPE_OBJECT)
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCompositor, meta_compositor,
|
||||||
|
G_TYPE_OBJECT)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_presented (ClutterStage *stage,
|
on_presented (ClutterStage *stage,
|
||||||
@ -189,20 +182,6 @@ meta_compositor_destroy (MetaCompositor *compositor)
|
|||||||
g_object_unref (compositor);
|
g_object_unref (compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
process_damage (MetaCompositor *compositor,
|
|
||||||
XDamageNotifyEvent *event,
|
|
||||||
MetaWindow *window)
|
|
||||||
{
|
|
||||||
MetaCompositorPrivate *priv =
|
|
||||||
meta_compositor_get_instance_private (compositor);
|
|
||||||
MetaWindowActor *window_actor = meta_window_actor_from_window (window);
|
|
||||||
|
|
||||||
meta_window_actor_process_x11_damage (window_actor, event);
|
|
||||||
|
|
||||||
priv->frame_has_updated_xsurfaces = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compat helper */
|
/* compat helper */
|
||||||
static MetaCompositor *
|
static MetaCompositor *
|
||||||
get_compositor_for_display (MetaDisplay *display)
|
get_compositor_for_display (MetaDisplay *display)
|
||||||
@ -290,50 +269,6 @@ meta_get_window_actors (MetaDisplay *display)
|
|||||||
return priv->windows;
|
return priv->windows;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
meta_set_stage_input_region (MetaDisplay *display,
|
|
||||||
XserverRegion region)
|
|
||||||
{
|
|
||||||
/* As a wayland compositor we can simply ignore all this trickery
|
|
||||||
* for setting an input region on the stage for capturing events in
|
|
||||||
* clutter since all input comes to us first and we get to choose
|
|
||||||
* who else sees them.
|
|
||||||
*/
|
|
||||||
if (!meta_is_wayland_compositor ())
|
|
||||||
{
|
|
||||||
MetaCompositor *compositor = display->compositor;
|
|
||||||
MetaCompositorPrivate *priv =
|
|
||||||
meta_compositor_get_instance_private (compositor);
|
|
||||||
Display *xdpy = meta_x11_display_get_xdisplay (display->x11_display);
|
|
||||||
Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (priv->stage));
|
|
||||||
|
|
||||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
|
||||||
|
|
||||||
/* It's generally a good heuristic that when a crossing event is generated because
|
|
||||||
* we reshape the overlay, we don't want it to affect focus-follows-mouse focus -
|
|
||||||
* it's not the user doing something, it's the environment changing under the user.
|
|
||||||
*/
|
|
||||||
meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy));
|
|
||||||
XFixesSetWindowShapeRegion (xdpy, priv->output, ShapeInput, 0, 0, region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_empty_stage_input_region (MetaDisplay *display)
|
|
||||||
{
|
|
||||||
/* Using a static region here is a bit hacky, but Metacity never opens more than
|
|
||||||
* one XDisplay, so it works fine. */
|
|
||||||
static XserverRegion region = None;
|
|
||||||
|
|
||||||
if (region == None)
|
|
||||||
{
|
|
||||||
Display *xdpy = meta_x11_display_get_xdisplay (display->x11_display);
|
|
||||||
region = XFixesCreateRegion (xdpy, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_set_stage_input_region (display, region);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_focus_stage_window (MetaDisplay *display,
|
meta_focus_stage_window (MetaDisplay *display,
|
||||||
guint32 timestamp)
|
guint32 timestamp)
|
||||||
@ -584,14 +519,10 @@ meta_compositor_manage (MetaCompositor *compositor)
|
|||||||
MetaCompositorPrivate *priv =
|
MetaCompositorPrivate *priv =
|
||||||
meta_compositor_get_instance_private (compositor);
|
meta_compositor_get_instance_private (compositor);
|
||||||
MetaDisplay *display = priv->display;
|
MetaDisplay *display = priv->display;
|
||||||
Display *xdisplay = NULL;
|
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
|
||||||
if (display->x11_display)
|
if (display->x11_display)
|
||||||
{
|
meta_x11_display_set_cm_selection (display->x11_display);
|
||||||
xdisplay = display->x11_display->xdisplay;
|
|
||||||
meta_x11_display_set_cm_selection (display->x11_display);
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->stage = meta_backend_get_stage (backend);
|
priv->stage = meta_backend_get_stage (backend);
|
||||||
|
|
||||||
@ -622,42 +553,7 @@ meta_compositor_manage (MetaCompositor *compositor)
|
|||||||
clutter_actor_add_child (priv->stage, priv->top_window_group);
|
clutter_actor_add_child (priv->stage, priv->top_window_group);
|
||||||
clutter_actor_add_child (priv->stage, priv->feedback_group);
|
clutter_actor_add_child (priv->stage, priv->feedback_group);
|
||||||
|
|
||||||
if (meta_is_wayland_compositor ())
|
META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor);
|
||||||
{
|
|
||||||
/* NB: When running as a wayland compositor we don't need an X
|
|
||||||
* composite overlay window, and we don't need to play any input
|
|
||||||
* region tricks to redirect events into clutter. */
|
|
||||||
priv->output = None;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Window xwin;
|
|
||||||
|
|
||||||
priv->output = display->x11_display->composite_overlay_window;
|
|
||||||
|
|
||||||
xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend));
|
|
||||||
|
|
||||||
XReparentWindow (xdisplay, xwin, priv->output, 0, 0);
|
|
||||||
|
|
||||||
meta_empty_stage_input_region (display);
|
|
||||||
|
|
||||||
/* Make sure there isn't any left-over output shape on the
|
|
||||||
* overlay window by setting the whole screen to be an
|
|
||||||
* output region.
|
|
||||||
*
|
|
||||||
* Note: there doesn't seem to be any real chance of that
|
|
||||||
* because the X server will destroy the overlay window
|
|
||||||
* when the last client using it exits.
|
|
||||||
*/
|
|
||||||
XFixesSetWindowShapeRegion (xdisplay, priv->output, ShapeBounding, 0, 0, None);
|
|
||||||
|
|
||||||
/* Map overlay window before redirecting windows offscreen so we catch their
|
|
||||||
* contents until we show the stage.
|
|
||||||
*/
|
|
||||||
XMapWindow (xdisplay, priv->output);
|
|
||||||
|
|
||||||
priv->have_x11_sync_object = meta_sync_ring_init (xdisplay);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_compositor_redirect_x11_windows (compositor);
|
meta_compositor_redirect_x11_windows (compositor);
|
||||||
|
|
||||||
@ -667,103 +563,7 @@ meta_compositor_manage (MetaCompositor *compositor)
|
|||||||
void
|
void
|
||||||
meta_compositor_unmanage (MetaCompositor *compositor)
|
meta_compositor_unmanage (MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
if (!meta_is_wayland_compositor ())
|
META_COMPOSITOR_GET_CLASS (compositor)->unmanage (compositor);
|
||||||
{
|
|
||||||
MetaCompositorPrivate *priv =
|
|
||||||
meta_compositor_get_instance_private (compositor);
|
|
||||||
MetaX11Display *display = priv->display->x11_display;
|
|
||||||
Display *xdisplay = display->xdisplay;
|
|
||||||
Window xroot = display->xroot;
|
|
||||||
|
|
||||||
/* This is the most important part of cleanup - we have to do this
|
|
||||||
* before giving up the window manager selection or the next
|
|
||||||
* window manager won't be able to redirect subwindows */
|
|
||||||
XCompositeUnredirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_shape_cow_for_window:
|
|
||||||
* @compositor: A #MetaCompositor
|
|
||||||
* @window: (nullable): A #MetaWindow to shape the COW for
|
|
||||||
*
|
|
||||||
* Sets an bounding shape on the COW so that the given window
|
|
||||||
* is exposed. If @window is %NULL it clears the shape again.
|
|
||||||
*
|
|
||||||
* Used so we can unredirect windows, by shaping away the part
|
|
||||||
* of the COW, letting the raw window be seen through below.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
meta_shape_cow_for_window (MetaCompositor *compositor,
|
|
||||||
MetaWindow *window)
|
|
||||||
{
|
|
||||||
MetaCompositorPrivate *priv =
|
|
||||||
meta_compositor_get_instance_private (compositor);
|
|
||||||
MetaDisplay *display = priv->display;
|
|
||||||
Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
|
|
||||||
|
|
||||||
if (window == NULL)
|
|
||||||
{
|
|
||||||
XFixesSetWindowShapeRegion (xdisplay, priv->output,
|
|
||||||
ShapeBounding, 0, 0, None);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XserverRegion output_region;
|
|
||||||
XRectangle screen_rect, window_bounds;
|
|
||||||
int width, height;
|
|
||||||
MetaRectangle rect;
|
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &rect);
|
|
||||||
|
|
||||||
window_bounds.x = rect.x;
|
|
||||||
window_bounds.y = rect.y;
|
|
||||||
window_bounds.width = rect.width;
|
|
||||||
window_bounds.height = rect.height;
|
|
||||||
|
|
||||||
meta_display_get_size (display, &width, &height);
|
|
||||||
screen_rect.x = 0;
|
|
||||||
screen_rect.y = 0;
|
|
||||||
screen_rect.width = width;
|
|
||||||
screen_rect.height = height;
|
|
||||||
|
|
||||||
output_region = XFixesCreateRegion (xdisplay, &window_bounds, 1);
|
|
||||||
|
|
||||||
XFixesInvertRegion (xdisplay, output_region, &screen_rect, output_region);
|
|
||||||
XFixesSetWindowShapeRegion (xdisplay, priv->output,
|
|
||||||
ShapeBounding, 0, 0, output_region);
|
|
||||||
XFixesDestroyRegion (xdisplay, output_region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_unredirected_window (MetaCompositor *compositor,
|
|
||||||
MetaWindow *window)
|
|
||||||
{
|
|
||||||
MetaCompositorPrivate *priv =
|
|
||||||
meta_compositor_get_instance_private (compositor);
|
|
||||||
|
|
||||||
if (priv->unredirected_window == window)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (priv->unredirected_window != NULL)
|
|
||||||
{
|
|
||||||
MetaWindowActor *window_actor;
|
|
||||||
|
|
||||||
window_actor = meta_window_actor_from_window (priv->unredirected_window);
|
|
||||||
meta_window_actor_set_unredirected (window_actor, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_shape_cow_for_window (compositor, window);
|
|
||||||
priv->unredirected_window = window;
|
|
||||||
|
|
||||||
if (priv->unredirected_window != NULL)
|
|
||||||
{
|
|
||||||
MetaWindowActor *window_actor;
|
|
||||||
|
|
||||||
window_actor = meta_window_actor_from_window (priv->unredirected_window);
|
|
||||||
meta_window_actor_set_unredirected (window_actor, TRUE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -805,18 +605,20 @@ meta_compositor_add_window (MetaCompositor *compositor,
|
|||||||
sync_actor_stacking (compositor);
|
sync_actor_stacking (compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_real_remove_window (MetaCompositor *compositor,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWindowActor *window_actor = meta_window_actor_from_window (window);
|
||||||
|
|
||||||
|
meta_window_actor_queue_destroy (window_actor);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_compositor_remove_window (MetaCompositor *compositor,
|
meta_compositor_remove_window (MetaCompositor *compositor,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
MetaCompositorPrivate *priv =
|
META_COMPOSITOR_GET_CLASS (compositor)->remove_window (compositor, window);
|
||||||
meta_compositor_get_instance_private (compositor);
|
|
||||||
MetaWindowActor *window_actor = meta_window_actor_from_window (window);
|
|
||||||
|
|
||||||
if (priv->unredirected_window == window)
|
|
||||||
set_unredirected_window (compositor, NULL);
|
|
||||||
|
|
||||||
meta_window_actor_queue_destroy (window_actor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -874,53 +676,6 @@ meta_compositor_window_opacity_changed (MetaCompositor *compositor,
|
|||||||
meta_window_actor_update_opacity (window_actor);
|
meta_window_actor_update_opacity (window_actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_compositor_process_event: (skip)
|
|
||||||
* @compositor:
|
|
||||||
* @event:
|
|
||||||
* @window:
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
meta_compositor_process_event (MetaCompositor *compositor,
|
|
||||||
XEvent *event,
|
|
||||||
MetaWindow *window)
|
|
||||||
{
|
|
||||||
MetaCompositorPrivate *priv =
|
|
||||||
meta_compositor_get_instance_private (compositor);
|
|
||||||
MetaX11Display *x11_display = priv->display->x11_display;
|
|
||||||
|
|
||||||
if (!meta_is_wayland_compositor () &&
|
|
||||||
event->type == meta_x11_display_get_damage_event_base (x11_display) + XDamageNotify)
|
|
||||||
{
|
|
||||||
/* Core code doesn't handle damage events, so we need to extract the MetaWindow
|
|
||||||
* ourselves
|
|
||||||
*/
|
|
||||||
if (window == NULL)
|
|
||||||
{
|
|
||||||
Window xwin = ((XDamageNotifyEvent *) event)->drawable;
|
|
||||||
window = meta_x11_display_lookup_x_window (x11_display, xwin);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window)
|
|
||||||
process_damage (compositor, (XDamageNotifyEvent *) event, window);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->have_x11_sync_object)
|
|
||||||
meta_sync_ring_handle_event (event);
|
|
||||||
|
|
||||||
/* Clutter needs to know about MapNotify events otherwise it will
|
|
||||||
think the stage is invisible */
|
|
||||||
if (!meta_is_wayland_compositor () && event->type == MapNotify)
|
|
||||||
clutter_x11_handle_event (event);
|
|
||||||
|
|
||||||
/* The above handling is basically just "observing" the events, so we return
|
|
||||||
* FALSE to indicate that the event should not be filtered out; if we have
|
|
||||||
* GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example.
|
|
||||||
*/
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
||||||
MetaKeyBinding *binding)
|
MetaKeyBinding *binding)
|
||||||
@ -1299,85 +1054,40 @@ on_presented (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_real_pre_paint (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaCompositorPrivate *priv =
|
||||||
|
meta_compositor_get_instance_private (compositor);
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = priv->windows; l; l = l->next)
|
||||||
|
meta_window_actor_pre_paint (l->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_pre_paint (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
META_COMPOSITOR_GET_CLASS (compositor)->pre_paint (compositor);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_pre_paint_func (gpointer data)
|
meta_pre_paint_func (gpointer data)
|
||||||
{
|
{
|
||||||
MetaCompositor *compositor = data;
|
MetaCompositor *compositor = data;
|
||||||
MetaCompositorPrivate *priv =
|
|
||||||
meta_compositor_get_instance_private (compositor);
|
|
||||||
GList *l;
|
|
||||||
MetaWindowActor *top_window_actor;
|
|
||||||
|
|
||||||
if (priv->windows == NULL)
|
meta_compositor_pre_paint (compositor);
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
top_window_actor = priv->top_window_actor;
|
|
||||||
if (top_window_actor &&
|
|
||||||
meta_window_actor_should_unredirect (top_window_actor) &&
|
|
||||||
priv->disable_unredirect_count == 0)
|
|
||||||
{
|
|
||||||
MetaWindow *top_window;
|
|
||||||
|
|
||||||
top_window = meta_window_actor_get_meta_window (top_window_actor);
|
|
||||||
set_unredirected_window (compositor, top_window);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set_unredirected_window (compositor, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (l = priv->windows; l; l = l->next)
|
|
||||||
meta_window_actor_pre_paint (l->data);
|
|
||||||
|
|
||||||
if (priv->frame_has_updated_xsurfaces)
|
|
||||||
{
|
|
||||||
/* We need to make sure that any X drawing that happens before
|
|
||||||
* the XDamageSubtract() for each window above is visible to
|
|
||||||
* subsequent GL rendering; the standardized way to do this is
|
|
||||||
* GL_EXT_X11_sync_object. Since this isn't implemented yet in
|
|
||||||
* mesa, we also have a path that relies on the implementation
|
|
||||||
* of the open source drivers.
|
|
||||||
*
|
|
||||||
* Anything else, we just hope for the best.
|
|
||||||
*
|
|
||||||
* Xorg and open source driver specifics:
|
|
||||||
*
|
|
||||||
* The X server makes sure to flush drawing to the kernel before
|
|
||||||
* sending out damage events, but since we use
|
|
||||||
* DamageReportBoundingBox there may be drawing between the last
|
|
||||||
* damage event and the XDamageSubtract() that needs to be
|
|
||||||
* flushed as well.
|
|
||||||
*
|
|
||||||
* Xorg always makes sure that drawing is flushed to the kernel
|
|
||||||
* before writing events or responses to the client, so any
|
|
||||||
* round trip request at this point is sufficient to flush the
|
|
||||||
* GLX buffers.
|
|
||||||
*/
|
|
||||||
if (priv->have_x11_sync_object)
|
|
||||||
priv->have_x11_sync_object = meta_sync_ring_insert_wait ();
|
|
||||||
else
|
|
||||||
XSync (priv->display->x11_display->xdisplay, False);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
meta_post_paint_func (gpointer data)
|
meta_compositor_real_post_paint (MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
MetaCompositor *compositor = data;
|
|
||||||
MetaCompositorPrivate *priv =
|
MetaCompositorPrivate *priv =
|
||||||
meta_compositor_get_instance_private (compositor);
|
meta_compositor_get_instance_private (compositor);
|
||||||
CoglGraphicsResetStatus status;
|
CoglGraphicsResetStatus status;
|
||||||
|
|
||||||
if (priv->frame_has_updated_xsurfaces)
|
|
||||||
{
|
|
||||||
if (priv->have_x11_sync_object)
|
|
||||||
priv->have_x11_sync_object = meta_sync_ring_after_frame ();
|
|
||||||
|
|
||||||
priv->frame_has_updated_xsurfaces = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = cogl_get_graphics_reset_status (priv->context);
|
status = cogl_get_graphics_reset_status (priv->context);
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
@ -1400,6 +1110,20 @@ meta_post_paint_func (gpointer data)
|
|||||||
meta_restart (NULL);
|
meta_restart (NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_post_paint (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
META_COMPOSITOR_GET_CLASS (compositor)->post_paint (compositor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_post_paint_func (gpointer data)
|
||||||
|
{
|
||||||
|
MetaCompositor *compositor = data;
|
||||||
|
|
||||||
|
meta_compositor_post_paint (compositor);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1427,7 +1151,13 @@ meta_compositor_new (MetaDisplay *display)
|
|||||||
MetaCompositor *compositor;
|
MetaCompositor *compositor;
|
||||||
MetaCompositorPrivate *priv;
|
MetaCompositorPrivate *priv;
|
||||||
|
|
||||||
compositor = g_object_new (META_TYPE_COMPOSITOR, NULL);
|
#ifdef HAVE_WAYLAND
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
compositor = g_object_new (META_TYPE_COMPOSITOR_SERVER, NULL);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
compositor = g_object_new (META_TYPE_COMPOSITOR_X11, NULL);
|
||||||
|
|
||||||
priv = meta_compositor_get_instance_private (compositor);
|
priv = meta_compositor_get_instance_private (compositor);
|
||||||
priv->display = display;
|
priv->display = display;
|
||||||
|
|
||||||
@ -1484,12 +1214,6 @@ meta_compositor_dispose (GObject *object)
|
|||||||
g_clear_pointer (&priv->feedback_group, clutter_actor_destroy);
|
g_clear_pointer (&priv->feedback_group, clutter_actor_destroy);
|
||||||
g_clear_pointer (&priv->windows, g_list_free);
|
g_clear_pointer (&priv->windows, g_list_free);
|
||||||
|
|
||||||
if (priv->have_x11_sync_object)
|
|
||||||
{
|
|
||||||
meta_sync_ring_destroy ();
|
|
||||||
priv->have_x11_sync_object = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_compositor_parent_class)->dispose (object);
|
G_OBJECT_CLASS (meta_compositor_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1499,6 +1223,10 @@ meta_compositor_class_init (MetaCompositorClass *klass)
|
|||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->dispose = meta_compositor_dispose;
|
object_class->dispose = meta_compositor_dispose;
|
||||||
|
|
||||||
|
klass->remove_window = meta_compositor_real_remove_window;
|
||||||
|
klass->pre_paint = meta_compositor_real_pre_paint;
|
||||||
|
klass->post_paint = meta_compositor_real_post_paint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1539,6 +1267,15 @@ meta_enable_unredirect_for_display (MetaDisplay *display)
|
|||||||
priv->disable_unredirect_count--;
|
priv->disable_unredirect_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaCompositorPrivate *priv =
|
||||||
|
meta_compositor_get_instance_private (compositor);
|
||||||
|
|
||||||
|
return priv->disable_unredirect_count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define FLASH_TIME_MS 50
|
#define FLASH_TIME_MS 50
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1771,15 +1508,6 @@ meta_compositor_get_display (MetaCompositor *compositor)
|
|||||||
return priv->display;
|
return priv->display;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window
|
|
||||||
meta_compositor_get_output_xwindow (MetaCompositor *compositor)
|
|
||||||
{
|
|
||||||
MetaCompositorPrivate *priv =
|
|
||||||
meta_compositor_get_instance_private (compositor);
|
|
||||||
|
|
||||||
return priv->output;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClutterStage *
|
ClutterStage *
|
||||||
meta_compositor_get_stage (MetaCompositor *compositor)
|
meta_compositor_get_stage (MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
@ -1789,6 +1517,15 @@ meta_compositor_get_stage (MetaCompositor *compositor)
|
|||||||
return CLUTTER_STAGE (priv->stage);
|
return CLUTTER_STAGE (priv->stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWindowActor *
|
||||||
|
meta_compositor_get_top_window_actor (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaCompositorPrivate *priv =
|
||||||
|
meta_compositor_get_instance_private (compositor);
|
||||||
|
|
||||||
|
return priv->top_window_actor;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_compositor_is_switching_workspace (MetaCompositor *compositor)
|
meta_compositor_is_switching_workspace (MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
|
54
src/compositor/meta-compositor-server.c
Normal file
54
src/compositor/meta-compositor-server.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "compositor/meta-compositor-server.h"
|
||||||
|
|
||||||
|
struct _MetaCompositorServer
|
||||||
|
{
|
||||||
|
MetaCompositor parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaCompositorServer, meta_compositor_server, META_TYPE_COMPOSITOR)
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_server_manage (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_server_unmanage (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_server_init (MetaCompositorServer *compositor_server)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_server_class_init (MetaCompositorServerClass *klass)
|
||||||
|
{
|
||||||
|
MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
|
||||||
|
|
||||||
|
compositor_class->manage = meta_compositor_server_manage;
|
||||||
|
compositor_class->unmanage = meta_compositor_server_unmanage;
|
||||||
|
}
|
30
src/compositor/meta-compositor-server.h
Normal file
30
src/compositor/meta-compositor-server.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_COMPOSITOR_SERVER_H
|
||||||
|
#define META_COMPOSITOR_SERVER_H
|
||||||
|
|
||||||
|
#include "compositor/compositor-private.h"
|
||||||
|
|
||||||
|
#define META_TYPE_COMPOSITOR_SERVER (meta_compositor_server_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaCompositorServer, meta_compositor_server,
|
||||||
|
META, COMPOSITOR_SERVER, MetaCompositor)
|
||||||
|
|
||||||
|
#endif /* META_COMPOSITOR_SERVER_H */
|
412
src/compositor/meta-compositor-x11.c
Normal file
412
src/compositor/meta-compositor-x11.c
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
/*
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "compositor/meta-compositor-x11.h"
|
||||||
|
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
#include <X11/extensions/Xcomposite.h>
|
||||||
|
|
||||||
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
|
#include "clutter/x11/clutter-x11.h"
|
||||||
|
#include "compositor/meta-sync-ring.h"
|
||||||
|
#include "core/display-private.h"
|
||||||
|
#include "x11/meta-x11-display-private.h"
|
||||||
|
|
||||||
|
struct _MetaCompositorX11
|
||||||
|
{
|
||||||
|
MetaCompositor parent;
|
||||||
|
|
||||||
|
Window output;
|
||||||
|
|
||||||
|
gboolean frame_has_updated_xsurfaces;
|
||||||
|
gboolean have_x11_sync_object;
|
||||||
|
|
||||||
|
MetaWindow *unredirected_window;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaCompositorX11, meta_compositor_x11, META_TYPE_COMPOSITOR)
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_damage (MetaCompositorX11 *compositor_x11,
|
||||||
|
XDamageNotifyEvent *damage_xevent,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWindowActor *window_actor = meta_window_actor_from_window (window);
|
||||||
|
|
||||||
|
meta_window_actor_process_x11_damage (window_actor, damage_xevent);
|
||||||
|
|
||||||
|
compositor_x11->frame_has_updated_xsurfaces = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11,
|
||||||
|
XEvent *xevent,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
|
||||||
|
MetaDisplay *display = meta_compositor_get_display (compositor);
|
||||||
|
MetaX11Display *x11_display = display->x11_display;
|
||||||
|
int damage_event_base;
|
||||||
|
|
||||||
|
damage_event_base = meta_x11_display_get_damage_event_base (x11_display);
|
||||||
|
if (xevent->type == damage_event_base + XDamageNotify)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Core code doesn't handle damage events, so we need to extract the
|
||||||
|
* MetaWindow ourselves.
|
||||||
|
*/
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
Window xwindow;
|
||||||
|
|
||||||
|
xwindow = ((XDamageNotifyEvent *) xevent)->drawable;
|
||||||
|
window = meta_x11_display_lookup_x_window (x11_display, xwindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
process_damage (compositor_x11, (XDamageNotifyEvent *) xevent, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compositor_x11->have_x11_sync_object)
|
||||||
|
meta_sync_ring_handle_event (xevent);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clutter needs to know about MapNotify events otherwise it will think the
|
||||||
|
* stage is invisible
|
||||||
|
*/
|
||||||
|
if (xevent->type == MapNotify)
|
||||||
|
clutter_x11_handle_event (xevent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_set_stage_input_region (MetaDisplay *display,
|
||||||
|
XserverRegion region)
|
||||||
|
{
|
||||||
|
MetaCompositor *compositor = display->compositor;
|
||||||
|
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (display->compositor);
|
||||||
|
Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
|
||||||
|
ClutterStage *stage = meta_compositor_get_stage (compositor);
|
||||||
|
Window xstage;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As a wayland compositor we can simply ignore all this trickery
|
||||||
|
* for setting an input region on the stage for capturing events in
|
||||||
|
* clutter since all input comes to us first and we get to choose
|
||||||
|
* who else sees them.
|
||||||
|
*/
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
xstage = clutter_x11_get_stage_window (stage);
|
||||||
|
XFixesSetWindowShapeRegion (xdisplay, xstage, ShapeInput, 0, 0, region);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's generally a good heuristic that when a crossing event is generated
|
||||||
|
* because we reshape the overlay, we don't want it to affect
|
||||||
|
* focus-follows-mouse focus - it's not the user doing something, it's the
|
||||||
|
* environment changing under the user.
|
||||||
|
*/
|
||||||
|
meta_display_add_ignored_crossing_serial (display, XNextRequest (xdisplay));
|
||||||
|
XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output,
|
||||||
|
ShapeInput, 0, 0, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_empty_stage_input_region (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Using a static region here is a bit hacky, but when running as X11
|
||||||
|
* compositing manager we only ever open a single XDisplay.
|
||||||
|
*/
|
||||||
|
static XserverRegion region = None;
|
||||||
|
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (region == None)
|
||||||
|
{
|
||||||
|
Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
|
||||||
|
|
||||||
|
region = XFixesCreateRegion (xdisplay, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_set_stage_input_region (display, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_x11_manage (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
|
||||||
|
MetaDisplay *display = meta_compositor_get_display (compositor);
|
||||||
|
Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
Window xwindow;
|
||||||
|
|
||||||
|
compositor_x11->output = display->x11_display->composite_overlay_window;
|
||||||
|
|
||||||
|
xwindow = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend));
|
||||||
|
|
||||||
|
XReparentWindow (xdisplay, xwindow, compositor_x11->output, 0, 0);
|
||||||
|
|
||||||
|
meta_empty_stage_input_region (display);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure there isn't any left-over output shape on the overlay window by
|
||||||
|
* setting the whole screen to be an output region.
|
||||||
|
*
|
||||||
|
* Note: there doesn't seem to be any real chance of that because the X
|
||||||
|
* server will destroy the overlay window when the last client using it
|
||||||
|
* exits.
|
||||||
|
*/
|
||||||
|
XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output,
|
||||||
|
ShapeBounding, 0, 0, None);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map overlay window before redirecting windows offscreen so we catch their
|
||||||
|
* contents until we show the stage.
|
||||||
|
*/
|
||||||
|
XMapWindow (xdisplay, compositor_x11->output);
|
||||||
|
|
||||||
|
compositor_x11->have_x11_sync_object = meta_sync_ring_init (xdisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_x11_unmanage (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_compositor_get_display (compositor);
|
||||||
|
MetaX11Display *x11_display = display->x11_display;
|
||||||
|
Display *xdisplay = x11_display->xdisplay;
|
||||||
|
Window xroot = x11_display->xroot;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the most important part of cleanup - we have to do this before
|
||||||
|
* giving up the window manager selection or the next window manager won't be
|
||||||
|
* able to redirect subwindows
|
||||||
|
*/
|
||||||
|
XCompositeUnredirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets an bounding shape on the COW so that the given window
|
||||||
|
* is exposed. If window is %NULL it clears the shape again.
|
||||||
|
*
|
||||||
|
* Used so we can unredirect windows, by shaping away the part
|
||||||
|
* of the COW, letting the raw window be seen through below.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
shape_cow_for_window (MetaCompositorX11 *compositor_x11,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
|
||||||
|
MetaDisplay *display = meta_compositor_get_display (compositor);
|
||||||
|
Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output,
|
||||||
|
ShapeBounding, 0, 0, None);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XserverRegion output_region;
|
||||||
|
XRectangle screen_rect, window_bounds;
|
||||||
|
int width, height;
|
||||||
|
MetaRectangle rect;
|
||||||
|
|
||||||
|
meta_window_get_frame_rect (window, &rect);
|
||||||
|
|
||||||
|
window_bounds.x = rect.x;
|
||||||
|
window_bounds.y = rect.y;
|
||||||
|
window_bounds.width = rect.width;
|
||||||
|
window_bounds.height = rect.height;
|
||||||
|
|
||||||
|
meta_display_get_size (display, &width, &height);
|
||||||
|
screen_rect.x = 0;
|
||||||
|
screen_rect.y = 0;
|
||||||
|
screen_rect.width = width;
|
||||||
|
screen_rect.height = height;
|
||||||
|
|
||||||
|
output_region = XFixesCreateRegion (xdisplay, &window_bounds, 1);
|
||||||
|
|
||||||
|
XFixesInvertRegion (xdisplay, output_region, &screen_rect, output_region);
|
||||||
|
XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output,
|
||||||
|
ShapeBounding, 0, 0, output_region);
|
||||||
|
XFixesDestroyRegion (xdisplay, output_region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_unredirected_window (MetaCompositorX11 *compositor_x11,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWindow *prev_unredirected_window = compositor_x11->unredirected_window;
|
||||||
|
|
||||||
|
if (prev_unredirected_window == window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (prev_unredirected_window)
|
||||||
|
{
|
||||||
|
MetaWindowActor *window_actor;
|
||||||
|
|
||||||
|
window_actor = meta_window_actor_from_window (prev_unredirected_window);
|
||||||
|
meta_window_actor_set_unredirected (window_actor, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
shape_cow_for_window (compositor_x11, window);
|
||||||
|
compositor_x11->unredirected_window = window;
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
MetaWindowActor *window_actor;
|
||||||
|
|
||||||
|
window_actor = meta_window_actor_from_window (window);
|
||||||
|
meta_window_actor_set_unredirected (window_actor, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_x11_pre_paint (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
|
||||||
|
MetaWindowActor *top_window_actor;
|
||||||
|
MetaCompositorClass *parent_class;
|
||||||
|
|
||||||
|
top_window_actor = meta_compositor_get_top_window_actor (compositor);
|
||||||
|
if (!meta_compositor_is_unredirect_inhibited (compositor) &&
|
||||||
|
top_window_actor &&
|
||||||
|
meta_window_actor_should_unredirect (top_window_actor))
|
||||||
|
{
|
||||||
|
MetaWindow *top_window;
|
||||||
|
|
||||||
|
top_window = meta_window_actor_get_meta_window (top_window_actor);
|
||||||
|
set_unredirected_window (compositor_x11, top_window);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_unredirected_window (compositor_x11, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
|
||||||
|
parent_class->pre_paint (compositor);
|
||||||
|
|
||||||
|
if (compositor_x11->frame_has_updated_xsurfaces)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_compositor_get_display (compositor);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to make sure that any X drawing that happens before the
|
||||||
|
* XDamageSubtract() for each window above is visible to subsequent GL
|
||||||
|
* rendering; the standardized way to do this is GL_EXT_X11_sync_object.
|
||||||
|
* Since this isn't implemented yet in mesa, we also have a path that
|
||||||
|
* relies on the implementation of the open source drivers.
|
||||||
|
*
|
||||||
|
* Anything else, we just hope for the best.
|
||||||
|
*
|
||||||
|
* Xorg and open source driver specifics:
|
||||||
|
*
|
||||||
|
* The X server makes sure to flush drawing to the kernel before sending
|
||||||
|
* out damage events, but since we use DamageReportBoundingBox there may
|
||||||
|
* be drawing between the last damage event and the XDamageSubtract()
|
||||||
|
* that needs to be flushed as well.
|
||||||
|
*
|
||||||
|
* Xorg always makes sure that drawing is flushed to the kernel before
|
||||||
|
* writing events or responses to the client, so any round trip request
|
||||||
|
* at this point is sufficient to flush the GLX buffers.
|
||||||
|
*/
|
||||||
|
if (compositor_x11->have_x11_sync_object)
|
||||||
|
compositor_x11->have_x11_sync_object = meta_sync_ring_insert_wait ();
|
||||||
|
else
|
||||||
|
XSync (display->x11_display->xdisplay, False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_x11_post_paint (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
|
||||||
|
MetaCompositorClass *parent_class;
|
||||||
|
|
||||||
|
if (compositor_x11->frame_has_updated_xsurfaces)
|
||||||
|
{
|
||||||
|
if (compositor_x11->have_x11_sync_object)
|
||||||
|
compositor_x11->have_x11_sync_object = meta_sync_ring_after_frame ();
|
||||||
|
|
||||||
|
compositor_x11->frame_has_updated_xsurfaces = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
|
||||||
|
parent_class->post_paint (compositor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_x11_remove_window (MetaCompositor *compositor,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
|
||||||
|
MetaCompositorClass *parent_class;
|
||||||
|
|
||||||
|
if (compositor_x11->unredirected_window == window)
|
||||||
|
set_unredirected_window (compositor_x11, NULL);
|
||||||
|
|
||||||
|
parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
|
||||||
|
parent_class->remove_window (compositor, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
Window
|
||||||
|
meta_compositor_x11_get_output_xwindow (MetaCompositorX11 *compositor_x11)
|
||||||
|
{
|
||||||
|
return compositor_x11->output;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_x11_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (object);
|
||||||
|
|
||||||
|
if (compositor_x11->have_x11_sync_object)
|
||||||
|
{
|
||||||
|
meta_sync_ring_destroy ();
|
||||||
|
compositor_x11->have_x11_sync_object = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_compositor_x11_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_x11_init (MetaCompositorX11 *compositor_x11)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_x11_class_init (MetaCompositorX11Class *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = meta_compositor_x11_dispose;
|
||||||
|
|
||||||
|
compositor_class->manage = meta_compositor_x11_manage;
|
||||||
|
compositor_class->unmanage = meta_compositor_x11_unmanage;
|
||||||
|
compositor_class->pre_paint = meta_compositor_x11_pre_paint;
|
||||||
|
compositor_class->post_paint = meta_compositor_x11_post_paint;
|
||||||
|
compositor_class->remove_window = meta_compositor_x11_remove_window;
|
||||||
|
}
|
36
src/compositor/meta-compositor-x11.h
Normal file
36
src/compositor/meta-compositor-x11.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_COMPOSITOR_X11_H
|
||||||
|
#define META_COMPOSITOR_X11_H
|
||||||
|
|
||||||
|
#include "compositor/compositor-private.h"
|
||||||
|
|
||||||
|
#define META_TYPE_COMPOSITOR_X11 (meta_compositor_x11_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaCompositorX11, meta_compositor_x11,
|
||||||
|
META, COMPOSITOR_X11, MetaCompositor)
|
||||||
|
|
||||||
|
void meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11,
|
||||||
|
XEvent *xevent,
|
||||||
|
MetaWindow *window);
|
||||||
|
|
||||||
|
Window meta_compositor_x11_get_output_xwindow (MetaCompositorX11 *compositor_x11);
|
||||||
|
|
||||||
|
#endif /* META_COMPOSITOR_X11_H */
|
@ -168,19 +168,20 @@ meta_dnd_notify_dnd_leave (MetaDnd *dnd)
|
|||||||
* http://www.freedesktop.org/wiki/Specifications/XDND
|
* http://www.freedesktop.org/wiki/Specifications/XDND
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
meta_dnd_handle_xdnd_event (MetaBackend *backend,
|
meta_dnd_handle_xdnd_event (MetaBackend *backend,
|
||||||
MetaCompositor *compositor,
|
MetaCompositorX11 *compositor_x11,
|
||||||
Display *xdisplay,
|
Display *xdisplay,
|
||||||
XEvent *xev)
|
XEvent *xev)
|
||||||
{
|
{
|
||||||
MetaDnd *dnd = meta_backend_get_dnd (backend);
|
MetaDnd *dnd = meta_backend_get_dnd (backend);
|
||||||
|
MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
|
||||||
Window output_window;
|
Window output_window;
|
||||||
ClutterStage *stage;
|
ClutterStage *stage;
|
||||||
|
|
||||||
if (xev->xany.type != ClientMessage)
|
if (xev->xany.type != ClientMessage)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
output_window = meta_compositor_get_output_xwindow (compositor);
|
output_window = meta_compositor_x11_get_output_xwindow (compositor_x11);
|
||||||
stage = meta_compositor_get_stage (compositor);
|
stage = meta_compositor_get_stage (compositor);
|
||||||
if (xev->xany.window != output_window &&
|
if (xev->xany.window != output_window &&
|
||||||
xev->xany.window != clutter_x11_get_stage_window (stage))
|
xev->xany.window != clutter_x11_get_stage_window (stage))
|
||||||
|
@ -271,6 +271,8 @@ mutter_sources = [
|
|||||||
'compositor/meta-background-group.c',
|
'compositor/meta-background-group.c',
|
||||||
'compositor/meta-background-image.c',
|
'compositor/meta-background-image.c',
|
||||||
'compositor/meta-background-private.h',
|
'compositor/meta-background-private.h',
|
||||||
|
'compositor/meta-compositor-x11.c',
|
||||||
|
'compositor/meta-compositor-x11.h',
|
||||||
'compositor/meta-cullable.c',
|
'compositor/meta-cullable.c',
|
||||||
'compositor/meta-cullable.h',
|
'compositor/meta-cullable.h',
|
||||||
'compositor/meta-dnd-actor.c',
|
'compositor/meta-dnd-actor.c',
|
||||||
@ -454,6 +456,8 @@ if have_wayland
|
|||||||
mutter_sources += [
|
mutter_sources += [
|
||||||
'compositor/meta-surface-actor-wayland.c',
|
'compositor/meta-surface-actor-wayland.c',
|
||||||
'compositor/meta-surface-actor-wayland.h',
|
'compositor/meta-surface-actor-wayland.h',
|
||||||
|
'compositor/meta-compositor-server.c',
|
||||||
|
'compositor/meta-compositor-server.h',
|
||||||
'wayland/meta-cursor-sprite-wayland.c',
|
'wayland/meta-cursor-sprite-wayland.c',
|
||||||
'wayland/meta-cursor-sprite-wayland.h',
|
'wayland/meta-cursor-sprite-wayland.h',
|
||||||
'wayland/meta-pointer-confinement-wayland.c',
|
'wayland/meta-pointer-confinement-wayland.c',
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#define META_COMPOSITOR_H
|
#define META_COMPOSITOR_H
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <X11/Xlib.h>
|
|
||||||
|
|
||||||
#include <meta/types.h>
|
#include <meta/types.h>
|
||||||
#include <meta/boxes.h>
|
#include <meta/boxes.h>
|
||||||
@ -87,11 +86,6 @@ META_EXPORT
|
|||||||
void meta_compositor_window_opacity_changed (MetaCompositor *compositor,
|
void meta_compositor_window_opacity_changed (MetaCompositor *compositor,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
|
|
||||||
META_EXPORT
|
|
||||||
gboolean meta_compositor_process_event (MetaCompositor *compositor,
|
|
||||||
XEvent *event,
|
|
||||||
MetaWindow *window);
|
|
||||||
|
|
||||||
META_EXPORT
|
META_EXPORT
|
||||||
gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
||||||
MetaKeyBinding *binding);
|
MetaKeyBinding *binding);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "backends/meta-cursor-tracker-private.h"
|
#include "backends/meta-cursor-tracker-private.h"
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
|
#include "compositor/meta-compositor-x11.h"
|
||||||
#include "core/bell.h"
|
#include "core/bell.h"
|
||||||
#include "core/display-private.h"
|
#include "core/display-private.h"
|
||||||
#include "core/meta-workspace-manager-private.h"
|
#include "core/meta-workspace-manager-private.h"
|
||||||
@ -1862,14 +1863,18 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (!bypass_compositor)
|
if (!bypass_compositor && META_IS_COMPOSITOR_X11 (display->compositor))
|
||||||
{
|
{
|
||||||
MetaWindow *window = modified != None ?
|
MetaCompositorX11 *compositor_x11 =
|
||||||
meta_x11_display_lookup_x_window (x11_display, modified) :
|
META_COMPOSITOR_X11 (display->compositor);
|
||||||
NULL;
|
MetaWindow *window;
|
||||||
|
|
||||||
if (meta_compositor_process_event (display->compositor, event, window))
|
if (modified != None)
|
||||||
bypass_gtk = TRUE;
|
window = meta_x11_display_lookup_x_window (x11_display, modified);
|
||||||
|
else
|
||||||
|
window = NULL;
|
||||||
|
|
||||||
|
meta_compositor_x11_process_xevent (compositor_x11, event, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
display->current_time = META_CURRENT_TIME;
|
display->current_time = META_CURRENT_TIME;
|
||||||
|
Loading…
Reference in New Issue
Block a user