summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Thurman <thomas@thurman.org.uk>2007-10-16 22:29:59 +0000
committerThomas James Alexander Thurman <tthurman@src.gnome.org>2007-10-16 22:29:59 +0000
commit4ef11cfbd38d3772dc05aa5a0804372d6fc33dec (patch)
treef66b7157582763b9fd02c4310d96847a6e7ee4ab
parent8a023b00f28dd38c502ebaf36384baede76b9cf4 (diff)
downloadmetacity-4ef11cfbd38d3772dc05aa5a0804372d6fc33dec.tar.gz
new function. rewrite assertion not to put window on top in terms of
2007-10-16 Thomas Thurman <thomas@thurman.org.uk> * src/window.c (window_would_be_covered): new function. * src/window.c (meta_window_show): rewrite assertion not to put window on top in terms of window_would_be_covered(); remove assertion because it's no longer valid; explicitly don't focus windows that shouldn't be focussed; closes #486445. svn path=/trunk/; revision=3358
-rw-r--r--ChangeLog8
-rw-r--r--src/window.c78
2 files changed, 72 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 5550d3e9..9b4b1c9f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-10-16 Thomas Thurman <thomas@thurman.org.uk>
+
+ * src/window.c (window_would_be_covered): new function.
+ * src/window.c (meta_window_show): rewrite assertion not
+ to put window on top in terms of window_would_be_covered();
+ remove assertion because it's no longer valid; explicitly
+ don't focus windows that shouldn't be focussed; closes #486445.
+
2007-10-14 Thomas Thurman <thomas@thurman.org.uk>
* configure.in: Post-branch bump to 2.21.1.
diff --git a/src/window.c b/src/window.c
index fac38259..a8ceda62 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1954,6 +1954,47 @@ windows_overlap (const MetaWindow *w1, const MetaWindow *w2)
return meta_rectangle_overlap (&w1rect, &w2rect);
}
+/* Returns whether a new window would be covered by any
+ * existing window on the same workspace that is set
+ * to be "above" ("always on top"). A window that is not
+ * set "above" would be underneath the new window anyway.
+ *
+ * We take "covered" to mean even partially covered, but
+ * some people might prefer entirely covered. I think it
+ * is more useful to behave this way if any part of the
+ * window is covered, because a partial coverage could be
+ * (say) ninety per cent and almost indistinguishable from total.
+ */
+static gboolean
+window_would_be_covered (const MetaWindow *newbie)
+{
+ MetaWorkspace *workspace = newbie->workspace;
+ GList *tmp, *windows;
+
+ windows = meta_workspace_list_windows (workspace);
+
+ tmp = windows;
+ while (tmp != NULL)
+ {
+ MetaWindow *w = tmp->data;
+
+ if (w->wm_state_above)
+ {
+ /* We have found a window that is "above". Perhaps it overlaps. */
+ if (windows_overlap (w, newbie))
+ {
+ g_list_free (windows); /* clean up... */
+ return TRUE; /* yes, it does */
+ }
+ }
+
+ tmp = tmp->next;
+ }
+
+ g_list_free (windows);
+ return FALSE; /* none found */
+}
+
/* XXX META_EFFECT_*_MAP */
void
meta_window_show (MetaWindow *window)
@@ -1986,11 +2027,24 @@ meta_window_show (MetaWindow *window)
takes_focus_on_map ? "does" : "does not",
place_on_top_on_map ? "does" : "does not");
- if ( !takes_focus_on_map &&
- focus_window != NULL &&
- !place_on_top_on_map &&
- window->showing_for_first_time )
- {
+ /* Now, in some rare cases we should *not* put a new window on top.
+ * These cases include certain types of windows showing for the firat
+ * time, and any window which would be covered because of another window
+ * being set "above" ("always on top").
+ *
+ * FIXME: Although "place_on_top_on_map" and "takes_focus_on_map" are
+ * generally based on the window type, there is a special case when the
+ * focus window is a terminal for them both to be false; this should
+ * probably rather be a term in the "if" condition below.
+ */
+
+ if ( focus_window != NULL &&
+ (
+ (window->showing_for_first_time &&
+ !place_on_top_on_map &&
+ !takes_focus_on_map) ||
+ window_would_be_covered (window))
+ ) {
if (meta_window_is_ancestor_of_transient (focus_window, window))
{
/* This happens for error dialogs or alerts; these need to remain on
@@ -2045,22 +2099,18 @@ meta_window_show (MetaWindow *window)
{
gboolean overlap;
- /* needs_stacking_adjustment is only set under certain
- * circumstances currently; if those circumstances change, this
- * code may need re-thinking too
- */
- g_assert(window->showing_for_first_time &&
- !place_on_top_on_map &&
- !takes_focus_on_map &&
- focus_window != NULL);
-
/* This window isn't getting focus on map. We may need to do some
* special handing with it in regards to
* - the stacking of the window
* - the MRU position of the window
* - the demands attention setting of the window
+ *
+ * Firstly, set the flag so we don't give the window focus anyway
+ * and confuse people.
*/
+ takes_focus_on_map = FALSE;
+
overlap = windows_overlap (window, focus_window);
/* We want alt tab to go to the denied-focus window */