summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <halfline@hawaii.rr.com>2003-08-15 22:09:55 +0000
committerRay Strode <halfline@src.gnome.org>2003-08-15 22:09:55 +0000
commit2fc880db192cd995bb86697f999295b20fefeed7 (patch)
treea21363a5325bd4669906754c2c916ed0bebec91b
parent60a453f5a01c8b3fdcb38771eed9674e3f007500 (diff)
downloadmetacity-2fc880db192cd995bb86697f999295b20fefeed7.tar.gz
Changed MRU list to be per workspace instead of per display, so sticky
2003-08-15 Ray Strode <halfline@hawaii.rr.com> Changed MRU list to be per workspace instead of per display, so sticky windows don't hijack the window focus after workspace switching (Bug #97635). * src/delete.c (meta_window_delete): Use meta_workspace_focus_top_window instead of meta_screen_focus_top_window. * src/display.c (meta_display_open): Stop using display->mru_list. (find_tab_forward): (find_tab_backward): (meta_display_get_tab_list): Use workspace->mru_list instead of display->mru_list and remove unneeded calls to meta_window_visible_on_workspace * src/display.h: Remove mru_list from MetaDisplay * src/keybindings.c (handle_toggle_desktop): Use meta_workspace_focus_top_window instead of meta_screen_focus_top_window. * src/screen.c (meta_screen_focus_top_window): (meta_screen_focus_default_window): Remove functions. (meta_screen_show_desktop): Use meta_workspace_focus_top_window instead of meta_screen_focus_top_window. * src/screen.h: Remove meta_screen_focus_top_window and meta_screen_focus_default_window declarations. * src/window.c (meta_window_new): Stop using display->mru_list. (meta_window_free): Use meta_workspace_focus_top_window instead of meta_screen_focus_top_window and stop using display->mru_list. (meta_window_stick): Add sticky window to all workspace MRU lists. (meta_window_unstick): Remove non-sticky window from the workspace MRU lists it doesn't belong in. (meta_window_notify_focus): Move newly focused window to the front of active workspace's MRU list. * src/workspace.c (meta_workspace_new): Initialize workspace->mru_list to NULL. (meta_workspace_add_window): Add window to workspace's MRU list. (meta_workspace_remove_window): Remove window from workspace's MRU list. (meta_workspace_activate_with_focus): Use meta_workspace_focus_default_window instead of meta_screen_focus_default_window. (meta_workspace_focus_default_window): (meta_workspace_focus_mru_window): (meta_workspace_focus_top_window): Add functions. * src/workspace.h: Add mru_list to MetaWorkspace and add function declarations for meta_workspace_focus_default_window, meta_workspace_focus_mru_window, meta_workspace_focus_top_window.
-rw-r--r--ChangeLog57
-rw-r--r--src/delete.c4
-rw-r--r--src/display.c37
-rw-r--r--src/display.h5
-rw-r--r--src/keybindings.c2
-rw-r--r--src/screen.c45
-rw-r--r--src/screen.h5
-rw-r--r--src/window.c61
-rw-r--r--src/workspace.c94
-rw-r--r--src/workspace.h10
10 files changed, 221 insertions, 99 deletions
diff --git a/ChangeLog b/ChangeLog
index 970ae378..a50f1f1d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+2003-08-15 Ray Strode <halfline@hawaii.rr.com>
+
+ Changed MRU list to be per workspace instead of per display, so
+ sticky windows don't hijack the window focus after workspace
+ switching (Bug #97635).
+
+ * src/delete.c (meta_window_delete): Use
+ meta_workspace_focus_top_window instead of
+ meta_screen_focus_top_window.
+
+ * src/display.c (meta_display_open): Stop using display->mru_list.
+ (find_tab_forward):
+ (find_tab_backward):
+ (meta_display_get_tab_list): Use workspace->mru_list instead of
+ display->mru_list and remove unneeded calls to
+ meta_window_visible_on_workspace
+
+ * src/display.h: Remove mru_list from MetaDisplay
+
+ * src/keybindings.c (handle_toggle_desktop): Use
+ meta_workspace_focus_top_window instead of
+ meta_screen_focus_top_window.
+
+ * src/screen.c (meta_screen_focus_top_window):
+ (meta_screen_focus_default_window): Remove functions.
+ (meta_screen_show_desktop): Use meta_workspace_focus_top_window
+ instead of meta_screen_focus_top_window.
+
+ * src/screen.h: Remove meta_screen_focus_top_window and
+ meta_screen_focus_default_window declarations.
+
+ * src/window.c (meta_window_new): Stop using display->mru_list.
+ (meta_window_free): Use meta_workspace_focus_top_window
+ instead of meta_screen_focus_top_window and stop using
+ display->mru_list.
+ (meta_window_stick): Add sticky window to all workspace MRU lists.
+ (meta_window_unstick): Remove non-sticky window from the workspace
+ MRU lists it doesn't belong in.
+ (meta_window_notify_focus): Move newly focused window to the front
+ of active workspace's MRU list.
+
+ * src/workspace.c (meta_workspace_new): Initialize
+ workspace->mru_list to NULL.
+ (meta_workspace_add_window): Add window to workspace's MRU list.
+ (meta_workspace_remove_window): Remove window from workspace's MRU
+ list.
+ (meta_workspace_activate_with_focus): Use
+ meta_workspace_focus_default_window instead of
+ meta_screen_focus_default_window.
+ (meta_workspace_focus_default_window):
+ (meta_workspace_focus_mru_window):
+ (meta_workspace_focus_top_window): Add functions.
+
+ * src/workspace.h: Add mru_list to MetaWorkspace and add function
+ declarations for meta_workspace_focus_default_window,
+ meta_workspace_focus_mru_window, meta_workspace_focus_top_window.
+
2003-08-14 Rob Adams <robadams@ucla.edu>
Allow windows that are too tall for the workarea to break the
diff --git a/src/delete.c b/src/delete.c
index 5e95449b..061c892e 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -23,6 +23,7 @@
#include "util.h"
#include "window.h"
#include "errors.h"
+#include "workspace.h"
#include <sys/types.h>
#include <signal.h>
@@ -387,7 +388,8 @@ meta_window_delete (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS,
"Focusing top window because focus window %s was deleted/killed\n",
window->desc);
- meta_screen_focus_top_window (window->screen, window);
+ meta_workspace_focus_top_window (window->screen->active_workspace,
+ window);
}
else
{
diff --git a/src/display.c b/src/display.c
index 2856dbc7..d04e0b35 100644
--- a/src/display.c
+++ b/src/display.c
@@ -310,7 +310,6 @@ meta_display_open (const char *name)
display->autoraise_timeout_id = 0;
display->focus_window = NULL;
display->expected_focus_window = NULL;
- display->mru_list = NULL;
#ifdef HAVE_XSYNC
display->grab_update_alarm = None;
@@ -3417,6 +3416,7 @@ find_tab_forward (MetaDisplay *display,
GList *tmp;
g_return_val_if_fail (start != NULL, NULL);
+ g_return_val_if_fail (workspace != NULL, NULL);
tmp = start->next;
while (tmp != NULL)
@@ -3424,22 +3424,18 @@ find_tab_forward (MetaDisplay *display,
MetaWindow *window = tmp->data;
if (window->screen == screen &&
- IN_TAB_CHAIN (window, type) &&
- (workspace == NULL ||
- meta_window_visible_on_workspace (window, workspace)))
+ IN_TAB_CHAIN (window, type))
return window;
tmp = tmp->next;
}
- tmp = display->mru_list;
+ tmp = workspace->mru_list;
while (tmp != start)
{
MetaWindow *window = tmp->data;
- if (IN_TAB_CHAIN (window, type) &&
- (workspace == NULL ||
- meta_window_visible_on_workspace (window, workspace)))
+ if (IN_TAB_CHAIN (window, type))
return window;
tmp = tmp->next;
@@ -3458,6 +3454,7 @@ find_tab_backward (MetaDisplay *display,
GList *tmp;
g_return_val_if_fail (start != NULL, NULL);
+ g_return_val_if_fail (workspace != NULL, NULL);
tmp = start->prev;
while (tmp != NULL)
@@ -3465,22 +3462,18 @@ find_tab_backward (MetaDisplay *display,
MetaWindow *window = tmp->data;
if (window->screen == screen &&
- IN_TAB_CHAIN (window, type) &&
- (workspace == NULL ||
- meta_window_visible_on_workspace (window, workspace)))
+ IN_TAB_CHAIN (window, type))
return window;
tmp = tmp->prev;
}
- tmp = g_list_last (display->mru_list);
+ tmp = g_list_last (workspace->mru_list);
while (tmp != start)
{
MetaWindow *window = tmp->data;
- if (IN_TAB_CHAIN (window, type) &&
- (workspace == NULL ||
- meta_window_visible_on_workspace (window, workspace)))
+ if (IN_TAB_CHAIN (window, type))
return window;
tmp = tmp->prev;
@@ -3497,7 +3490,7 @@ meta_display_get_tab_list (MetaDisplay *display,
{
GList *tab_list;
- /* workspace can be NULL for all workspaces */
+ g_return_val_if_fail (workspace != NULL, NULL);
/* Windows sellout mode - MRU order. Collect unminimized windows
* then minimized so minimized windows aren't in the way so much.
@@ -3506,16 +3499,14 @@ meta_display_get_tab_list (MetaDisplay *display,
GList *tmp;
tab_list = NULL;
- tmp = screen->display->mru_list;
+ tmp = workspace->mru_list;
while (tmp != NULL)
{
MetaWindow *window = tmp->data;
if (!window->minimized &&
window->screen == screen &&
- IN_TAB_CHAIN (window, type) &&
- (workspace == NULL ||
- meta_window_visible_on_workspace (window, workspace)))
+ IN_TAB_CHAIN (window, type))
tab_list = g_list_prepend (tab_list, window);
tmp = tmp->next;
@@ -3525,16 +3516,14 @@ meta_display_get_tab_list (MetaDisplay *display,
{
GList *tmp;
- tmp = screen->display->mru_list;
+ tmp = workspace->mru_list;
while (tmp != NULL)
{
MetaWindow *window = tmp->data;
if (window->minimized &&
window->screen == screen &&
- IN_TAB_CHAIN (window, type) &&
- (workspace == NULL ||
- meta_window_visible_on_workspace (window, workspace)))
+ IN_TAB_CHAIN (window, type))
tab_list = g_list_prepend (tab_list, window);
tmp = tmp->next;
diff --git a/src/display.h b/src/display.h
index 4c880025..f96253d6 100644
--- a/src/display.h
+++ b/src/display.h
@@ -179,11 +179,6 @@ struct _MetaDisplay
*/
MetaWindow *expected_focus_window;
- /* Most recently focused list. Always contains all
- * live windows.
- */
- GList *mru_list;
-
guint static_gravity_works : 1;
/*< private-ish >*/
diff --git a/src/keybindings.c b/src/keybindings.c
index 0b2eb667..ab0a9140 100644
--- a/src/keybindings.c
+++ b/src/keybindings.c
@@ -2609,7 +2609,7 @@ handle_toggle_desktop (MetaDisplay *display,
if (screen->showing_desktop)
{
meta_screen_unshow_desktop (screen);
- meta_screen_focus_top_window (screen, NULL);
+ meta_workspace_focus_top_window (screen->active_workspace, NULL);
}
else
meta_screen_show_desktop (screen);
diff --git a/src/screen.c b/src/screen.c
index 7a287f17..348d467b 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1188,39 +1188,6 @@ meta_screen_ensure_workspace_popup (MetaScreen *screen)
/* don't show tab popup, since proper space isn't selected yet */
}
-/* Focus top window on active workspace */
-void
-meta_screen_focus_top_window (MetaScreen *screen,
- MetaWindow *not_this_one)
-{
- MetaWindow *window;
-
- if (not_this_one)
- meta_topic (META_DEBUG_FOCUS,
- "Focusing top window excluding %s\n", not_this_one->desc);
-
- window = meta_stack_get_default_focus_window (screen->stack,
- screen->active_workspace,
- not_this_one);
-
- /* FIXME I'm a loser on the CurrentTime front */
- if (window)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing top window %s\n", window->desc);
-
- meta_window_focus (window, meta_display_get_current_time (screen->display));
-
- /* Also raise the window if in click-to-focus */
- if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
- meta_window_raise (window);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS, "No top window to focus found\n");
- }
-}
-
void
meta_screen_focus_mouse_window (MetaScreen *screen,
MetaWindow *not_this_one)
@@ -1271,16 +1238,6 @@ meta_screen_focus_mouse_window (MetaScreen *screen,
}
}
-void
-meta_screen_focus_default_window (MetaScreen *screen,
- MetaWindow *not_this_one)
-{
- if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
- meta_screen_focus_top_window (screen, not_this_one);
- else
- meta_screen_focus_mouse_window (screen, not_this_one);
-}
-
const MetaXineramaScreenInfo*
meta_screen_get_xinerama_for_rect (MetaScreen *screen,
MetaRectangle *rect)
@@ -2199,7 +2156,7 @@ meta_screen_show_desktop (MetaScreen *screen)
update_showing_desktop_hint (screen);
- meta_screen_focus_top_window (screen, NULL);
+ meta_workspace_focus_top_window (screen->active_workspace, NULL);
}
void
diff --git a/src/screen.h b/src/screen.h
index 677f7faa..64fa4948 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -134,13 +134,8 @@ void meta_screen_ensure_tab_popup (MetaScreen *scree
void meta_screen_ensure_workspace_popup (MetaScreen *screen);
-void meta_screen_focus_top_window (MetaScreen *screen,
- MetaWindow *not_this_one);
void meta_screen_focus_mouse_window (MetaScreen *screen,
MetaWindow *not_this_one);
-void meta_screen_focus_default_window (MetaScreen *screen,
- MetaWindow *not_this_one);
-
const MetaXineramaScreenInfo* meta_screen_get_current_xinerama (MetaScreen *screen);
const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_rect (MetaScreen *screen,
diff --git a/src/window.c b/src/window.c
index b831c1cf..c18e59ea 100644
--- a/src/window.c
+++ b/src/window.c
@@ -657,10 +657,6 @@ meta_window_new (MetaDisplay *display,
window->size_hints.width,
window->size_hints.height);
- /* add to MRU list */
- window->display->mru_list =
- g_list_append (window->display->mru_list, window);
-
meta_stack_add (window->screen->stack,
window);
@@ -883,7 +879,7 @@ meta_window_free (MetaWindow *window)
meta_topic (META_DEBUG_FOCUS,
"Focusing top window since we're unmanaging %s\n",
window->desc);
- meta_screen_focus_top_window (window->screen, window);
+ meta_workspace_focus_top_window (window->screen->active_workspace, window);
}
else if (window->display->expected_focus_window == window)
{
@@ -891,7 +887,7 @@ meta_window_free (MetaWindow *window)
"Focusing top window since expected focus window freed %s\n",
window->desc);
window->display->expected_focus_window = NULL;
- meta_screen_focus_top_window (window->screen, window);
+ meta_workspace_focus_top_window (window->screen->active_workspace, window);
}
else
{
@@ -920,9 +916,6 @@ meta_window_free (MetaWindow *window)
if (window->display->focus_window == window)
window->display->focus_window = NULL;
- window->display->mru_list =
- g_list_remove (window->display->mru_list, window);
-
meta_window_unqueue_calc_showing (window);
meta_window_unqueue_move_resize (window);
meta_window_unqueue_update_icon (window);
@@ -1763,7 +1756,7 @@ meta_window_minimize (MetaWindow *window)
meta_topic (META_DEBUG_FOCUS,
"Focusing top window due to minimization of focus window %s\n",
window->desc);
- meta_screen_focus_top_window (window->screen, window);
+ meta_workspace_focus_top_window (window->screen->active_workspace, window);
}
else
{
@@ -3194,6 +3187,9 @@ meta_window_change_workspace (MetaWindow *window,
void
meta_window_stick (MetaWindow *window)
{
+ GList *tmp;
+ MetaWorkspace *workspace;
+
meta_verbose ("Sticking window %s current on_all_workspaces = %d\n",
window->desc, window->on_all_workspaces);
@@ -3206,6 +3202,18 @@ meta_window_stick (MetaWindow *window)
*/
window->on_all_workspaces = TRUE;
+ /* We do, however, change the MRU lists of all the workspaces
+ */
+ tmp = window->workspaces;
+ while (tmp)
+ {
+ workspace = (MetaWorkspace *) tmp->data;
+ if (!g_list_find (workspace->mru_list, window))
+ g_list_append (workspace->mru_list, window);
+
+ tmp = tmp->next;
+ }
+
meta_window_set_current_workspace_hint (window);
meta_window_queue_calc_showing (window);
@@ -3214,6 +3222,9 @@ meta_window_stick (MetaWindow *window)
void
meta_window_unstick (MetaWindow *window)
{
+ GList *tmp;
+ MetaWorkspace *workspace;
+
if (!window->on_all_workspaces)
return;
@@ -3221,6 +3232,16 @@ meta_window_unstick (MetaWindow *window)
window->on_all_workspaces = FALSE;
+ /* Remove window from MRU lists that it doesn't belong in */
+ tmp = window->workspaces;
+ while (tmp)
+ {
+ workspace = (MetaWorkspace *) tmp->data;
+ if (!meta_workspace_contains_window (workspace, window))
+ g_list_remove (workspace->mru_list, window);
+ tmp = tmp->next;
+ }
+
/* We change ourselves to the active workspace, since otherwise you'd get
* a weird window-vaporization effect. Once we have UI for being
* on more than one workspace this should probably be add_workspace
@@ -3946,11 +3967,21 @@ meta_window_notify_focus (MetaWindow *window,
"* Focus --> %s\n", window->desc);
window->display->focus_window = window;
window->has_focus = TRUE;
- /* Move to the front of the MRU list */
- window->display->mru_list =
- g_list_remove (window->display->mru_list, window);
- window->display->mru_list =
- g_list_prepend (window->display->mru_list, window);
+
+ /* Move to the front of the focusing workspace's MRU list
+ * FIXME: is the active workspace guaranteed to be the focusing
+ * workspace?
+ */
+ if (window->screen->active_workspace)
+ {
+ window->screen->active_workspace->mru_list =
+ g_list_remove (window->screen->active_workspace->mru_list,
+ window);
+ window->screen->active_workspace->mru_list =
+ g_list_prepend (window->screen->active_workspace->mru_list,
+ window);
+ }
+
if (window->frame)
meta_frame_queue_draw (window->frame);
diff --git a/src/workspace.c b/src/workspace.c
index 09dc25a5..dc73879f 100644
--- a/src/workspace.c
+++ b/src/workspace.c
@@ -41,6 +41,7 @@ meta_workspace_new (MetaScreen *screen)
workspace->screen->workspaces =
g_list_append (workspace->screen->workspaces, workspace);
workspace->windows = NULL;
+ workspace->mru_list = NULL;
workspace->work_areas = NULL;
workspace->work_areas_invalid = TRUE;
@@ -113,6 +114,8 @@ meta_workspace_add_window (MetaWorkspace *workspace,
workspace->windows = g_list_prepend (workspace->windows, window);
window->workspaces = g_list_prepend (window->workspaces, workspace);
+ workspace->mru_list = g_list_append (workspace->mru_list, window);
+
meta_window_set_current_workspace_hint (window);
meta_window_queue_calc_showing (window);
@@ -138,6 +141,7 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
workspace->windows = g_list_remove (workspace->windows, window);
window->workspaces = g_list_remove (window->workspaces, workspace);
+ workspace->mru_list = g_list_remove (workspace->mru_list, window);
meta_window_set_current_workspace_hint (window);
@@ -239,7 +243,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
else
{
meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
- meta_screen_focus_default_window (workspace->screen, NULL);
+ meta_workspace_focus_default_window (workspace, NULL);
}
}
@@ -687,3 +691,91 @@ meta_workspace_get_name (MetaWorkspace *workspace)
{
return meta_prefs_get_workspace_name (meta_workspace_index (workspace));
}
+
+void
+meta_workspace_focus_default_window (MetaWorkspace *workspace,
+ MetaWindow *not_this_one)
+{
+ if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+ meta_workspace_focus_mru_window (workspace, not_this_one);
+ else
+ meta_screen_focus_mouse_window (workspace->screen, not_this_one);
+}
+
+/* Focus MRU window (or top window if failed) on active workspace */
+void
+meta_workspace_focus_mru_window (MetaWorkspace *workspace,
+ MetaWindow *not_this_one)
+{
+ MetaWindow *window = NULL;
+ GList *tmp;
+
+ if (not_this_one)
+ meta_topic (META_DEBUG_FOCUS,
+ "Focusing MRU window excluding %s\n", not_this_one->desc);
+
+ tmp = workspace->mru_list;
+
+ while (tmp)
+ {
+ if (((MetaWindow*) tmp->data) != not_this_one)
+ {
+ window = tmp->data;
+ break;
+ }
+
+ tmp = tmp->next;
+ }
+
+ if (window)
+ {
+ meta_topic (META_DEBUG_FOCUS,
+ "Focusing workspace MRU window %s\n", window->desc);
+
+ meta_window_focus (window,
+ meta_display_get_current_time (workspace->screen->display));
+
+ /* Also raise the window if in click-to-focus */
+ if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+ meta_window_raise (window);
+ }
+ else
+ {
+ meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found\n");
+ meta_workspace_focus_top_window (workspace, not_this_one);
+ }
+}
+
+/* Focus top window on workspace */
+void
+meta_workspace_focus_top_window (MetaWorkspace *workspace,
+ MetaWindow *not_this_one)
+{
+ MetaWindow *window;
+
+ if (not_this_one)
+ meta_topic (META_DEBUG_FOCUS,
+ "Focusing top window excluding %s\n", not_this_one->desc);
+
+ window = meta_stack_get_default_focus_window (workspace->screen->stack,
+ workspace,
+ not_this_one);
+
+ /* FIXME I'm a loser on the CurrentTime front */
+ if (window)
+ {
+ meta_topic (META_DEBUG_FOCUS,
+ "Focusing top window %s\n", window->desc);
+
+ meta_window_focus (window,
+ meta_display_get_current_time (workspace->screen->display));
+
+ /* Also raise the window if in click-to-focus */
+ if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+ meta_window_raise (window);
+ }
+ else
+ {
+ meta_topic (META_DEBUG_FOCUS, "No top window to focus found\n");
+ }
+}
diff --git a/src/workspace.h b/src/workspace.h
index b89f5673..5a45c60c 100644
--- a/src/workspace.h
+++ b/src/workspace.h
@@ -40,6 +40,7 @@ struct _MetaWorkspace
MetaScreen *screen;
GList *windows;
+ GList *mru_list;
MetaRectangle all_work_areas;
MetaRectangle *work_areas;
@@ -76,9 +77,12 @@ void meta_workspace_get_work_area_for_xinerama (MetaWorkspace *workspace,
void meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
MetaRectangle *area);
-
-
-
+void meta_workspace_focus_mru_window (MetaWorkspace *workspace,
+ MetaWindow *not_this_one);
+void meta_workspace_focus_default_window (MetaWorkspace *workspace,
+ MetaWindow *not_this_one);
+void meta_workspace_focus_top_window (MetaWorkspace *workspace,
+ MetaWindow *not_this_one);
MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace *workspace,
MetaMotionDirection direction);