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.
This commit is contained in:
Ray Strode 2003-08-15 22:09:55 +00:00 committed by Ray Strode
parent 60a453f5a0
commit 2fc880db19
10 changed files with 221 additions and 99 deletions

View File

@ -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

View File

@ -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
{

View File

@ -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;

View File

@ -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 >*/

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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");
}
}

View File

@ -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);