summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Thurman <thomas@thurman.org.uk>2006-03-29 18:43:22 +0000
committerThomas James Alexander Thurman <tthurman@src.gnome.org>2006-03-29 18:43:22 +0000
commitcf3deef6eacb24c7d59add7e73001467a9e5777d (patch)
tree04dab84e98b78390ae2c39a976985086c6b83592
parent28aeacb247d065a50923a28e2fc3abd1ef718f8b (diff)
downloadmetacity-cf3deef6eacb24c7d59add7e73001467a9e5777d.tar.gz
mark a window as needing or not needing the user's attention use the new
2006-03-29 Thomas Thurman <thomas@thurman.org.uk> * src/window.c, src/window.h (meta_window_set_demands_attention, meta_window_unset_demands_attention): mark a window as needing or not needing the user's attention * src/window.c (meta_window_show, window_activate, meta_window_focus, meta_window_configure_request, meta_window_client_message): use the new set/unset demands attention functions. Fixes #305822.
-rw-r--r--ChangeLog9
-rw-r--r--src/window.c97
-rw-r--r--src/window.h3
3 files changed, 94 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index beac33f7..1fb53f8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2006-03-29 Thomas Thurman <thomas@thurman.org.uk>
+ * src/window.c, src/window.h (meta_window_set_demands_attention,
+ meta_window_unset_demands_attention): mark a window as needing
+ or not needing the user's attention
+ * src/window.c (meta_window_show, window_activate,
+ meta_window_focus, meta_window_configure_request,
+ meta_window_client_message): use the new set/unset
+ demands attention functions. Fixes #305822.
+
2006-03-29 Björn Lindqvist <bjourne@gmail.com>
* src/resizepopup.c:
diff --git a/src/window.c b/src/window.c
index 7438338d..4f384de9 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2006,6 +2006,11 @@ meta_window_show (MetaWindow *window)
/* If the window will be obscured by the focus window, then the
* user might not notice the window appearing so set the
* demands attention hint.
+ *
+ * We set the hint ourselves rather than calling
+ * meta_window_set_demands_attention() because that would cause
+ * a recalculation of overlap, and a call to set_net_wm_state()
+ * which we are going to call ourselves here a few lines down.
*/
if (overlap)
window->wm_state_demands_attention = TRUE;
@@ -2484,8 +2489,7 @@ window_activate (MetaWindow *window,
"last_user_time (%lu) is more recent; ignoring "
" _NET_ACTIVE_WINDOW message.\n",
window->display->last_user_time);
- window->wm_state_demands_attention = TRUE;
- set_net_wm_state (window);
+ meta_window_set_demands_attention(window);
return;
}
@@ -3758,10 +3762,7 @@ meta_window_focus (MetaWindow *window,
}
if (window->wm_state_demands_attention)
- {
- window->wm_state_demands_attention = FALSE;
- set_net_wm_state (window);
- }
+ meta_window_unset_demands_attention(window);
}
static void
@@ -4281,10 +4282,7 @@ meta_window_configure_request (MetaWindow *window,
active_window->desc,
active_window->net_wm_user_time);
if (event->xconfigurerequest.detail == Above)
- {
- window->wm_state_demands_attention = TRUE;
- set_net_wm_state (window);
- }
+ meta_window_set_demands_attention(window);
}
else
{
@@ -4530,11 +4528,11 @@ meta_window_client_message (MetaWindow *window,
if (first == display->atom_net_wm_state_demands_attention ||
second == display->atom_net_wm_state_demands_attention)
{
- window->wm_state_demands_attention =
- (action == _NET_WM_STATE_ADD) ||
- (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention);
-
- set_net_wm_state (window);
+ if ((action == _NET_WM_STATE_ADD) ||
+ (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention))
+ meta_window_set_demands_attention(window);
+ else
+ meta_window_unset_demands_attention(window);
}
return TRUE;
@@ -7656,3 +7654,72 @@ meta_window_set_user_time (MetaWindow *window,
window->display->allow_terminal_deactivation = FALSE;
}
}
+
+/* Sets the demands_attention hint on a window, but only
+ * if it's at least partially obscured (see #305882).
+ */
+void
+meta_window_set_demands_attention (MetaWindow *window)
+{
+ MetaRectangle candidate_rect, other_rect;
+ GList *stack = window->screen->stack->sorted;
+ MetaWindow *other_window;
+ gboolean obscured = FALSE;
+
+ /* Does the window have any other window on this workspace
+ * overlapping it?
+ */
+
+ meta_window_get_outer_rect (window, &candidate_rect);
+
+ /* The stack is sorted with the top windows first. */
+
+ while (stack != NULL && stack->data != window)
+ {
+ other_window = stack->data;
+ stack = stack->next;
+
+ if (other_window->on_all_workspaces ||
+ window->on_all_workspaces ||
+ other_window->workspace == window->workspace)
+ {
+ meta_window_get_outer_rect (other_window, &other_rect);
+
+ if (meta_rectangle_overlap (&candidate_rect, &other_rect))
+ {
+ obscured = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* If the window's in full view, there's no point setting the flag. */
+
+ if (!obscured)
+ {
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Not marking %s as needing attention because it's in full view\n",
+ window->desc);
+ return;
+ }
+
+ /* Otherwise, go ahead and set the flag. */
+
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Marking %s as needing attention\n", window->desc);
+
+ window->wm_state_demands_attention = TRUE;
+ set_net_wm_state (window);
+}
+
+void
+meta_window_unset_demands_attention (MetaWindow *window)
+{
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Marking %s as not needing attention\n", window->desc);
+
+ window->wm_state_demands_attention = FALSE;
+ set_net_wm_state (window);
+}
+
+
diff --git a/src/window.h b/src/window.h
index 3562cbc2..7b9a9eb8 100644
--- a/src/window.h
+++ b/src/window.h
@@ -582,4 +582,7 @@ void meta_window_stack_just_below (MetaWindow *window,
void meta_window_set_user_time (MetaWindow *window,
Time timestamp);
+void meta_window_set_demands_attention (MetaWindow *window);
+
+void meta_window_unset_demands_attention (MetaWindow *window);
#endif