summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElijah Newren <newren gmail com>2006-08-07 23:34:55 +0000
committerElijah Newren <newren@src.gnome.org>2006-08-07 23:34:55 +0000
commit57bedc42a4ecf8351312ee1f72f2f1d56fc0f05d (patch)
tree5d0f0d31b48835e2fde0157e6d179282df13ed7b
parentacc6c97997ca08b1d311b7da2dcb69aa133f63be (diff)
downloadmutter-57bedc42a4ecf8351312ee1f72f2f1d56fc0f05d.tar.gz
Add a constrain_titlebar_visible constraint; should fix both bug 333328
2006-08-07 Elijah Newren <newren gmail com> Add a constrain_titlebar_visible constraint; should fix both bug 333328 and bug 345522. Not perfect (minor annoying snap pulling windows back onscreen, plus an ugly hack almost as bad as the old one), but tarballs are due in less than half an hour. ;-) * src/boxes.[ch] (meta_rectangle_overlaps_with_region): new function * src/constraints.c (constrain_titlebar_visible): new function, (enum ConstraintPriority, array all_constraints, update_onscreen_requirements): various small changes to accomodate the new function * src/edge-resistance.c: remove the infinite edge resistance, which was a big hack of a way to workaround the lack of a titlebar_visible constraint * src/window.[ch] (MetaWindow): new require_titlebar_visible bitfield, (meta_window_new_with_attrs): initialized here
-rw-r--r--ChangeLog22
-rw-r--r--src/boxes.c19
-rw-r--r--src/boxes.h3
-rw-r--r--src/constraints.c143
-rw-r--r--src/edge-resistance.c19
-rw-r--r--src/window.c1
-rw-r--r--src/window.h3
7 files changed, 176 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 9c6968e12..f56d98e32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
2006-08-07 Elijah Newren <newren gmail com>
+ Add a constrain_titlebar_visible constraint; should fix both bug
+ 333328 and bug 345522. Not perfect (minor annoying snap pulling
+ windows back onscreen, plus an ugly hack almost as bad as the old
+ one), but tarballs are due in less than half an hour. ;-)
+
+ * src/boxes.[ch] (meta_rectangle_overlaps_with_region):
+ new function
+
+ * src/constraints.c (constrain_titlebar_visible): new function,
+ (enum ConstraintPriority, array all_constraints,
+ update_onscreen_requirements): various small changes to
+ accomodate the new function
+
+ * src/edge-resistance.c: remove the infinite edge resistance,
+ which was a big hack of a way to workaround the lack of a
+ titlebar_visible constraint
+
+ * src/window.[ch] (MetaWindow): new require_titlebar_visible
+ bitfield, (meta_window_new_with_attrs): initialized here
+
+2006-08-07 Elijah Newren <newren gmail com>
+
* src/frames.c (meta_frames_button_press_event): Patch from Chris
Ball to not minimize in response to double clicks on the titlebar
when minimiziation should not be allowed. #347377
diff --git a/src/boxes.c b/src/boxes.c
index fe99ff6b3..d01d2851c 100644
--- a/src/boxes.c
+++ b/src/boxes.c
@@ -705,6 +705,25 @@ meta_rectangle_contained_in_region (const GList *spanning_rects,
return contained;
}
+gboolean
+meta_rectangle_overlaps_with_region (const GList *spanning_rects,
+ const MetaRectangle *rect)
+{
+ const GList *temp;
+ gboolean overlaps;
+
+ temp = spanning_rects;
+ overlaps = FALSE;
+ while (!overlaps && temp != NULL)
+ {
+ overlaps = overlaps || meta_rectangle_overlap (temp->data, rect);
+ temp = temp->next;
+ }
+
+ return overlaps;
+}
+
+
void
meta_rectangle_clamp_to_fit_into_region (const GList *spanning_rects,
FixedDirections fixed_directions,
diff --git a/src/boxes.h b/src/boxes.h
index 4f5f26670..52c366982 100644
--- a/src/boxes.h
+++ b/src/boxes.h
@@ -183,6 +183,9 @@ gboolean meta_rectangle_could_fit_in_region (
gboolean meta_rectangle_contained_in_region (
const GList *spanning_rects,
const MetaRectangle *rect);
+gboolean meta_rectangle_overlaps_with_region (
+ const GList *spanning_rects,
+ const MetaRectangle *rect);
/* Make the rectangle small enough to fit into one of the spanning_rects,
* but make it no smaller than min_size.
diff --git a/src/constraints.c b/src/constraints.c
index 06d65bc83..8eb2d83d8 100644
--- a/src/constraints.c
+++ b/src/constraints.c
@@ -97,6 +97,7 @@ typedef enum
PRIORITY_MAXIMIZATION = 2,
PRIORITY_FULLSCREEN = 2,
PRIORITY_SIZE_HINTS_LIMITS = 3,
+ PRIORITY_TITLEBAR_VISIBLE = 4,
PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA = 4,
PRIORITY_MAXIMUM = 4 // Dummy value used for loop end = max(all priorities)
} ConstraintPriority;
@@ -165,6 +166,10 @@ static gboolean constrain_fully_onscreen (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
gboolean check_only);
+static gboolean constrain_titlebar_visible (MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only);
static gboolean constrain_partially_onscreen (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
@@ -209,6 +214,7 @@ static const Constraint all_constraints[] = {
{constrain_aspect_ratio, "constrain_aspect_ratio"},
{constrain_to_single_xinerama, "constrain_to_single_xinerama"},
{constrain_fully_onscreen, "constrain_fully_onscreen"},
+ {constrain_titlebar_visible, "constrain_titlebar_visible"},
{constrain_partially_onscreen, "constrain_partially_onscreen"},
{NULL, NULL}
};
@@ -536,23 +542,23 @@ update_onscreen_requirements (MetaWindow *window,
window->type == META_WINDOW_DOCK)
return;
- /* USABILITY NOTE: Naturally, I only want the require_fully_onscreen and
- * require_on_single_xinerama flags to *become false* due to user
- * interactions (which is allowed since certain constraints are ignored
- * for user interactions regardless of the setting of these flags).
- * However, whether to make these flags *become true* due to just an
- * application interaction is a little trickier. It's possible that
- * users may find not doing that strange since two application
- * interactions that resize in opposite ways don't necessarily end up
- * cancelling--but it may also be strange for the user to have an
- * application resize the window so that it's onscreen, the user forgets
- * about it, and then later the app is able to resize itself off the
- * screen. Anyway, for now, I'm think the latter is the more problematic
- * case but this may need to be revisited.
+ /* USABILITY NOTE: Naturally, I only want the require_fully_onscreen,
+ * require_on_single_xinerama, and require_titlebar_visible flags to
+ * *become false* due to user interactions (which is allowed since
+ * certain constraints are ignored for user interactions regardless of
+ * the setting of these flags). However, whether to make these flags
+ * *become true* due to just an application interaction is a little
+ * trickier. It's possible that users may find not doing that strange
+ * since two application interactions that resize in opposite ways don't
+ * necessarily end up cancelling--but it may also be strange for the user
+ * to have an application resize the window so that it's onscreen, the
+ * user forgets about it, and then later the app is able to resize itself
+ * off the screen. Anyway, for now, I think the latter is the more
+ * problematic case but this may need to be revisited.
*/
- /* The require onscreen/on-single-xinerama stuff is relative to the
- * outer window, not the inner
+ /* The require onscreen/on-single-xinerama and titlebar_visible
+ * stuff is relative to the outer window, not the inner
*/
extend_by_frame (&info->current, info->fgeom);
@@ -582,6 +588,26 @@ update_onscreen_requirements (MetaWindow *window,
window->desc,
window->require_on_single_xinerama ? "TRUE" : "FALSE");
+ /* Update whether we want future constraint runs to require the
+ * titlebar to be visible.
+ */
+ if (window->frame && window->decorated)
+ {
+ MetaRectangle titlebar_rect;
+
+ titlebar_rect = info->current;
+ titlebar_rect.height = info->fgeom->top_height;
+ old = window->require_titlebar_visible;
+ window->require_titlebar_visible =
+ meta_rectangle_overlaps_with_region (info->usable_screen_region,
+ &titlebar_rect);
+ if (old ^ window->require_titlebar_visible)
+ meta_topic (META_DEBUG_GEOMETRY,
+ "require_titlebar_visible for %s toggled to %s\n",
+ window->desc,
+ window->require_titlebar_visible ? "TRUE" : "FALSE");
+ }
+
/* Don't forget to restore the position of the window */
unextend_by_frame (&info->current, info->fgeom);
}
@@ -1054,6 +1080,93 @@ constrain_fully_onscreen (MetaWindow *window,
}
static gboolean
+constrain_titlebar_visible (MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only)
+{
+ gboolean unconstrained_user_action;
+ gboolean retval;
+ int bottom_amount;
+ int horiz_amount_offscreen, vert_amount_offscreen;
+ int horiz_amount_onscreen, vert_amount_onscreen;
+
+ if (priority > PRIORITY_TITLEBAR_VISIBLE)
+ return TRUE;
+
+ /* Allow the titlebar beyond the top of the screen only if the user wasn't
+ * clicking on the titlebar to start the move.
+ * FIXME: This is kind of a hack; nearly as ugly as the old infinite edge
+ * resistance.
+ */
+ unconstrained_user_action =
+ info->is_user_action &&
+ window->display->grab_anchor_root_y >= window->display->grab_initial_window_pos.y;
+
+ /* Exit early if we know the constraint won't apply--note that this constraint
+ * is only meant for normal windows (e.g. we don't want docks to be shoved
+ * "onscreen" by their own strut).
+ */
+ if (window->type == META_WINDOW_DESKTOP ||
+ window->type == META_WINDOW_DOCK ||
+ !window->require_titlebar_visible ||
+ !window->decorated ||
+ unconstrained_user_action)
+ return TRUE;
+
+ /* Determine how much offscreen things are allowed. We first need to
+ * figure out how much must remain on the screen. For that, we use 25%
+ * window width/height but clamp to the range of (10,75) pixels. This is
+ * somewhat of a seat of my pants random guess at what might look good.
+ * Then, the amount that is allowed off is just the window size minus
+ * this amount (but no less than 0 for tiny windows).
+ */
+ horiz_amount_onscreen = info->current.width / 4;
+ vert_amount_onscreen = info->current.height / 4;
+ horiz_amount_onscreen = CLAMP (horiz_amount_onscreen, 10, 75);
+ vert_amount_onscreen = CLAMP (vert_amount_onscreen, 10, 75);
+ horiz_amount_offscreen = info->current.width - horiz_amount_onscreen;
+ vert_amount_offscreen = info->current.height - vert_amount_onscreen;
+ horiz_amount_offscreen = MAX (horiz_amount_offscreen, 0);
+ vert_amount_offscreen = MAX (vert_amount_offscreen, 0);
+ /* Allow the titlebar to touch the bottom panel; If there is no titlebar,
+ * require vert_amount to remain on the screen.
+ */
+ if (window->frame)
+ {
+ bottom_amount = info->current.height + info->fgeom->bottom_height;
+ vert_amount_onscreen = info->fgeom->top_height;
+ }
+ else
+ bottom_amount = vert_amount_offscreen;
+
+ /* Extend the region, have a helper function handle the constraint,
+ * then return the region to its original size.
+ */
+ meta_rectangle_expand_region_conditionally (info->usable_screen_region,
+ horiz_amount_offscreen,
+ horiz_amount_offscreen,
+ 0, /* Don't let titlebar off */
+ bottom_amount,
+ horiz_amount_onscreen,
+ vert_amount_onscreen);
+ retval =
+ do_screen_and_xinerama_relative_constraints (window,
+ info->usable_screen_region,
+ info,
+ check_only);
+ meta_rectangle_expand_region_conditionally (info->usable_screen_region,
+ -horiz_amount_offscreen,
+ -horiz_amount_offscreen,
+ 0, /* Don't let titlebar off */
+ -bottom_amount,
+ horiz_amount_onscreen,
+ vert_amount_onscreen);
+
+ return retval;
+}
+
+static gboolean
constrain_partially_onscreen (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
diff --git a/src/edge-resistance.c b/src/edge-resistance.c
index 189b9e365..a00612332 100644
--- a/src/edge-resistance.c
+++ b/src/edge-resistance.c
@@ -44,7 +44,6 @@ struct ResistanceDataForAnEdge
GSourceFunc timeout_func;
MetaWindow *window;
int keyboard_buildup;
- gboolean allow_past_screen_edge;
};
typedef struct ResistanceDataForAnEdge ResistanceDataForAnEdge;
@@ -397,18 +396,6 @@ apply_edge_resistance (MetaWindow *window,
{
int threshold;
- /* INFINITE RESISTANCE for screen edges under certain cases; If
- * the edge is relevant and we're moving towards it and it's a
- * screen edge and infinite resistance has been requested for
- * this particular grab op then don't allow movement past it.
- */
- if (edge->edge_type == META_EDGE_SCREEN &&
- !resistance_data->allow_past_screen_edge &&
- movement_towards_edge (edge->side_type, increment))
- {
- return compare;
- }
-
/* TIMEOUT RESISTANCE: If the edge is relevant and we're moving
* towards it, then we may want to have some kind of time delay
* before the user can move past this edge.
@@ -913,12 +900,6 @@ initialize_grab_edge_resistance_data (MetaDisplay *display)
edge_data->right_data.keyboard_buildup = 0;
edge_data->top_data.keyboard_buildup = 0;
edge_data->bottom_data.keyboard_buildup = 0;
-
- edge_data->left_data.allow_past_screen_edge = TRUE;
- edge_data->right_data.allow_past_screen_edge = TRUE;
- edge_data->bottom_data.allow_past_screen_edge = TRUE;
- edge_data->top_data.allow_past_screen_edge =
- display->grab_anchor_root_y >= display->grab_initial_window_pos.y;
}
void
diff --git a/src/window.c b/src/window.c
index 72821bd7e..408d84d2f 100644
--- a/src/window.c
+++ b/src/window.c
@@ -448,6 +448,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->fullscreen = FALSE;
window->require_fully_onscreen = TRUE;
window->require_on_single_xinerama = TRUE;
+ window->require_titlebar_visible = TRUE;
window->on_all_workspaces = FALSE;
window->shaded = FALSE;
window->initially_iconic = FALSE;
diff --git a/src/window.h b/src/window.h
index 5a6af5851..4695945c3 100644
--- a/src/window.h
+++ b/src/window.h
@@ -138,6 +138,9 @@ struct _MetaWindow
/* Whether we're trying to constrain the window to be on a single xinerama */
guint require_on_single_xinerama : 1;
+ /* Whether we're trying to constrain the window's titlebar to be onscreen */
+ guint require_titlebar_visible : 1;
+
/* Whether we're sticky in the multi-workspace sense
* (vs. the not-scroll-with-viewport sense, we don't
* have no stupid viewports)