[mutter] window: Introduce meta_window_get_tile_match()
- From: Rui Matos <rtcm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] window: Introduce meta_window_get_tile_match()
- Date: Fri, 16 Mar 2012 18:15:00 +0000 (UTC)
commit 2926323a9a0defc2f9f845d80a5ec6b00a23d78e
Author: Rui Matos <tiagomatos gmail com>
Date: Fri Feb 24 17:08:55 2012 +0100
window: Introduce meta_window_get_tile_match()
Returns the matching tiled window. This is the topmost tiled window in a
complementary tile mode that is:
- on the same monitor;
- on the same workspace;
- spanning the remaining monitor width;
- there is no 3rd window stacked between both tiled windows that's
partially visible in the common edge.
https://bugzilla.gnome.org/show_bug.cgi?id=643075
src/core/stack.c | 29 +++++++++++++
src/core/stack.h | 2 +
src/core/window-private.h | 5 ++
src/core/window.c | 101 +++++++++++++++++++++++++++++++++++++++++++++
src/meta/window.h | 2 +
5 files changed, 139 insertions(+), 0 deletions(-)
---
diff --git a/src/core/stack.c b/src/core/stack.c
index c3917c6..de1c9e0 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -121,6 +121,7 @@ meta_stack_add (MetaStack *stack,
window->desc, window->stack_position);
stack_sync_to_server (stack);
+ meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
void
@@ -156,6 +157,7 @@ meta_stack_remove (MetaStack *stack,
GUINT_TO_POINTER (window->frame->xwindow));
stack_sync_to_server (stack);
+ meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
void
@@ -165,6 +167,7 @@ meta_stack_update_layer (MetaStack *stack,
stack->need_relayer = TRUE;
stack_sync_to_server (stack);
+ meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
void
@@ -174,6 +177,7 @@ meta_stack_update_transient (MetaStack *stack,
stack->need_constrain = TRUE;
stack_sync_to_server (stack);
+ meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
/* raise/lower within a layer */
@@ -185,6 +189,7 @@ meta_stack_raise (MetaStack *stack,
stack->n_positions - 1);
stack_sync_to_server (stack);
+ meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
void
@@ -194,6 +199,7 @@ meta_stack_lower (MetaStack *stack,
meta_window_set_stack_position_no_sync (window, 0);
stack_sync_to_server (stack);
+ meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
}
void
@@ -209,6 +215,26 @@ meta_stack_thaw (MetaStack *stack)
stack->freeze_count -= 1;
stack_sync_to_server (stack);
+ meta_stack_update_window_tile_matches (stack, NULL);
+}
+
+void
+meta_stack_update_window_tile_matches (MetaStack *stack,
+ MetaWorkspace *workspace)
+{
+ GList *windows;
+
+ if (stack->freeze_count > 0)
+ return;
+
+ windows = meta_stack_list_windows (stack, workspace);
+ while (windows)
+ {
+ meta_window_compute_tile_match ((MetaWindow *) windows->data);
+ windows = windows->next;
+ }
+
+ g_list_free (windows);
}
static gboolean
@@ -1656,6 +1682,7 @@ meta_stack_set_positions (MetaStack *stack,
"Reset the stack positions of (nearly) all windows\n");
stack_sync_to_server (stack);
+ meta_stack_update_window_tile_matches (stack, NULL);
}
void
@@ -1718,4 +1745,6 @@ meta_window_set_stack_position (MetaWindow *window,
{
meta_window_set_stack_position_no_sync (window, position);
stack_sync_to_server (window->screen->stack);
+ meta_stack_update_window_tile_matches (window->screen->stack,
+ window->screen->active_workspace);
}
diff --git a/src/core/stack.h b/src/core/stack.h
index e8b6310..4102cc6 100644
--- a/src/core/stack.h
+++ b/src/core/stack.h
@@ -383,4 +383,6 @@ GList* meta_stack_get_positions (MetaStack *stack);
void meta_stack_set_positions (MetaStack *stack,
GList *windows);
+void meta_stack_update_window_tile_matches (MetaStack *stack,
+ MetaWorkspace *workspace);
#endif
diff --git a/src/core/window-private.h b/src/core/window-private.h
index b425aed..d89924c 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -410,6 +410,9 @@ struct _MetaWindow
/* Focused window that is (directly or indirectly) attached to this one */
MetaWindow *attached_focus_window;
+
+ /* The currently complementary tiled window, if any */
+ MetaWindow *tile_match;
};
struct _MetaWindowClass
@@ -663,4 +666,6 @@ void meta_window_propagate_focus_appearance (MetaWindow *window,
gboolean meta_window_should_attach_to_parent (MetaWindow *window);
gboolean meta_window_can_tile_side_by_side (MetaWindow *window);
+void meta_window_compute_tile_match (MetaWindow *window);
+
#endif
diff --git a/src/core/window.c b/src/core/window.c
index 8c54839..ff09914 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -1167,6 +1167,8 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->monitor = meta_screen_get_monitor_for_window (window->screen, window);
+ window->tile_match = NULL;
+
if (window->override_redirect)
{
window->decorated = FALSE;
@@ -5022,6 +5024,9 @@ meta_window_move_resize_internal (MetaWindow *window,
}
meta_window_foreach_transient (window, maybe_move_attached_dialog, NULL);
+
+ meta_stack_update_window_tile_matches (window->screen->stack,
+ window->screen->active_workspace);
}
/**
@@ -10712,3 +10717,99 @@ meta_window_is_attached_dialog (MetaWindow *window)
{
return window->attached;
}
+
+/**
+ * meta_window_get_tile_match:
+ *
+ * Returns the matching tiled window on the same monitor as @window. This is
+ * the topmost tiled window in a complementary tile mode that is:
+ *
+ * - on the same monitor;
+ * - on the same workspace;
+ * - spanning the remaining monitor width;
+ * - there is no 3rd window stacked between both tiled windows that's
+ * partially visible in the common edge.
+ *
+ * Return value: (transfer none) (allow-none): the matching tiled window or
+ * %NULL if it doesn't exist.
+ */
+MetaWindow *
+meta_window_get_tile_match (MetaWindow *window)
+{
+ return window->tile_match;
+}
+
+void
+meta_window_compute_tile_match (MetaWindow *window)
+{
+ MetaWindow *match;
+ MetaTileMode match_tile_mode;
+ MetaStack *stack;
+
+ window->tile_match = NULL;
+
+ if (window->shaded ||
+ window->minimized ||
+ !META_WINDOW_TILED_SIDE_BY_SIDE (window))
+ return;
+
+ if (META_WINDOW_TILED_LEFT (window))
+ match_tile_mode = META_TILE_RIGHT;
+ else if (META_WINDOW_TILED_RIGHT (window))
+ match_tile_mode = META_TILE_LEFT;
+
+ stack = window->screen->stack;
+
+ for (match = meta_stack_get_top (stack);
+ match;
+ match = meta_stack_get_below (stack, match, FALSE))
+ {
+ if (!match->shaded &&
+ !match->minimized &&
+ match->tile_mode == match_tile_mode &&
+ match->monitor == window->monitor &&
+ meta_window_get_workspace (match) == meta_window_get_workspace (window))
+ break;
+ }
+
+ if (match)
+ {
+ MetaWindow *above, *bottommost, *topmost;
+ MetaRectangle above_rect, bottommost_rect, topmost_rect;
+
+ if (meta_stack_windows_cmp (window->screen->stack, match, window) > 0)
+ {
+ topmost = match;
+ bottommost = window;
+ }
+ else
+ {
+ topmost = window;
+ bottommost = match;
+ }
+
+ meta_window_get_outer_rect (bottommost, &bottommost_rect);
+ meta_window_get_outer_rect (topmost, &topmost_rect);
+ /*
+ * If there's a window stacked in between which is partially visible
+ * behind the topmost tile we don't consider the tiles to match.
+ */
+ for (above = meta_stack_get_above (stack, bottommost, FALSE);
+ above && above != topmost;
+ above = meta_stack_get_above (stack, above, FALSE))
+ {
+ if (above->minimized ||
+ above->monitor != window->monitor ||
+ meta_window_get_workspace (above) != meta_window_get_workspace (window))
+ continue;
+
+ meta_window_get_outer_rect (above, &above_rect);
+
+ if (meta_rectangle_overlap (&above_rect, &bottommost_rect) &&
+ meta_rectangle_overlap (&above_rect, &topmost_rect))
+ return;
+ }
+
+ window->tile_match = match;
+ }
+}
diff --git a/src/meta/window.h b/src/meta/window.h
index 765ef28..5e09b59 100644
--- a/src/meta/window.h
+++ b/src/meta/window.h
@@ -169,4 +169,6 @@ MetaFrameType meta_window_get_frame_type (MetaWindow *window);
cairo_region_t *meta_window_get_frame_bounds (MetaWindow *window);
+MetaWindow *meta_window_get_tile_match (MetaWindow *window);
+
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]