From 467465c99c413376240e9cbd6d832157660e8776 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 13 Aug 2014 19:46:32 -0400 Subject: [PATCH] backend: Create the stage in the backend, rather than the compositor This allows creating the stage much earlier than it otherwise would have been. Our initialization sequence has always been a bit haphazard, with first the MetaBackend created, then the MetaDisplay, and inside of that, the MetaScreen and MetaCompositor. Refactor this out so that the MetaBackend creates the Clutter stage. Besides the clarity of early initialization, we now have much easier access to the stage, allowing us to use it for things such as key focus and beyond. --- src/Makefile.am | 4 +- src/backends/meta-backend-private.h | 3 + src/backends/meta-backend.c | 65 +++++++++++++++- src/backends/meta-cursor-renderer.c | 9 ++- src/{compositor => backends}/meta-stage.c | 0 src/{compositor => backends}/meta-stage.h | 0 src/backends/native/meta-launcher.c | 4 +- src/backends/x11/meta-backend-x11.c | 47 +++++++++--- src/compositor/compositor.c | 92 ++--------------------- src/core/screen.c | 3 - src/meta/compositor.h | 3 - src/meta/meta-backend.h | 4 + 12 files changed, 125 insertions(+), 109 deletions(-) rename src/{compositor => backends}/meta-stage.c (100%) rename src/{compositor => backends}/meta-stage.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 2b40090e9..f6b0c0909 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -69,6 +69,8 @@ libmutter_la_SOURCES = \ backends/meta-monitor-manager.h \ backends/meta-monitor-manager-dummy.c \ backends/meta-monitor-manager-dummy.h \ + backends/meta-stage.h \ + backends/meta-stage.c \ backends/edid-parse.c \ backends/edid.h \ backends/x11/meta-backend-x11.c \ @@ -115,8 +117,6 @@ libmutter_la_SOURCES = \ compositor/meta-surface-actor-x11.h \ compositor/meta-surface-actor-wayland.c \ compositor/meta-surface-actor-wayland.h \ - compositor/meta-stage.h \ - compositor/meta-stage.c \ compositor/meta-texture-rectangle.c \ compositor/meta-texture-rectangle.h \ compositor/meta-texture-tower.c \ diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 13dd53c70..bd665c17a 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -84,6 +84,9 @@ struct _MetaBackendClass void (* lock_layout_group) (MetaBackend *backend, guint idx); + + void (* update_screen_size) (MetaBackend *backend, int width, int height); + void (* select_stage_events) (MetaBackend *backend); }; MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend, diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index d2cd2eea9..75222daef 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -27,9 +27,8 @@ #include #include "meta-backend-private.h" -#include - #include "backends/x11/meta-backend-x11.h" +#include "meta-stage.h" #ifdef HAVE_NATIVE_BACKEND #include "backends/native/meta-backend-native.h" @@ -54,6 +53,8 @@ struct _MetaBackendPrivate { MetaMonitorManager *monitor_manager; MetaCursorRenderer *cursor_renderer; + + ClutterActor *stage; }; typedef struct _MetaBackendPrivate MetaBackendPrivate; @@ -77,12 +78,40 @@ meta_backend_finalize (GObject *object) G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object); } +static void +meta_backend_sync_screen_size (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + int width, height; + + meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height); + + META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height); +} + +static void +on_monitors_changed (MetaMonitorManager *monitors, + gpointer user_data) +{ + MetaBackend *backend = META_BACKEND (user_data); + meta_backend_sync_screen_size (backend); +} + static void meta_backend_real_post_init (MetaBackend *backend) { MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + priv->stage = meta_stage_new (); + clutter_actor_realize (priv->stage); + META_BACKEND_GET_CLASS (backend)->select_stage_events (backend); + priv->monitor_manager = META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend); + + g_signal_connect (priv->monitor_manager, "monitors-changed", + G_CALLBACK (on_monitors_changed), backend); + meta_backend_sync_screen_size (backend); + priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend); } @@ -110,6 +139,21 @@ meta_backend_real_ungrab_device (MetaBackend *backend, return TRUE; } +static void +meta_backend_real_update_screen_size (MetaBackend *backend, + int width, int height) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + clutter_actor_set_size (priv->stage, width, height); +} + +static void +meta_backend_real_select_stage_events (MetaBackend *backend) +{ + /* Do nothing */ +} + static void meta_backend_class_init (MetaBackendClass *klass) { @@ -121,6 +165,8 @@ meta_backend_class_init (MetaBackendClass *klass) klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer; klass->grab_device = meta_backend_real_grab_device; klass->ungrab_device = meta_backend_real_ungrab_device; + klass->update_screen_size = meta_backend_real_update_screen_size; + klass->select_stage_events = meta_backend_real_select_stage_events; } static void @@ -251,6 +297,21 @@ meta_backend_lock_layout_group (MetaBackend *backend, META_BACKEND_GET_CLASS (backend)->lock_layout_group (backend, idx); } +/** + * meta_backend_get_stage: + * @backend: A #MetaBackend + * + * Gets the global #ClutterStage that's managed by this backend. + * + * Returns: (transfer none): the #ClutterStage + */ +ClutterActor * +meta_backend_get_stage (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + return priv->stage; +} + static GType get_backend_type (void) { diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index 21f1a463e..3d1f85718 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -27,14 +27,15 @@ #include "meta-cursor-renderer.h" #include "meta-cursor-private.h" +#include +#include + #include #include #include #include "meta-stage.h" -#include "wayland/meta-wayland-private.h" - struct _MetaCursorRendererPrivate { int current_x, current_y; @@ -51,8 +52,8 @@ static void queue_redraw (MetaCursorRenderer *renderer) { MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); - MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); - ClutterActor *stage = compositor->stage; + MetaBackend *backend = meta_get_backend (); + ClutterActor *stage = meta_backend_get_stage (backend); /* During early initialization, we can have no stage */ if (!stage) diff --git a/src/compositor/meta-stage.c b/src/backends/meta-stage.c similarity index 100% rename from src/compositor/meta-stage.c rename to src/backends/meta-stage.c diff --git a/src/compositor/meta-stage.h b/src/backends/meta-stage.h similarity index 100% rename from src/compositor/meta-stage.h rename to src/backends/meta-stage.h diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c index 87b3f28dd..70454bb01 100644 --- a/src/backends/native/meta-launcher.c +++ b/src/backends/native/meta-launcher.c @@ -101,15 +101,15 @@ session_unpause (void) clutter_egl_thaw_master_clock (); { - MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); MetaBackend *backend = meta_get_backend (); MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend); + ClutterActor *stage = meta_backend_get_stage (backend); /* When we mode-switch back, we need to immediately queue a redraw * in case nothing else queued one for us, and force the cursor to * update. */ - clutter_actor_queue_redraw (compositor->stage); + clutter_actor_queue_redraw (stage); meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer)); } } diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index 5e8c25a05..2d420cb05 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -592,6 +592,40 @@ meta_backend_x11_lock_layout_group (MetaBackend *backend, XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, idx); } +static void +meta_backend_x11_update_screen_size (MetaBackend *backend, + int width, int height) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + Window xwin = meta_backend_x11_get_xwindow (x11); + XResizeWindow (priv->xdisplay, xwin, width, height); +} + +static void +meta_backend_x11_select_stage_events (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + Window xwin = meta_backend_x11_get_xwindow (x11); + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + XISetMask (mask.mask, XI_KeyPress); + XISetMask (mask.mask, XI_KeyRelease); + XISetMask (mask.mask, XI_ButtonPress); + XISetMask (mask.mask, XI_ButtonRelease); + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_FocusIn); + XISetMask (mask.mask, XI_FocusOut); + XISetMask (mask.mask, XI_Motion); + XIClearMask (mask.mask, XI_TouchBegin); + XIClearMask (mask.mask, XI_TouchEnd); + XIClearMask (mask.mask, XI_TouchUpdate); + XISelectEvents (priv->xdisplay, xwin, &mask, 1); +} + static void meta_backend_x11_class_init (MetaBackendX11Class *klass) { @@ -601,13 +635,14 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass) backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor; backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager; backend_class->create_cursor_renderer = meta_backend_x11_create_cursor_renderer; - backend_class->grab_device = meta_backend_x11_grab_device; backend_class->ungrab_device = meta_backend_x11_ungrab_device; backend_class->warp_pointer = meta_backend_x11_warp_pointer; backend_class->set_keymap = meta_backend_x11_set_keymap; backend_class->get_keymap = meta_backend_x11_get_keymap; backend_class->lock_layout_group = meta_backend_x11_lock_layout_group; + backend_class->update_screen_size = meta_backend_x11_update_screen_size; + backend_class->select_stage_events = meta_backend_x11_select_stage_events; } static void @@ -628,12 +663,6 @@ meta_backend_x11_get_xdisplay (MetaBackendX11 *x11) Window meta_backend_x11_get_xwindow (MetaBackendX11 *x11) { - MetaDisplay *display = meta_get_display (); - MetaCompositor *compositor = display->compositor; - - if (compositor == NULL) - return None; - - ClutterStage *stage = CLUTTER_STAGE (compositor->stage); - return clutter_x11_get_stage_window (stage); + ClutterActor *stage = meta_backend_get_stage (META_BACKEND (x11)); + return clutter_x11_get_stage_window (CLUTTER_STAGE (stage)); } diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 887be9e2d..a887c0657 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -73,7 +73,6 @@ #include #include "meta-window-actor-private.h" #include "meta-window-group.h" -#include "meta-stage.h" #include "window-private.h" /* to check window->hidden */ #include "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */ #include "util-private.h" @@ -450,55 +449,13 @@ meta_compositor_manage (MetaCompositor *compositor) MetaDisplay *display = compositor->display; Display *xdisplay = display->xdisplay; MetaScreen *screen = display->screen; - Window xwin = 0; - gint width, height; meta_screen_set_cm_selection (display->screen); - if (meta_is_wayland_compositor ()) - { - MetaWaylandCompositor *wayland_compositor = meta_wayland_compositor_get_default (); - - compositor->stage = meta_stage_new (); - - wayland_compositor->stage = compositor->stage; - - meta_screen_get_size (screen, &width, &height); - clutter_actor_set_size (compositor->stage, width, height); - clutter_actor_show (compositor->stage); - } - else - { - compositor->stage = clutter_stage_new (); - - meta_screen_get_size (screen, &width, &height); - clutter_actor_realize (compositor->stage); - - xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); - - XResizeWindow (xdisplay, xwin, width, height); - - { - MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); - Display *backend_xdisplay = meta_backend_x11_get_xdisplay (backend); - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - - XISetMask (mask.mask, XI_KeyPress); - XISetMask (mask.mask, XI_KeyRelease); - XISetMask (mask.mask, XI_ButtonPress); - XISetMask (mask.mask, XI_ButtonRelease); - XISetMask (mask.mask, XI_Enter); - XISetMask (mask.mask, XI_Leave); - XISetMask (mask.mask, XI_FocusIn); - XISetMask (mask.mask, XI_FocusOut); - XISetMask (mask.mask, XI_Motion); - XIClearMask (mask.mask, XI_TouchBegin); - XIClearMask (mask.mask, XI_TouchEnd); - XIClearMask (mask.mask, XI_TouchUpdate); - XISelectEvents (backend_xdisplay, xwin, &mask, 1); - } - } + { + MetaBackend *backend = meta_get_backend (); + compositor->stage = meta_backend_get_stage (backend); + } /* We use connect_after() here to accomodate code in GNOME Shell that, * when benchmarking drawing performance, connects to ::after-paint @@ -528,8 +485,12 @@ meta_compositor_manage (MetaCompositor *compositor) } else { + Window xwin; + compositor->output = screen->composite_overlay_window; + xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (meta_get_backend ())); + XReparentWindow (xdisplay, xwin, compositor->output, 0, 0); meta_empty_stage_input_region (screen); @@ -1021,43 +982,6 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor, meta_window_actor_sync_actor_geometry (window_actor, did_placement); } -void -meta_compositor_sync_screen_size (MetaCompositor *compositor, - guint width, - guint height) -{ - MetaDisplay *display = compositor->display; - - if (meta_is_wayland_compositor ()) - { - /* FIXME: when we support a sliced stage, this is the place to do it - But! This is not the place to apply KMS config, here we only - notify Clutter/Cogl/GL that the framebuffer sizes changed. - - And because for now clutter does not do sliced, we use one - framebuffer the size of the whole screen, and when running on - bare metal MetaMonitorManager will do the necessary tricks to - show the right portions on the right screens. - */ - - clutter_actor_set_size (compositor->stage, width, height); - } - else - { - Display *xdisplay; - Window xwin; - - xdisplay = meta_display_get_xdisplay (display); - xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); - - XResizeWindow (xdisplay, xwin, width, height); - } - - meta_verbose ("Changed size for stage on screen %d to %dx%d\n", - meta_screen_get_screen_number (display->screen), - width, height); -} - static void frame_callback (CoglOnscreen *onscreen, CoglFrameEvent event, diff --git a/src/core/screen.c b/src/core/screen.c index 9742db7ab..4b46413c7 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -2522,9 +2522,6 @@ on_monitors_changed (MetaMonitorManager *manager, &changes); } - meta_compositor_sync_screen_size (screen->display->compositor, - screen->rect.width, screen->rect.height); - /* Queue a resize on all the windows */ meta_screen_foreach_window (screen, meta_screen_resize_func, 0); diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 6c4ba51b5..3ba55c953 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -109,9 +109,6 @@ void meta_compositor_queue_frame_drawn (MetaCompositor *compositor, void meta_compositor_sync_stack (MetaCompositor *compositor, GList *stack); -void meta_compositor_sync_screen_size (MetaCompositor *compositor, - guint width, - guint height); void meta_compositor_flash_screen (MetaCompositor *compositor, MetaScreen *screen); diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h index da0b452f9..c50429abe 100644 --- a/src/meta/meta-backend.h +++ b/src/meta/meta-backend.h @@ -27,6 +27,8 @@ #include +#include + typedef struct _MetaBackend MetaBackend; typedef struct _MetaBackendClass MetaBackendClass; @@ -42,6 +44,8 @@ void meta_backend_set_keymap (MetaBackend *backend, void meta_backend_lock_layout_group (MetaBackend *backend, guint idx); +ClutterActor *meta_backend_get_stage (MetaBackend *backend); + void meta_clutter_init (void); #endif /* META_BACKEND_H */