From a0def065480f936a934e3dd4b11364cef41b24e5 Mon Sep 17 00:00:00 2001 From: Alistair Buxton Date: Fri, 2 May 2014 21:43:19 +0100 Subject: [PATCH] This patch "fixes" the multimonitor output problems. It makes the tasklist idle function into a timeout, introducing a half-second delay to ensure the race condition does not happen. It changes the panel to abuse the position-changed event to signal that the panel moved to a different output. It changes the plugin interface so that position change events are passed through even if the position didn't actually change. --- libxfce4panel/xfce-panel-plugin.c | 8 +++---- panel/panel-window.c | 1 + plugins/tasklist/tasklist-widget.c | 46 +++++++++----------------------------- 3 files changed, 15 insertions(+), 40 deletions(-) diff --git a/libxfce4panel/xfce-panel-plugin.c b/libxfce4panel/xfce-panel-plugin.c index 9fb43d1..bd09f53 100644 --- a/libxfce4panel/xfce-panel-plugin.c +++ b/libxfce4panel/xfce-panel-plugin.c @@ -1449,9 +1449,9 @@ xfce_panel_plugin_set_screen_position (XfcePanelPluginProvider *provider, panel_return_if_fail (XFCE_IS_PANEL_PLUGIN (provider)); /* check if update is required */ - if (G_LIKELY (plugin->priv->screen_position != screen_position - || xfce_screen_position_is_floating (screen_position))) - { +// if (G_LIKELY (plugin->priv->screen_position != screen_position +// || xfce_screen_position_is_floating (screen_position))) +// { plugin->priv->screen_position = screen_position; g_signal_emit (G_OBJECT (plugin), @@ -1459,7 +1459,7 @@ xfce_panel_plugin_set_screen_position (XfcePanelPluginProvider *provider, screen_position); g_object_notify_by_pspec (G_OBJECT (plugin), plugin_props[PROP_SCREEN_POSITION]); - } +// } } diff --git a/panel/panel-window.c b/panel/panel-window.c index 982ea9b..296e1a1 100644 --- a/panel/panel-window.c +++ b/panel/panel-window.c @@ -686,6 +686,7 @@ panel_window_set_property (GObject *object, window->output_name = g_strdup (val_string); panel_window_screen_layout_changed (window->screen, window); + panel_window_plugins_update (window, PLUGIN_PROP_SCREEN_POSITION); break; case PROP_POSITION: diff --git a/plugins/tasklist/tasklist-widget.c b/plugins/tasklist/tasklist-widget.c index 1a1755b..99c982a 100644 --- a/plugins/tasklist/tasklist-widget.c +++ b/plugins/tasklist/tasklist-widget.c @@ -163,8 +163,6 @@ struct _XfceTasklist * the monitor the tasklist is on */ guint all_monitors : 1; guint n_monitors; - guint my_monitor; - GdkRectangle *all_monitors_geometry; /* whether we show wireframes when hovering a button in * the tasklist */ @@ -558,7 +556,6 @@ xfce_tasklist_init (XfceTasklist *tasklist) tasklist->show_handle = TRUE; tasklist->all_monitors = TRUE; tasklist->n_monitors = 0; - tasklist->all_monitors_geometry = NULL; tasklist->window_scrolling = TRUE; tasklist->all_blinking = TRUE; tasklist->middle_click = XFCE_TASKLIST_MIDDLE_CLICK_DEFAULT; @@ -1902,8 +1899,6 @@ xfce_tasklist_update_monitor_geometry_idle (gpointer data) XfceTasklist *tasklist = XFCE_TASKLIST (data); GdkScreen *screen; gboolean geometry_set = FALSE; - GdkWindow *window; - guint tmp; panel_return_val_if_fail (XFCE_IS_TASKLIST (tasklist), FALSE); @@ -1912,23 +1907,10 @@ xfce_tasklist_update_monitor_geometry_idle (gpointer data) if (!tasklist->all_monitors) { screen = gtk_widget_get_screen (GTK_WIDGET (tasklist)); - window = gtk_widget_get_window (GTK_WIDGET (tasklist)); - if (G_LIKELY (screen != NULL - && window != NULL - && (tasklist->n_monitors = gdk_screen_get_n_monitors (screen)) > 1)) + if (G_LIKELY (screen != NULL)) { - /* set the monitor geometry */ - tasklist->my_monitor = gdk_screen_get_monitor_at_window (screen, window); - - if (tasklist->all_monitors_geometry) - tasklist->all_monitors_geometry = g_renew (GdkRectangle, tasklist->all_monitors_geometry, tasklist->n_monitors); - else - tasklist->all_monitors_geometry = g_new (GdkRectangle, tasklist->n_monitors); - - for(tmp = 0; tmp < tasklist->n_monitors; tmp++) - gdk_screen_get_monitor_geometry (screen, tmp, &tasklist->all_monitors_geometry[tmp]); - + tasklist->n_monitors = gdk_screen_get_n_monitors (screen); geometry_set = TRUE; } } @@ -2248,8 +2230,8 @@ xfce_tasklist_button_visible (XfceTasklistChild *child, WnckWorkspace *active_ws) { XfceTasklist *tasklist = XFCE_TASKLIST (child->tasklist); - GdkRectangle window, intersection; - guint best_size = 0, best_monitor = 0, size, tmp; + gint x, y, w, h; + GdkWindow *window; panel_return_val_if_fail (active_ws == NULL || WNCK_IS_WORKSPACE (active_ws), FALSE); panel_return_val_if_fail (XFCE_IS_TASKLIST (tasklist), FALSE); @@ -2257,20 +2239,12 @@ xfce_tasklist_button_visible (XfceTasklistChild *child, if (xfce_tasklist_filter_monitors (tasklist)) { - /* center of the window must be on this screen */ - wnck_window_get_geometry (child->window, &window.x, &window.y, &window.width, &window.height); + window = gtk_widget_get_window (GTK_WIDGET (tasklist)); + /* center of the window must be on or nearest this monitor */ + wnck_window_get_geometry (child->window, &x, &y, &w, &h); - for (tmp = 0; tmp < tasklist->n_monitors; tmp++) - { - gdk_rectangle_intersect(&tasklist->all_monitors_geometry[tmp], &window, &intersection); - size = intersection.width * intersection.height; - if (size > best_size) - { - best_size = size; - best_monitor = tmp; - } - } - if (best_monitor != tasklist->my_monitor) + if (gdk_screen_get_monitor_at_window(tasklist->gdk_screen, window) != + gdk_screen_get_monitor_at_point(tasklist->gdk_screen, x+(w/2), y+(h/2)) ) return FALSE; } @@ -3978,7 +3952,7 @@ xfce_tasklist_update_monitor_geometry (XfceTasklist *tasklist) { if (tasklist->update_monitor_geometry_id == 0) { - tasklist->update_monitor_geometry_id = g_idle_add_full (G_PRIORITY_LOW, xfce_tasklist_update_monitor_geometry_idle, + tasklist->update_monitor_geometry_id = g_timeout_add_full (G_PRIORITY_LOW, 1000, xfce_tasklist_update_monitor_geometry_idle, tasklist, xfce_tasklist_update_monitor_geometry_idle_destroy); } } -- 1.9.1