summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog21
-rw-r--r--libwnck/screen.c31
-rw-r--r--libwnck/screen.h1
-rw-r--r--libwnck/tasklist.c9
-rw-r--r--libwnck/window.c32
-rw-r--r--libwnck/window.h1
6 files changed, 93 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 564482c..ce639fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2004-08-15 Elijah Newren <newren@math.utah.edu>
+
+ Fix window activation vs. minimization for mouse focus. (fixes
+ #136581)
+
+ * libwnck/screen.c (struct _WnckScreenPrivate): add a
+ previously_active_window field,
+ (wnck_screen_get_previously_active_window): new function,
+ (update_client_list): update the previously_active_window as well,
+ (update_active_window): also updates the previously_active_window
+ now.
+
+ * libwnck/screen.h Added wnck_screen_get_previously_active_window
+
+ * libwnck/tasklist.c (wnck_task_button_press_event): minimize when
+ the tasklist button is pressed if the window is the most recently
+ activated (instead of if the window is currently active).
+
+ * libwnck/window.[ch] (wnck_window_is_most_recently_activated):
+ new function
+
2004-08-09 Mark McLoughlin <mark@skynet.ie>
* libwnck/wnck-enum-types.[ch],
diff --git a/libwnck/screen.c b/libwnck/screen.c
index 34797ab..2091ed5 100644
--- a/libwnck/screen.c
+++ b/libwnck/screen.c
@@ -47,8 +47,12 @@ struct _WnckScreenPrivate
GList *stacked_windows;
/* in 0-to-N order */
GList *workspaces;
-
+
+ /* previously_active_window is used in tandem with active_window to
+ * determine return status of meta_window_is_most_recently_actived().
+ */
WnckWindow *active_window;
+ WnckWindow *previously_active_window;
WnckWorkspace *active_workspace;
Pixmap bg_pixmap;
@@ -551,6 +555,24 @@ wnck_screen_get_active_window (WnckScreen *screen)
}
/**
+ * wnck_screen_get_previously_active_window:
+ * @screen: a #WnckScreen
+ *
+ * Gets the previously active window. May return %NULL
+ * sometimes, since not all window managers guarantee
+ * that a window is always active.
+ *
+ * Return value: previously active window or %NULL
+ **/
+WnckWindow*
+wnck_screen_get_previously_active_window (WnckScreen *screen)
+{
+ g_return_val_if_fail (WNCK_IS_SCREEN (screen), NULL);
+
+ return screen->priv->previously_active_window;
+}
+
+/**
* wnck_screen_get_windows:
* @screen: a #WnckScreen
*
@@ -1038,9 +1060,15 @@ update_client_list (WnckScreen *screen)
if (window == screen->priv->active_window)
{
+ screen->priv->previously_active_window = screen->priv->active_window;
screen->priv->active_window = NULL;
active_changed = TRUE;
}
+
+ if (window == screen->priv->previously_active_window)
+ {
+ screen->priv->previously_active_window = NULL;
+ }
emit_window_closed (screen, window);
}
@@ -1363,6 +1391,7 @@ update_active_window (WnckScreen *screen)
if (window == screen->priv->active_window)
return;
+ screen->priv->previously_active_window = screen->priv->active_window;
screen->priv->active_window = window;
emit_active_window_changed (screen);
diff --git a/libwnck/screen.h b/libwnck/screen.h
index a11a3d8..11b6c56 100644
--- a/libwnck/screen.h
+++ b/libwnck/screen.h
@@ -119,6 +119,7 @@ WnckWorkspace* wnck_screen_get_workspace (WnckScreen *screen,
int workspace);
WnckWorkspace* wnck_screen_get_active_workspace (WnckScreen *screen);
WnckWindow* wnck_screen_get_active_window (WnckScreen *screen);
+WnckWindow* wnck_screen_get_previously_active_window (WnckScreen *screen);
GList* wnck_screen_get_windows (WnckScreen *screen);
GList* wnck_screen_get_windows_stacked (WnckScreen *screen);
void wnck_screen_force_update (WnckScreen *screen);
diff --git a/libwnck/tasklist.c b/libwnck/tasklist.c
index 9c96834..c6d17b1 100644
--- a/libwnck/tasklist.c
+++ b/libwnck/tasklist.c
@@ -2345,7 +2345,14 @@ wnck_task_button_press_event (GtkWidget *widget,
case WNCK_TASK_WINDOW:
if (event->button == 1)
{
- if (wnck_window_is_active (task->window))
+ /* is_most_recently_activated == is_active for click &
+ * sloppy focus methods. We use the former here because
+ * 'mouse' focus provides a special case. In that case, no
+ * window will be active, but if a window was the most
+ * recently active one (i.e. user moves mouse straight from
+ * window to tasklist), then we should still minimize it.
+ */
+ if (wnck_window_is_most_recently_activated (task->window))
task->was_active = TRUE;
else
task->was_active = FALSE;
diff --git a/libwnck/window.c b/libwnck/window.c
index 2b7fa73..629c659 100644
--- a/libwnck/window.c
+++ b/libwnck/window.c
@@ -1049,6 +1049,38 @@ wnck_window_is_active (WnckWindow *window)
return window == wnck_screen_get_active_window (window->priv->screen);
}
+/**
+ * wnck_window_is_most_recently_activated:
+ * @window: a #WnckWindow
+ *
+ * Determines whether @window is the most recently activated window.
+ * The most recently activated window is identical to the active
+ * window for click and sloppy focus methods (since a window is always
+ * active in those cases) but differs slightly for mouse focus since
+ * we often have no window active.
+ *
+ * Return value: %TRUE if window was the most recently activated window
+ **/
+gboolean
+wnck_window_is_most_recently_activated (WnckWindow *window)
+{
+ g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+
+ WnckWindow * current;
+ WnckWindow * previous;
+ WnckWindow * most_recently_activated_window;
+
+ current = wnck_screen_get_active_window (window->priv->screen);
+ previous = wnck_screen_get_previously_active_window (window->priv->screen);
+
+ if (current)
+ most_recently_activated_window = current;
+ else
+ most_recently_activated_window = previous;
+
+ return (window == most_recently_activated_window);
+}
+
static WnckWindow*
find_last_transient_for (GList *windows,
diff --git a/libwnck/window.h b/libwnck/window.h
index de4c5a6..6bbddaf 100644
--- a/libwnck/window.h
+++ b/libwnck/window.h
@@ -189,6 +189,7 @@ void wnck_window_unpin (WnckWindow *window);
void wnck_window_activate (WnckWindow *window);
gboolean wnck_window_is_active (WnckWindow *window);
+gboolean wnck_window_is_most_recently_activated (WnckWindow *window);
void wnck_window_activate_transient (WnckWindow *window);