diff options
-rw-r--r-- | src/core/display.c | 33 | ||||
-rw-r--r-- | src/core/monitor-private.h | 7 | ||||
-rw-r--r-- | src/core/monitor.c | 122 | ||||
-rw-r--r-- | src/core/screen-private.h | 4 | ||||
-rw-r--r-- | src/core/screen.c | 41 |
5 files changed, 122 insertions, 85 deletions
diff --git a/src/core/display.c b/src/core/display.c index e39361e83..64f5511c1 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2146,6 +2146,7 @@ event_callback (XEvent *event, gboolean bypass_compositor; gboolean filter_out_event; XIEvent *input_event; + MetaMonitorManager *monitor; display = data; @@ -2157,6 +2158,14 @@ event_callback (XEvent *event, #ifdef HAVE_STARTUP_NOTIFICATION sn_display_process_event (display->sn_display, event); #endif + + /* Intercept XRandR events early and don't attempt any + processing for them. We still let them through to Gdk though, + so it can update its own internal state. + */ + monitor = meta_monitor_manager_get (); + if (meta_monitor_manager_handle_xevent (monitor, event)) + return FALSE; bypass_compositor = FALSE; filter_out_event = FALSE; @@ -2822,32 +2831,10 @@ event_callback (XEvent *event, meta_stack_tracker_configure_event (screen->stack_tracker, &event->xconfigure); } + if (window && window->override_redirect) meta_window_configure_notify (window, &event->xconfigure); - else - /* Handle screen resize */ - { - MetaScreen *screen; - screen = meta_display_screen_for_root (display, - event->xconfigure.window); - - if (screen != NULL) - { -#ifdef HAVE_RANDR - /* do the resize the official way */ - XRRUpdateConfiguration (event); -#else - /* poke around in Xlib */ - screen->xscreen->width = event->xconfigure.width; - screen->xscreen->height = event->xconfigure.height; -#endif - - meta_screen_resize (screen, - event->xconfigure.width, - event->xconfigure.height); - } - } break; case ConfigureRequest: /* This comment and code is found in both twm and fvwm */ diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h index 93f5ebca5..c159d2b21 100644 --- a/src/core/monitor-private.h +++ b/src/core/monitor-private.h @@ -162,6 +162,11 @@ MetaOutput *meta_monitor_manager_get_outputs (MetaMonitorManager * int meta_monitor_manager_get_primary_index (MetaMonitorManager *manager); -void meta_monitor_manager_invalidate (MetaMonitorManager *manager); +gboolean meta_monitor_manager_handle_xevent (MetaMonitorManager *manager, + XEvent *event); + +void meta_monitor_manager_get_screen_size (MetaMonitorManager *manager, + int *width, + int *height); #endif diff --git a/src/core/monitor.c b/src/core/monitor.c index e109bfc36..0a3aba145 100644 --- a/src/core/monitor.c +++ b/src/core/monitor.c @@ -56,16 +56,16 @@ enum wl_output_transform { #endif typedef enum { + META_BACKEND_UNSPECIFIED, META_BACKEND_DUMMY, - META_BACKEND_XRANDR, - META_BACKEND_COGL -} MetaBackend; + META_BACKEND_XRANDR +} MetaMonitorBackend; struct _MetaMonitorManager { GObject parent_instance; - MetaBackend backend; + MetaMonitorBackend backend; /* XXX: this structure is very badly packed, but I like the logical organization @@ -75,6 +75,8 @@ struct _MetaMonitorManager int max_screen_width; int max_screen_height; + int screen_width; + int screen_height; /* Outputs refer to physical screens, CRTCs refer to stuff that can drive outputs @@ -100,6 +102,8 @@ struct _MetaMonitorManager Display *xdisplay; XRRScreenResources *resources; int time; + int rr_event_base; + int rr_error_base; #endif int dbus_name_id; @@ -125,23 +129,17 @@ make_dummy_monitor_config (MetaMonitorManager *manager) { manager->backend = META_BACKEND_DUMMY; + manager->max_screen_width = 65535; + manager->max_screen_height = 65535; + manager->screen_width = 1024; + manager->screen_height = 768; + manager->modes = g_new0 (MetaMonitorMode, 1); manager->n_modes = 1; manager->modes[0].mode_id = 1; - if (manager->xdisplay) - { - Screen *screen = ScreenOfDisplay (manager->xdisplay, - DefaultScreen (manager->xdisplay)); - - manager->modes[0].width = WidthOfScreen (screen); - manager->modes[0].height = HeightOfScreen (screen); - } - else - { - manager->modes[0].width = 1024; - manager->modes[0].height = 768; - } + manager->modes[0].width = manager->screen_width; + manager->modes[0].height = manager->screen_height; manager->modes[0].refresh_rate = 60.0; manager->crtcs = g_new0 (MetaCRTC, 1); @@ -177,9 +175,6 @@ make_dummy_monitor_config (MetaMonitorManager *manager) manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0]; manager->outputs[0].n_possible_clones = 0; manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0); - - manager->max_screen_width = manager->modes[0].width; - manager->max_screen_height = manager->modes[0].height; } #ifdef HAVE_RANDR @@ -192,6 +187,7 @@ read_monitor_infos_from_xrandr (MetaMonitorManager *manager) unsigned int i, j, k; unsigned int n_actual_outputs; int min_width, min_height; + Screen *screen; if (manager->resources) XRRFreeScreenResources (manager->resources); @@ -203,12 +199,17 @@ read_monitor_infos_from_xrandr (MetaMonitorManager *manager) &manager->max_screen_width, &manager->max_screen_height); + screen = ScreenOfDisplay (manager->xdisplay, + DefaultScreen (manager->xdisplay)); + /* This is updated because we called RRUpdateConfiguration below */ + manager->screen_width = WidthOfScreen (screen); + manager->screen_height = HeightOfScreen (screen); + resources = XRRGetScreenResourcesCurrent (manager->xdisplay, DefaultRootWindow (manager->xdisplay)); if (!resources) return make_dummy_monitor_config (manager); - manager->backend = META_BACKEND_XRANDR; manager->resources = resources; manager->time = resources->configTimestamp; manager->n_outputs = resources->noutput; @@ -388,7 +389,7 @@ meta_monitor_manager_init (MetaMonitorManager *manager) { } -static gboolean +static MetaMonitorBackend make_debug_config (MetaMonitorManager *manager) { const char *env; @@ -396,14 +397,14 @@ make_debug_config (MetaMonitorManager *manager) env = g_getenv ("META_DEBUG_MULTIMONITOR"); if (env == NULL) - return FALSE; + return META_BACKEND_UNSPECIFIED; #ifdef HAVE_RANDR if (strcmp (env, "xrandr") == 0) - read_monitor_infos_from_xrandr (manager); + return META_BACKEND_XRANDR; else #endif - make_dummy_monitor_config (manager); + return META_BACKEND_DUMMY; return TRUE; } @@ -411,15 +412,12 @@ make_debug_config (MetaMonitorManager *manager) static void read_current_config (MetaMonitorManager *manager) { - if (make_debug_config (manager)) - return; - - if (has_dummy_output ()) - return make_dummy_monitor_config (manager); - #ifdef HAVE_RANDR - return read_monitor_infos_from_xrandr (manager); + if (manager->backend == META_BACKEND_XRANDR) + return read_monitor_infos_from_xrandr (manager); #endif + + return make_dummy_monitor_config (manager); } /* @@ -526,6 +524,40 @@ meta_monitor_manager_new (Display *display) manager->xdisplay = display; + manager->backend = make_debug_config (manager); + + if (manager->backend == META_BACKEND_UNSPECIFIED) + { +#ifdef HAVE_XRANDR + if (display) + manager->backend = META_BACKEND_XRANDR; + else +#endif + if (has_dummy_output ()) + manager->backend = META_BACKEND_DUMMY; + } + +#ifdef HAVE_XRANDR + if (manager->backend == META_BACKEND_XRANDR) + { + if (!XRRQueryExtension (display, + &manager->rr_event_base, + &manager->rr_error_base)) + { + manager->backend = META_BACKEND_DUMMY; + } + else + { + /* We only use ScreenChangeNotify, but GDK uses the others, + and we don't want to step on its toes */ + XRRSelectInput (display, DefaultRootWindow (display), + RRScreenChangeNotifyMask + | RRCrtcChangeNotifyMask + | RROutputPropertyNotifyMask); + } + } +#endif + read_current_config (manager); make_logical_config (manager); return manager; @@ -1157,7 +1189,17 @@ meta_monitor_manager_get_primary_index (MetaMonitorManager *manager) } void -meta_monitor_manager_invalidate (MetaMonitorManager *manager) +meta_monitor_manager_get_screen_size (MetaMonitorManager *manager, + int *width, + int *height) +{ + *width = manager->screen_width; + *height = manager->screen_height; +} + +gboolean +meta_monitor_manager_handle_xevent (MetaMonitorManager *manager, + XEvent *event) { MetaOutput *old_outputs; MetaCRTC *old_crtcs; @@ -1165,6 +1207,15 @@ meta_monitor_manager_invalidate (MetaMonitorManager *manager) MetaMonitorMode *old_modes; int n_old_outputs; + if (manager->backend != META_BACKEND_XRANDR) + return FALSE; + +#ifdef HAVE_RANDR + if ((event->type - manager->rr_event_base) != RRScreenChangeNotify) + return FALSE; + + XRRUpdateConfiguration (event); + /* Save the old structures, so they stay valid during the update */ old_outputs = manager->outputs; n_old_outputs = manager->n_outputs; @@ -1182,5 +1233,10 @@ meta_monitor_manager_invalidate (MetaMonitorManager *manager) free_output_array (old_outputs, n_old_outputs); g_free (old_modes); g_free (old_crtcs); + + return TRUE; +#else + return FALSE; +#endif } diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 894eda5e4..9e0da8d7a 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -222,10 +222,6 @@ void meta_screen_calc_workspace_layout (MetaScreen *screen, MetaWorkspaceLayout *layout); void meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout); -void meta_screen_resize (MetaScreen *screen, - int width, - int height); - void meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen, MetaWindow *keep); diff --git a/src/core/screen.c b/src/core/screen.c index cb02f201b..86f462d2f 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -510,6 +510,7 @@ meta_screen_new (MetaDisplay *display, char buf[128]; guint32 manager_timestamp; gulong current_workspace; + MetaMonitorManager *manager; replace_current_wm = meta_get_replace_current_wm (); @@ -668,8 +669,17 @@ meta_screen_new (MetaDisplay *display, screen->xscreen = ScreenOfDisplay (xdisplay, number); screen->xroot = xroot; screen->rect.x = screen->rect.y = 0; - screen->rect.width = WidthOfScreen (screen->xscreen); - screen->rect.height = HeightOfScreen (screen->xscreen); + + meta_monitor_manager_initialize (screen->display->xdisplay); + + manager = meta_monitor_manager_get (); + g_signal_connect (manager, "monitors-changed", + G_CALLBACK (on_monitors_changed), screen); + + meta_monitor_manager_get_screen_size (manager, + &screen->rect.width, + &screen->rect.height); + screen->current_cursor = -1; /* invalid/unset */ screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen); screen->default_depth = DefaultDepthOfScreen (screen->xscreen); @@ -694,17 +704,7 @@ meta_screen_new (MetaDisplay *display, screen->compositor_data = NULL; screen->guard_window = None; - { - MetaMonitorManager *manager; - - meta_monitor_manager_initialize (screen->display->xdisplay); - - reload_monitor_infos (screen); - - manager = meta_monitor_manager_get (); - g_signal_connect (manager, "monitors-changed", - G_CALLBACK (on_monitors_changed), screen); - } + reload_monitor_infos (screen); meta_screen_set_cursor (screen, META_CURSOR_DEFAULT); @@ -2845,23 +2845,16 @@ meta_screen_resize_func (MetaScreen *screen, meta_window_recalc_features (window); } -void -meta_screen_resize (MetaScreen *screen, - int width, - int height) -{ - screen->rect.width = width; - screen->rect.height = height; - - meta_monitor_manager_invalidate (meta_monitor_manager_get ()); -} - static void on_monitors_changed (MetaMonitorManager *manager, MetaScreen *screen) { GSList *tmp, *windows; + meta_monitor_manager_get_screen_size (manager, + &screen->rect.width, + &screen->rect.height); + reload_monitor_infos (screen); set_desktop_geometry_hint (screen); |