diff --git a/src/gs-manager.c b/src/gs-manager.c index 8faa41f..b23c28b 100644 --- a/src/gs-manager.c +++ b/src/gs-manager.c @@ -639,7 +639,6 @@ static GSWindow * find_window_at_pointer (GSManager *manager) { GdkDisplay *display; - GdkScreen *screen; GdkMonitor *monitor; int x, y; GSWindow *window; @@ -648,25 +647,27 @@ find_window_at_pointer (GSManager *manager) display = gdk_display_get_default (); GdkSeat* seat = gdk_display_get_default_seat (display); GdkDevice* pointer = gdk_seat_get_pointer (seat); - gdk_device_get_position (pointer, &screen, &x, &y); + gdk_device_get_position (pointer, NULL, &x, &y); monitor = gdk_display_get_monitor_at_point (display, x, y); - /* Find the gs-window that is on that screen */ + /* Find the gs-window that is on that monitor */ window = NULL; for (l = manager->priv->windows; l; l = l->next) { GSWindow *win = GS_WINDOW (l->data); - if (gs_window_get_screen (win) == screen - && gdk_display_get_monitor (display, gs_window_get_monitor (win)) == monitor) { + if (gs_window_get_display (win) == display + && gs_window_get_monitor (win) == monitor) { window = win; } } if (window == NULL) { - gs_debug ("WARNING: Could not find the GSWindow for screen 0"); + gs_debug ("WARNING: Could not find the GSWindow for display &s", + gdk_display_get_name (display)); /* take the first one */ window = manager->priv->windows->data; } else { - gs_debug ("Requesting unlock for screen 0"); + gs_debug ("Requesting unlock for display %s", + gdk_display_get_name (display)); } return window; @@ -694,7 +695,6 @@ manager_maybe_grab_window (GSManager *manager, GSWindow *window) { GdkDisplay *display; - GdkScreen *screen; GdkMonitor *monitor; int x, y; gboolean grabbed; @@ -702,13 +702,13 @@ manager_maybe_grab_window (GSManager *manager, display = gdk_display_get_default (); GdkSeat* seat = gdk_display_get_default_seat (display); GdkDevice* pointer = gdk_seat_get_pointer (seat); - gdk_device_get_position (pointer, &screen, &x, &y); + gdk_device_get_position (pointer, NULL, &x, &y); monitor = gdk_display_get_monitor_at_point (display, x, y); gdk_display_flush (display); grabbed = FALSE; - if (gs_window_get_screen (window) == screen - && gdk_display_get_monitor (display, gs_window_get_monitor (window)) == monitor) { + if (gs_window_get_display (window) == display + && gs_window_get_monitor (window) == monitor) { gs_debug ("Moving grab to %p", window); gs_grab_move_to_window (manager->priv->grab, gs_window_get_gdk_window (window), @@ -799,7 +799,7 @@ apply_background_to_window (GSManager *manager, } gdk_window = gs_window_get_gdk_window (window); - monitor = gdk_display_get_monitor_at_window (gdk_display_get_default (), gdk_window); + monitor = gs_window_get_monitor (window); gdk_monitor_get_geometry (monitor, &monitor_geometry); width = monitor_geometry.width; height = monitor_geometry.height; @@ -977,19 +977,17 @@ connect_window_signals (GSManager *manager, static void gs_manager_create_window_for_monitor (GSManager *manager, - GdkScreen *screen, - int monitor_index) + GdkMonitor *monitor) { GSWindow *window; GdkRectangle rect; - GdkMonitor* monitor = gdk_display_get_monitor(gdk_display_get_default(), monitor_index); gdk_monitor_get_geometry (monitor, &rect); - gs_debug ("Creating window for monitor %d [%d,%d] (%dx%d)", - monitor_index, rect.x, rect.y, rect.width, rect.height); + gs_debug ("Creating a window [%d,%d] (%dx%d)", + rect.x, rect.y, rect.width, rect.height); - window = gs_window_new (screen, monitor_index, manager->priv->lock_active); + window = gs_window_new (monitor, manager->priv->lock_active); gs_window_set_user_switch_enabled (window, manager->priv->user_switch_enabled); gs_window_set_logout_enabled (window, manager->priv->logout_enabled); @@ -1009,68 +1007,80 @@ gs_manager_create_window_for_monitor (GSManager *manager, } static void -on_screen_monitors_changed (GdkScreen *screen, - GSManager *manager) +on_display_monitor_added (GdkDisplay *display, + GdkMonitor *monitor, + GSManager *manager) { - GSList *l; - int n_monitors; - int n_windows; - int i; + GSList *l; + int n_monitors; - n_monitors = gdk_display_get_n_monitors (gdk_display_get_default ()); - n_windows = g_slist_length (manager->priv->windows); + n_monitors = gdk_display_get_n_monitors (display); - gs_debug ("Monitors changed for screen 0: num=%d", n_monitors); + gs_debug ("Monitor added on display %s, now there are %d", + gdk_display_get_name (display), n_monitors); - if (n_monitors > n_windows) { + /* Tear down the unlock dialog in case we want to move it + * to the new monitor + */ + l = manager->priv->windows; + while (l != NULL) + { + gs_window_cancel_unlock_request (GS_WINDOW (l->data)); + l = l->next; + } - /* Tear down unlock dialog in case we want to move it - * to a new monitor - */ - l = manager->priv->windows; - while (l != NULL) { - gs_window_cancel_unlock_request (GS_WINDOW (l->data)); - l = l->next; - } + /* add a new window */ + gs_manager_create_window_for_monitor (manager, monitor); - /* add more windows */ - for (i = n_windows; i < n_monitors; i++) { - gs_manager_create_window_for_monitor (manager, screen, i); - } - - /* And put unlock dialog up where ever it's supposed to be - */ - gs_manager_request_unlock (manager); - } else { - - gdk_x11_grab_server (); - - /* remove the extra windows */ - l = manager->priv->windows; - while (l != NULL) { - GdkScreen *this_screen; - int this_monitor; - GSList *next = l->next; - - this_screen = gs_window_get_screen (GS_WINDOW (l->data)); - this_monitor = gs_window_get_monitor (GS_WINDOW (l->data)); - if (this_screen == screen && this_monitor >= n_monitors) { - gs_window_destroy (GS_WINDOW (l->data)); - manager->priv->windows = g_slist_delete_link (manager->priv->windows, l); - } - l = next; - } + /* and put unlock dialog up whereever it's supposed to be */ + gs_manager_request_unlock (manager); +} - /* make sure there is a lock dialog on a connected monitor, +static void +on_display_monitor_removed (GdkDisplay *display, + GdkMonitor *monitor, + GSManager *manager) +{ + GSList *l; + int n_monitors; + int n_windows; + + n_monitors = gdk_display_get_n_monitors (display); + n_windows = g_slist_length (manager->priv->windows); + + gs_debug ("Monitor removed on display %s, now there are %d", + gdk_display_get_name (display), n_monitors); + + gdk_x11_grab_server (); + + /* remove the now extra window */ + l = manager->priv->windows; + while (l != NULL) + { + GdkDisplay *this_display; + GdkMonitor *this_monitor; + GSList *next = l->next; + + this_display = gs_window_get_display (GS_WINDOW (l->data)); + this_monitor = gs_window_get_monitor (GS_WINDOW (l->data)); + + if (this_display == display && this_monitor == monitor) + { + gs_window_destroy (GS_WINDOW (l->data)); + manager->priv->windows = g_slist_delete_link (manager->priv->windows, l); + } + l = next; + } + + /* make sure there is a lock dialog on a connected monitor, * and that the keyboard is still properly grabbed after all * the windows above got destroyed*/ - if (n_windows > n_monitors) { - gs_manager_request_unlock (manager); - } + if (n_windows > n_monitors) { + gs_manager_request_unlock (manager); + } - gdk_display_flush (gdk_display_get_default ()); - gdk_x11_ungrab_server (); - } + gdk_display_flush (display); + gdk_x11_ungrab_server (); } static void @@ -1088,11 +1098,15 @@ gs_manager_destroy_windows (GSManager *manager) display = gdk_display_get_default (); - g_signal_handlers_disconnect_by_func (gdk_display_get_default_screen (display), - on_screen_monitors_changed, - manager); + g_signal_handlers_disconnect_by_func (display, + on_display_monitor_removed, + manager); + g_signal_handlers_disconnect_by_func (display, + on_display_monitor_added, + manager); - for (l = manager->priv->windows; l; l = l->next) { + + for (l = manager->priv->windows; l; l = l->next) { gs_window_destroy (l->data); } g_slist_free (manager->priv->windows); @@ -1136,28 +1150,29 @@ gs_manager_finalize (GObject *object) } static void -gs_manager_create_windows_for_screen (GSManager *manager, - GdkScreen *screen) +gs_manager_create_windows_for_display (GSManager *manager, + GdkDisplay *display) { - int n_monitors; - int i; + int n_monitors; + int i; g_return_if_fail (manager != NULL); g_return_if_fail (GS_IS_MANAGER (manager)); - g_return_if_fail (GDK_IS_SCREEN (screen)); + g_return_if_fail (GDK_IS_DISPLAY (display)); g_object_ref (manager); - g_object_ref (screen); + g_object_ref (display); - n_monitors = gdk_display_get_n_monitors (gdk_display_get_default ()); + n_monitors = gdk_display_get_n_monitors (display); - gs_debug ("Creating %d windows for screen 0", n_monitors); + gs_debug ("Creating %d windows for display %s", n_monitors, gdk_display_get_name (display)); for (i = 0; i < n_monitors; i++) { - gs_manager_create_window_for_monitor (manager, screen, i); + GdkMonitor *mon = gdk_display_get_monitor (display, i); + gs_manager_create_window_for_monitor (manager, mon); } - g_object_unref (screen); + g_object_unref (display); g_object_unref (manager); } @@ -1165,7 +1180,6 @@ static void gs_manager_create_windows (GSManager *manager) { GdkDisplay *display; - GdkScreen *screen; g_return_if_fail (manager != NULL); g_return_if_fail (GS_IS_MANAGER (manager)); @@ -1173,14 +1187,17 @@ gs_manager_create_windows (GSManager *manager) g_assert (manager->priv->windows == NULL); display = gdk_display_get_default (); - screen = gdk_display_get_default_screen (display); - g_signal_connect (screen, - "monitors-changed", - G_CALLBACK (on_screen_monitors_changed), - manager); + g_signal_connect (display, + "monitor-added", + G_CALLBACK (on_display_monitor_added), + manager); + g_signal_connect (display, + "monitor-removed", + G_CALLBACK (on_display_monitor_removed), + manager); - gs_manager_create_windows_for_screen (manager, screen); + gs_manager_create_windows_for_display (manager, display); } GSManager * diff --git a/src/gs-window-x11.c b/src/gs-window-x11.c index 9fedbf7..71f4850 100644 --- a/src/gs-window-x11.c +++ b/src/gs-window-x11.c @@ -64,7 +64,7 @@ enum { struct _GSWindowPrivate { - int monitor; + GdkMonitor *monitor; GdkRectangle geometry; guint obscured : 1; @@ -257,24 +257,26 @@ gs_window_clear (GSWindow *window) static cairo_region_t * get_outside_region (GSWindow *window) { - GdkMonitor* monitor; - int i; + GdkDisplay *display; + int i; cairo_region_t *region; - GdkDisplay* default_display = gdk_display_get_default(); + display = gtk_widget_get_display (GTK_WIDGET (window)); region = cairo_region_create (); - for (i = 0; i < window->priv->monitor; i++) { + for (i = 0; i < gdk_display_get_n_monitors (display); i++) { GdkRectangle geometry; cairo_rectangle_int_t rectangle; - monitor = gdk_display_get_monitor (default_display, i); - gdk_monitor_get_geometry (monitor, &geometry); - rectangle.x = geometry.x; - rectangle.y = geometry.y; - rectangle.width = geometry.width; - rectangle.height = geometry.height; - cairo_region_union_rectangle (region, &rectangle); + GdkMonitor *mon = gdk_display_get_monitor (display, i); + if (mon != window->priv->monitor) { + gdk_monitor_get_geometry(mon, &geometry); + rectangle.x = geometry.x; + rectangle.y = geometry.y; + rectangle.width = geometry.width; + rectangle.height = geometry.height; + cairo_region_union_rectangle(region, &rectangle); + } } return region; @@ -289,11 +291,9 @@ update_geometry (GSWindow *window) outside_region = get_outside_region (window); - GdkDisplay* display = gdk_display_get_default (); - GdkMonitor* monitor = gdk_display_get_monitor (display, window->priv->monitor); - gdk_monitor_get_geometry (monitor, &geometry); - gs_debug ("got geometry for monitor %d: x=%d y=%d w=%d h=%d", - window->priv->monitor, + gdk_monitor_get_geometry (window->priv->monitor, &geometry); + + gs_debug ("got geometry for monitor: x=%d y=%d w=%d h=%d", geometry.x, geometry.y, geometry.width, @@ -305,8 +305,7 @@ update_geometry (GSWindow *window) cairo_region_get_extents (monitor_region, (cairo_rectangle_int_t *)&geometry); cairo_region_destroy (monitor_region); - gs_debug ("using geometry for monitor %d: x=%d y=%d w=%d h=%d", - window->priv->monitor, + gs_debug ("using geometry for monitor: x=%d y=%d w=%d h=%d", geometry.x, geometry.y, geometry.width, @@ -319,12 +318,11 @@ update_geometry (GSWindow *window) } static void -screen_size_changed (GdkScreen *screen, - GSWindow *window) +monitor_geometry_notify (GdkMonitor *monitor, + GParamSpec *pspec, + GSWindow *window) { - (void) screen; - - gs_debug ("Got screen size changed signal"); + gs_debug ("Got monitor geometry notify signal"); gtk_widget_queue_resize (GTK_WIDGET (window)); } @@ -375,9 +373,10 @@ gs_window_move_resize_window (GSWindow *window, static void gs_window_real_unrealize (GtkWidget *widget) { - g_signal_handlers_disconnect_by_func (gtk_window_get_screen (GTK_WINDOW (widget)), - screen_size_changed, - widget); + GdkMonitor *monitor = GS_WINDOW (widget)->priv->monitor; + + g_signal_handlers_disconnect_by_func (monitor, monitor_geometry_notify, + widget); if (GTK_WIDGET_CLASS (gs_window_parent_class)->unrealize) { GTK_WIDGET_CLASS (gs_window_parent_class)->unrealize (widget); @@ -388,15 +387,15 @@ gs_window_real_unrealize (GtkWidget *widget) extern char **environ; static gchar ** -spawn_make_environment_for_screen (GdkScreen *screen, - gchar **envp) +spawn_make_environment_for_display (GdkDisplay *display, + gchar **envp) { gchar **retval = NULL; - gchar *display_name; + const gchar *display_name; gint display_index = -1; gint i, env_len; - g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); if (envp == NULL) envp = environ; @@ -408,7 +407,7 @@ spawn_make_environment_for_screen (GdkScreen *screen, retval = g_new (char *, env_len + 1); retval[env_len] = NULL; - display_name = gdk_screen_make_display_name (screen); + display_name = gdk_display_get_name (display); for (i = 0; i < env_len; i++) if (i == display_index) @@ -418,14 +417,14 @@ spawn_make_environment_for_screen (GdkScreen *screen, g_assert (i == env_len); - g_free (display_name); - return retval; } static void gs_window_real_realize (GtkWidget *widget) { + GdkMonitor *monitor = GS_WINDOW (widget)->priv->monitor; + if (GTK_WIDGET_CLASS (gs_window_parent_class)->realize) { GTK_WIDGET_CLASS (gs_window_parent_class)->realize (widget); } @@ -434,9 +433,9 @@ gs_window_real_realize (GtkWidget *widget) gs_window_move_resize_window (GS_WINDOW (widget), TRUE, TRUE); - g_signal_connect (gtk_window_get_screen (GTK_WINDOW (widget)), - "size_changed", - G_CALLBACK (screen_size_changed), + g_signal_connect (monitor, + "notify::geometry", + G_CALLBACK (monitor_geometry_notify), widget); } @@ -885,7 +884,7 @@ spawn_on_window (GSWindow *window, return FALSE; } - envp = spawn_make_environment_for_screen (gtk_window_get_screen (GTK_WINDOW (window)), NULL); + envp = spawn_make_environment_for_display (gtk_widget_get_display (GTK_WIDGET (window)), NULL); error = NULL; result = g_spawn_async_with_pipes (NULL, @@ -1573,23 +1572,11 @@ gs_window_set_lock_enabled (GSWindow *window, g_object_notify (G_OBJECT (window), "lock-enabled"); } -void -gs_window_set_screen (GSWindow *window, - GdkScreen *screen) -{ - - g_return_if_fail (GS_IS_WINDOW (window)); - g_return_if_fail (GDK_IS_SCREEN (screen)); - - gtk_window_set_screen (GTK_WINDOW (window), screen); -} - -GdkScreen * -gs_window_get_screen (GSWindow *window) +GdkDisplay *gs_window_get_display (GSWindow *window) { - g_return_val_if_fail (GS_IS_WINDOW (window), NULL); + g_return_val_if_fail (GS_IS_WINDOW (window), NULL); - return gtk_window_get_screen (GTK_WINDOW (window)); + return gtk_widget_get_display (GTK_WIDGET (window)); } void @@ -1674,7 +1661,7 @@ gs_window_set_status_message (GSWindow *window, void gs_window_set_monitor (GSWindow *window, - int monitor) + GdkMonitor *monitor) { g_return_if_fail (GS_IS_WINDOW (window)); @@ -1689,10 +1676,10 @@ gs_window_set_monitor (GSWindow *window, g_object_notify (G_OBJECT (window), "monitor"); } -int -gs_window_get_monitor (GSWindow *window) +GdkMonitor +*gs_window_get_monitor (GSWindow *window) { - g_return_val_if_fail (GS_IS_WINDOW (window), -1); + g_return_val_if_fail (GS_IS_WINDOW (window), NULL); return window->priv->monitor; } @@ -1730,7 +1717,7 @@ gs_window_set_property (GObject *object, gs_window_set_logout_timeout (self, g_value_get_long (value)); break; case PROP_MONITOR: - gs_window_set_monitor (self, g_value_get_int (value)); + gs_window_set_monitor (self, g_value_get_pointer (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1771,7 +1758,7 @@ gs_window_get_property (GObject *object, g_value_set_long (value, self->priv->logout_timeout); break; case PROP_MONITOR: - g_value_set_int (value, self->priv->monitor); + g_value_set_pointer (value, self->priv->monitor); break; case PROP_OBSCURED: g_value_set_boolean (value, self->priv->obscured); @@ -1853,15 +1840,17 @@ static gboolean gs_window_real_motion_notify_event (GtkWidget *widget, GdkEventMotion *event) { - GSWindow *window; - gdouble distance; - gdouble min_distance; - gdouble min_percentage = 0.1; - GdkScreen *screen; + GSWindow *window; + gdouble distance; + gdouble min_distance; + gdouble min_percentage = 0.1; + GdkDisplay *display; + GdkScreen *screen; window = GS_WINDOW (widget); - screen = gs_window_get_screen (window); + display = gs_window_get_display (window); + screen = gdk_display_get_default_screen (display); min_distance = gdk_screen_get_width (screen) * min_percentage; /* if the last position was not set then don't detect motion */ @@ -2158,15 +2147,11 @@ gs_window_class_init (GSWindowClass *klass) G_PARAM_READWRITE)); g_object_class_install_property (object_class, - PROP_MONITOR, - g_param_spec_int ("monitor", - "Xinerama monitor", - "The monitor (in terms of Xinerama) which the window is on", - 0, - G_MAXINT, - 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - + PROP_MONITOR, + g_param_spec_pointer ("monitor", + "Gdk monitor", + "The monitor (in terms of Gdk) which the window is on", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); } static void @@ -2410,11 +2395,12 @@ gs_window_finalize (GObject *object) } GSWindow * -gs_window_new (GdkScreen *screen, - int monitor, - gboolean lock_enabled) +gs_window_new (GdkMonitor *monitor, + gboolean lock_enabled) { - GObject *result; + GObject *result; + GdkDisplay *display = gdk_monitor_get_display (monitor); + GdkScreen *screen = gdk_display_get_default_screen (display); result = g_object_new (GS_TYPE_WINDOW, "type", GTK_WINDOW_POPUP, diff --git a/src/gs-window.h b/src/gs-window.h index 2e034f3..9a98747 100644 --- a/src/gs-window.h +++ b/src/gs-window.h @@ -57,10 +57,11 @@ GType gs_window_get_type(void); gboolean gs_window_is_obscured(GSWindow* window); gboolean gs_window_is_dialog_up(GSWindow* window); -void gs_window_set_screen(GSWindow* window, GdkScreen* screen); -GdkScreen* gs_window_get_screen(GSWindow* window); -void gs_window_set_monitor(GSWindow* window, int monitor); -int gs_window_get_monitor(GSWindow* window); +GdkDisplay *gs_window_get_display(GSWindow *window); +void gs_window_set_monitor (GSWindow *window, + GdkMonitor *monitor); +GdkMonitor *gs_window_get_monitor(GSWindow* window); + void gs_window_set_background_surface(GSWindow* window, cairo_surface_t* surface); void gs_window_set_lock_enabled(GSWindow* window, gboolean lock_enabled); @@ -76,7 +77,8 @@ void gs_window_show_message(GSWindow* window, const char* summary, const char* b void gs_window_request_unlock(GSWindow* window); void gs_window_cancel_unlock_request(GSWindow* window); -GSWindow* gs_window_new(GdkScreen* screen, int monitor, gboolean lock_enabled); +GSWindow* gs_window_new(GdkMonitor *monitor, + gboolean lock_enabled); void gs_window_show(GSWindow* window); void gs_window_destroy(GSWindow* window); GdkWindow* gs_window_get_gdk_window(GSWindow* window);