[mutter/meego-1.0: 9/30] Infrastructure allowing plugins to implement custom window constraints
- From: Tomas Frydrych <tomasf src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/meego-1.0: 9/30] Infrastructure allowing plugins to implement custom window constraints
- Date: Fri, 14 May 2010 15:50:31 +0000 (UTC)
commit 757f8ee8da0c85ca91aa76f86847d8b090eee885
Author: Tomas Frydrych <tf linux intel com>
Date: Mon Jan 18 09:20:29 2010 +0000
Infrastructure allowing plugins to implement custom window constraints
This commit adds a constrain_window() vfunction to the plugin class, and hooks
it onto the WM constraint mechanism.
The constraints.h file is split into a public and private parts; the definition
of the theme-specific version of MetaFrameGeometry struct was moved from its
location in theme.h to frames.h to avoid redefinition when autogenerating type
info for enums.
Plugin API version is bumped to 4
configure.in | 2 +-
src/Makefile.am | 5 +-
src/compositor/compositor.c | 22 +++
src/compositor/mutter-plugin-manager.c | 37 ++++-
src/compositor/mutter-plugin-manager.h | 9 +-
src/core/{constraints.h => constraints-private.h} | 10 +-
src/core/constraints.c | 207 +++++++++------------
src/core/frame-private.h | 11 -
src/core/window-private.h | 3 +
src/core/window.c | 22 +++
src/include/compositor.h | 7 +
src/include/constraints.h | 97 ++++++++++
src/include/frame.h | 9 +
src/include/mutter-plugin.h | 9 +-
src/include/types.h | 1 +
src/include/window.h | 2 +
src/ui/frames.h | 52 +++++
src/ui/theme.c | 1 +
src/ui/theme.h | 55 +------
19 files changed, 369 insertions(+), 192 deletions(-)
---
diff --git a/configure.in b/configure.in
index 632b7f7..c31d1b5 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,7 @@ m4_define([mutter_micro_version], [1])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
-m4_define([mutter_plugin_api_version], [3])
+m4_define([mutter_plugin_api_version], [4])
AC_INIT([mutter], [mutter_version],
[http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
diff --git a/src/Makefile.am b/src/Makefile.am
index ae17abc..73b3653 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,7 +43,8 @@ mutter_SOURCES= \
include/mutter-window.h \
include/compositor-mutter.h \
core/constraints.c \
- core/constraints.h \
+ core/constraints-private.h \
+ include/constraints.h \
core/core.c \
core/delete.c \
core/display.c \
@@ -168,6 +169,8 @@ libmutterinclude_base_headers = \
include/display.h \
include/group.h \
include/keybindings.h \
+ include/frame.h \
+ include/constraints.h \
include/mutter-plugin.h \
include/mutter-window.h \
include/mutter-shadow.h
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 7de1065..a346a80 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -1021,6 +1021,28 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor,
width, height);
}
+gboolean
+meta_compositor_constrain_window (MetaCompositor *compositor,
+ MetaWindow *window,
+ ConstraintInfo *constraint_info,
+ ConstraintPriority priority,
+ gboolean check_only)
+{
+ MetaScreen *screen = meta_window_get_screen (window);
+ MetaCompScreen *info = meta_screen_get_compositor_data (screen);
+ MutterPluginManager *mgr;
+
+ g_return_val_if_fail (info, FALSE);
+
+ mgr = info->plugin_mgr;
+
+ if (!mgr)
+ return FALSE;
+
+ return mutter_plugin_manager_constrain_window (mgr, window, constraint_info,
+ priority, check_only);
+}
+
static void
pre_paint_windows (MetaCompScreen *info)
{
diff --git a/src/compositor/mutter-plugin-manager.c b/src/compositor/mutter-plugin-manager.c
index c8d3d86..2f7c543 100644
--- a/src/compositor/mutter-plugin-manager.c
+++ b/src/compositor/mutter-plugin-manager.c
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (c) 2008 Intel Corp.
+ * Copyright (c) 2008, 2010 Intel Corp.
*
* Author: Tomas Frydrych <tf linux intel com>
*
@@ -677,3 +677,38 @@ mutter_plugin_manager_get_shadow (MutterPluginManager *mgr,
return NULL;
}
+
+/*
+ * This function needs to return TRUE by default (meaning 'constraint already
+ * satisfied').
+ */
+gboolean
+mutter_plugin_manager_constrain_window (MutterPluginManager *mgr,
+ MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only)
+{
+ GList *l;
+
+ if (!mgr)
+ return TRUE;
+
+ l = mgr->plugins;
+
+ while (l)
+ {
+ MutterPlugin *plugin = l->data;
+ MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
+
+ if (klass->constrain_window)
+ {
+ return klass->constrain_window (plugin, window, info, priority,
+ check_only);
+ }
+
+ l = l->next;
+ }
+
+ return TRUE;
+}
diff --git a/src/compositor/mutter-plugin-manager.h b/src/compositor/mutter-plugin-manager.h
index 690e61b..b6baadb 100644
--- a/src/compositor/mutter-plugin-manager.h
+++ b/src/compositor/mutter-plugin-manager.h
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (c) 2008 Intel Corp.
+ * Copyright (c) 2008, 2010 Intel Corp.
*
* Author: Tomas Frydrych <tf linux intel com>
*
@@ -63,4 +63,11 @@ gboolean mutter_plugin_manager_xevent_filter (MutterPluginManager *mgr,
MutterShadow * mutter_plugin_manager_get_shadow (MutterPluginManager *mgr,
MutterWindow *window);
+gboolean
+mutter_plugin_manager_constrain_window (MutterPluginManager *mgr,
+ MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only);
+
#endif
diff --git a/src/core/constraints.h b/src/core/constraints-private.h
similarity index 95%
rename from src/core/constraints.h
rename to src/core/constraints-private.h
index fa3f039..1b5ca3f 100644
--- a/src/core/constraints.h
+++ b/src/core/constraints-private.h
@@ -2,10 +2,10 @@
/* Mutter size/position constraints */
-/*
+/*
* Copyright (C) 2002 Red Hat, Inc.
* Copyright (C) 2005 Elijah Newren
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@@ -15,15 +15,15 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
-#ifndef META_CONSTRAINTS_H
-#define META_CONSTRAINTS_H
+#ifndef META_CONSTRAINTS_PRIVATE_H
+#define META_CONSTRAINTS_PRIVATE_H
#include "util.h"
#include "window-private.h"
diff --git a/src/core/constraints.c b/src/core/constraints.c
index 93c8864..88f302e 100644
--- a/src/core/constraints.c
+++ b/src/core/constraints.c
@@ -25,6 +25,7 @@
#include <config.h>
#include "constraints.h"
+#include "constraints-private.h"
#include "workspace-private.h"
#include "place.h"
#include "prefs.h"
@@ -43,7 +44,7 @@
// "constrain_whatever".
// 3) Add your function to the all_constraints and all_constraint_names
// arrays (the latter of which is for debugging purposes)
- //
+ //
// An example constraint function, constrain_whatever:
//
// /* constrain_whatever does the following:
@@ -90,56 +91,6 @@
// }
#endif
-typedef enum
-{
- PRIORITY_MINIMUM = 0, /* Dummy value used for loop start = min(all priorities) */
- PRIORITY_ASPECT_RATIO = 0,
- PRIORITY_ENTIRELY_VISIBLE_ON_SINGLE_MONITOR = 0,
- PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1,
- PRIORITY_SIZE_HINTS_INCREMENTS = 1,
- 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;
-
-typedef enum
-{
- ACTION_MOVE,
- ACTION_RESIZE,
- ACTION_MOVE_AND_RESIZE
-} ActionType;
-
-typedef struct
-{
- MetaRectangle orig;
- MetaRectangle current;
- MetaFrameGeometry *fgeom;
- ActionType action_type;
- gboolean is_user_action;
-
- /* I know that these two things probably look similar at first, but they
- * have much different uses. See doc/how-constraints-works.txt for for
- * explanation of the differences and similarity between resize_gravity
- * and fixed_directions
- */
- int resize_gravity;
- FixedDirections fixed_directions;
-
- /* work_area_monitor - current monitor region minus struts
- * entire_monitor - current monitor, including strut regions
- */
- MetaRectangle work_area_monitor;
- MetaRectangle entire_monitor;
-
- /* Spanning rectangles for the non-covered (by struts) region of the
- * screen and also for just the current monitor
- */
- GList *usable_screen_region;
- GList *usable_monitor_region;
-} ConstraintInfo;
static gboolean constrain_maximization (MetaWindow *window,
ConstraintInfo *info,
@@ -178,6 +129,11 @@ static gboolean constrain_partially_onscreen (MetaWindow *window,
ConstraintPriority priority,
gboolean check_only);
+static gboolean constrain_plugin (MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only);
+
static void setup_constraint_info (ConstraintInfo *info,
MetaWindow *window,
MetaFrameGeometry *orig_fgeom,
@@ -189,15 +145,6 @@ static void place_window_if_needed (MetaWindow *window,
ConstraintInfo *info);
static void update_onscreen_requirements (MetaWindow *window,
ConstraintInfo *info);
-static void extend_by_frame (MetaRectangle *rect,
- const MetaFrameGeometry *fgeom);
-static void unextend_by_frame (MetaRectangle *rect,
- const MetaFrameGeometry *fgeom);
-static inline void get_size_limits (const MetaWindow *window,
- const MetaFrameGeometry *fgeom,
- gboolean include_frame,
- MetaRectangle *min_size,
- MetaRectangle *max_size);
typedef gboolean (* ConstraintFunc) (MetaWindow *window,
ConstraintInfo *info,
@@ -219,6 +166,8 @@ static const Constraint all_constraints[] = {
{constrain_fully_onscreen, "constrain_fully_onscreen"},
{constrain_titlebar_visible, "constrain_titlebar_visible"},
{constrain_partially_onscreen, "constrain_partially_onscreen"},
+ {constrain_plugin, "constrain_plugin"},
+
{NULL, NULL}
};
@@ -243,7 +192,7 @@ do_all_constraints (MetaWindow *window,
/* Log how the constraint modified the position */
meta_topic (META_DEBUG_GEOMETRY,
"info->current is %d,%d +%d,%d after %s\n",
- info->current.x, info->current.y,
+ info->current.x, info->current.y,
info->current.width, info->current.height,
constraint->name);
}
@@ -285,8 +234,8 @@ meta_window_constrain (MetaWindow *window,
new->x, new->y, new->width, new->height);
setup_constraint_info (&info,
- window,
- orig_fgeom,
+ window,
+ orig_fgeom,
flags,
resize_gravity,
orig,
@@ -299,7 +248,7 @@ meta_window_constrain (MetaWindow *window,
/* Individually enforce all the high-enough priority constraints */
do_all_constraints (window, &info, priority, !check_only);
- /* Check if all high-enough priority constraints are simultaneously
+ /* Check if all high-enough priority constraints are simultaneously
* satisfied
*/
satisfied = do_all_constraints (window, &info, priority, check_only);
@@ -416,10 +365,10 @@ setup_constraint_info (ConstraintInfo *info,
}
cur_workspace = window->screen->active_workspace;
- info->usable_screen_region =
+ info->usable_screen_region =
meta_workspace_get_onscreen_region (cur_workspace);
- info->usable_monitor_region =
- meta_workspace_get_onmonitor_region (cur_workspace,
+ info->usable_monitor_region =
+ meta_workspace_get_onmonitor_region (cur_workspace,
monitor_info->number);
#if 0
@@ -455,7 +404,7 @@ setup_constraint_info (ConstraintInfo *info,
" work_area_monitor: %d,%d +%d,%d\n"
" entire_monitor : %d,%d +%d,%d\n",
info->orig.x, info->orig.y, info->orig.width, info->orig.height,
- info->current.x, info->current.y,
+ info->current.x, info->current.y,
info->current.width, info->current.height,
info->fgeom->left_width, info->fgeom->right_width,
info->fgeom->top_height, info->fgeom->bottom_height,
@@ -470,7 +419,7 @@ setup_constraint_info (ConstraintInfo *info,
(info->fixed_directions == FIXED_DIRECTION_Y) ? "Y fixed" :
"Freakin' Invalid Stupid",
info->work_area_monitor.x, info->work_area_monitor.y,
- info->work_area_monitor.width,
+ info->work_area_monitor.width,
info->work_area_monitor.height,
info->entire_monitor.x, info->entire_monitor.y,
info->entire_monitor.width, info->entire_monitor.height);
@@ -513,8 +462,8 @@ place_window_if_needed(MetaWindow *window,
monitor_info->number,
&info->work_area_monitor);
cur_workspace = window->screen->active_workspace;
- info->usable_monitor_region =
- meta_workspace_get_onmonitor_region (cur_workspace,
+ info->usable_monitor_region =
+ meta_workspace_get_onmonitor_region (cur_workspace,
monitor_info->number);
@@ -551,7 +500,7 @@ place_window_if_needed(MetaWindow *window,
if (window->maximize_horizontally_after_placement ||
window->maximize_vertically_after_placement)
- meta_window_maximize_internal (window,
+ meta_window_maximize_internal (window,
(window->maximize_horizontally_after_placement ?
META_MAXIMIZE_HORIZONTAL : 0 ) |
(window->maximize_vertically_after_placement ?
@@ -620,7 +569,7 @@ update_onscreen_requirements (MetaWindow *window,
/* The require onscreen/on-single-monitor and titlebar_visible
* stuff is relative to the outer window, not the inner
*/
- extend_by_frame (&info->current, info->fgeom);
+ meta_constraints_extend_by_frame (&info->current, info->fgeom);
/* Update whether we want future constraint runs to require the
* window to be on fully onscreen.
@@ -645,7 +594,7 @@ update_onscreen_requirements (MetaWindow *window,
if (old ^ window->require_on_single_monitor)
meta_topic (META_DEBUG_GEOMETRY,
"require_on_single_monitor for %s toggled to %s\n",
- window->desc,
+ window->desc,
window->require_on_single_monitor ? "TRUE" : "FALSE");
/* Update whether we want future constraint runs to require the
@@ -669,12 +618,12 @@ update_onscreen_requirements (MetaWindow *window,
}
/* Don't forget to restore the position of the window */
- unextend_by_frame (&info->current, info->fgeom);
+ meta_constraints_unextend_by_frame (&info->current, info->fgeom);
}
-static void
-extend_by_frame (MetaRectangle *rect,
- const MetaFrameGeometry *fgeom)
+void
+meta_constraints_extend_by_frame (MetaRectangle *rect,
+ const MetaFrameGeometry *fgeom)
{
rect->x -= fgeom->left_width;
rect->y -= fgeom->top_height;
@@ -682,9 +631,9 @@ extend_by_frame (MetaRectangle *rect,
rect->height += fgeom->top_height + fgeom->bottom_height;
}
-static void
-unextend_by_frame (MetaRectangle *rect,
- const MetaFrameGeometry *fgeom)
+void
+meta_constraints_unextend_by_frame (MetaRectangle *rect,
+ const MetaFrameGeometry *fgeom)
{
rect->x += fgeom->left_width;
rect->y += fgeom->top_height;
@@ -692,12 +641,12 @@ unextend_by_frame (MetaRectangle *rect,
rect->height -= fgeom->top_height + fgeom->bottom_height;
}
-static inline void
-get_size_limits (const MetaWindow *window,
- const MetaFrameGeometry *fgeom,
- gboolean include_frame,
- MetaRectangle *min_size,
- MetaRectangle *max_size)
+void
+meta_constraints_get_size_limits (const MetaWindow *window,
+ const MetaFrameGeometry *fgeom,
+ gboolean include_frame,
+ MetaRectangle *min_size,
+ MetaRectangle *max_size)
{
/* We pack the results into MetaRectangle structs just for convienience; we
* don't actually use the position of those rects.
@@ -769,19 +718,20 @@ constrain_maximization (MetaWindow *window,
active_workspace_struts = window->screen->active_workspace->all_struts;
target_size = info->current;
- extend_by_frame (&target_size, info->fgeom);
+ meta_constraints_extend_by_frame (&target_size, info->fgeom);
meta_rectangle_expand_to_avoiding_struts (&target_size,
&info->entire_monitor,
direction,
active_workspace_struts);
}
/* Now make target_size = maximized size of client window */
- unextend_by_frame (&target_size, info->fgeom);
+ meta_constraints_unextend_by_frame (&target_size, info->fgeom);
/* Check min size constraints; max size constraints are ignored for maximized
* windows, as per bug 327543.
*/
- get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
+ meta_constraints_get_size_limits (window, info->fgeom, FALSE,
+ &min_size, &max_size);
hminbad = target_size.width < min_size.width && window->maximized_horizontally;
vminbad = target_size.height < min_size.height && window->maximized_vertically;
if (hminbad || vminbad)
@@ -830,7 +780,8 @@ constrain_fullscreen (MetaWindow *window,
monitor = info->entire_monitor;
- get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
+ meta_constraints_get_size_limits (window, info->fgeom, FALSE,
+ &min_size, &max_size);
too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size);
too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor);
if (too_big || too_small)
@@ -862,7 +813,7 @@ constrain_size_increments (MetaWindow *window,
return TRUE;
/* Determine whether constraint applies; exit if it doesn't */
- if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
+ if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
info->action_type == ACTION_MOVE)
return TRUE;
@@ -879,7 +830,7 @@ constrain_size_increments (MetaWindow *window,
if (window->maximized_vertically)
extra_height *= 0;
/* constraint is satisfied iff there is no extra height or width */
- constraint_already_satisfied =
+ constraint_already_satisfied =
(extra_height == 0 && extra_width == 0);
if (check_only || constraint_already_satisfied)
@@ -905,10 +856,10 @@ constrain_size_increments (MetaWindow *window,
start_rect = &info->current;
else
start_rect = &info->orig;
-
+
/* Resize to the new size */
meta_rectangle_resize_with_gravity (start_rect,
- &info->current,
+ &info->current,
info->resize_gravity,
new_width,
new_height);
@@ -938,7 +889,8 @@ constrain_size_limits (MetaWindow *window,
return TRUE;
/* Determine whether constraint is already satisfied; exit if it is */
- get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
+ meta_constraints_get_size_limits (window, info->fgeom, FALSE,
+ &min_size, &max_size);
/* We ignore max-size limits for maximized windows; see #327543 */
if (window->maximized_horizontally)
max_size.width = MAX (max_size.width, info->current.width);
@@ -953,7 +905,7 @@ constrain_size_limits (MetaWindow *window,
/*** Enforce constraint ***/
new_width = CLAMP (info->current.width, min_size.width, max_size.width);
new_height = CLAMP (info->current.height, min_size.height, max_size.height);
-
+
/* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
* See bug 448183
*/
@@ -961,9 +913,9 @@ constrain_size_limits (MetaWindow *window,
start_rect = &info->current;
else
start_rect = &info->orig;
-
+
meta_rectangle_resize_with_gravity (start_rect,
- &info->current,
+ &info->current,
info->resize_gravity,
new_width,
new_height);
@@ -993,7 +945,7 @@ constrain_aspect_ratio (MetaWindow *window,
(double)window->size_hints.max_aspect.y;
constraints_are_inconsistent = minr > maxr;
if (constraints_are_inconsistent ||
- META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
+ META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
info->action_type == ACTION_MOVE)
return TRUE;
@@ -1032,7 +984,7 @@ constrain_aspect_ratio (MetaWindow *window,
fudge = 1;
break;
}
- constraint_already_satisfied =
+ constraint_already_satisfied =
info->current.width - (info->current.height * minr ) > -minr*fudge &&
info->current.width - (info->current.height * maxr ) < maxr*fudge;
if (check_only || constraint_already_satisfied)
@@ -1096,7 +1048,7 @@ constrain_aspect_ratio (MetaWindow *window,
start_rect = &info->orig;
meta_rectangle_resize_with_gravity (start_rect,
- &info->current,
+ &info->current,
info->resize_gravity,
new_width,
new_height);
@@ -1129,8 +1081,9 @@ do_screen_and_monitor_relative_constraints (
/* Determine whether constraint applies; exit if it doesn't */
how_far_it_can_be_smushed = info->current;
- get_size_limits (window, info->fgeom, TRUE, &min_size, &max_size);
- extend_by_frame (&info->current, info->fgeom);
+ meta_constraints_get_size_limits (window, info->fgeom, TRUE,
+ &min_size, &max_size);
+ meta_constraints_extend_by_frame (&info->current, info->fgeom);
if (info->action_type != ACTION_MOVE)
{
@@ -1145,12 +1098,12 @@ do_screen_and_monitor_relative_constraints (
exit_early = TRUE;
/* Determine whether constraint is already satisfied; exit if it is */
- constraint_satisfied =
+ constraint_satisfied =
meta_rectangle_contained_in_region (region_spanning_rectangles,
&info->current);
if (exit_early || constraint_satisfied || check_only)
{
- unextend_by_frame (&info->current, info->fgeom);
+ meta_constraints_unextend_by_frame (&info->current, info->fgeom);
return constraint_satisfied;
}
@@ -1174,7 +1127,7 @@ do_screen_and_monitor_relative_constraints (
info->fixed_directions,
&info->current);
- unextend_by_frame (&info->current, info->fgeom);
+ meta_constraints_unextend_by_frame (&info->current, info->fgeom);
return TRUE;
}
@@ -1188,7 +1141,7 @@ constrain_to_single_monitor (MetaWindow *window,
return TRUE;
/* 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
+ * is only meant for normal windows (e.g. we don't want docks to be shoved
* "onscreen" by their own strut) and we can't apply it to frameless windows
* or else users will be unable to move windows such as XMMS across monitors.
*/
@@ -1201,7 +1154,7 @@ constrain_to_single_monitor (MetaWindow *window,
return TRUE;
/* Have a helper function handle the constraint for us */
- return do_screen_and_monitor_relative_constraints (window,
+ return do_screen_and_monitor_relative_constraints (window,
info->usable_monitor_region,
info,
check_only);
@@ -1217,18 +1170,18 @@ constrain_fully_onscreen (MetaWindow *window,
return TRUE;
/* 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
+ * 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->fullscreen ||
- !window->require_fully_onscreen ||
+ !window->require_fully_onscreen ||
info->is_user_action)
return TRUE;
/* Have a helper function handle the constraint for us */
- return do_screen_and_monitor_relative_constraints (window,
+ return do_screen_and_monitor_relative_constraints (window,
info->usable_screen_region,
info,
check_only);
@@ -1256,7 +1209,7 @@ constrain_titlebar_visible (MetaWindow *window,
info->is_user_action && !window->display->grab_frame_action;
/* 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
+ * 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 ||
@@ -1298,13 +1251,13 @@ constrain_titlebar_visible (MetaWindow *window,
*/
meta_rectangle_expand_region_conditionally (info->usable_screen_region,
horiz_amount_offscreen,
- horiz_amount_offscreen,
+ horiz_amount_offscreen,
0, /* Don't let titlebar off */
bottom_amount,
horiz_amount_onscreen,
vert_amount_onscreen);
retval =
- do_screen_and_monitor_relative_constraints (window,
+ do_screen_and_monitor_relative_constraints (window,
info->usable_screen_region,
info,
check_only);
@@ -1334,7 +1287,7 @@ constrain_partially_onscreen (MetaWindow *window,
return TRUE;
/* 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
+ * 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 ||
@@ -1373,13 +1326,13 @@ constrain_partially_onscreen (MetaWindow *window,
*/
meta_rectangle_expand_region_conditionally (info->usable_screen_region,
horiz_amount_offscreen,
- horiz_amount_offscreen,
+ horiz_amount_offscreen,
top_amount,
bottom_amount,
horiz_amount_onscreen,
vert_amount_onscreen);
retval =
- do_screen_and_monitor_relative_constraints (window,
+ do_screen_and_monitor_relative_constraints (window,
info->usable_screen_region,
info,
check_only);
@@ -1393,3 +1346,21 @@ constrain_partially_onscreen (MetaWindow *window,
return retval;
}
+
+static gboolean
+constrain_plugin (MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only)
+{
+ MetaDisplay *display = window->screen->display;
+
+ if (!display->compositor)
+ return FALSE;
+
+ return meta_compositor_constrain_window (display->compositor,
+ window,
+ info,
+ priority,
+ check_only);
+}
diff --git a/src/core/frame-private.h b/src/core/frame-private.h
index 89c3d42..b5687f3 100644
--- a/src/core/frame-private.h
+++ b/src/core/frame-private.h
@@ -27,17 +27,6 @@
#include "frame.h"
#include "window-private.h"
-typedef struct _MetaFrameGeometry MetaFrameGeometry;
-
-struct _MetaFrameGeometry
-{
- /* border sizes (space between frame and child) */
- int left_width;
- int right_width;
- int top_height;
- int bottom_height;
-};
-
struct _MetaFrame
{
/* window we frame */
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 77759ec..a048491 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -136,6 +136,9 @@ struct _MetaWindow
/* Whether we have to fullscreen after placement */
guint fullscreen_after_placement : 1;
+ /* Set if the user moved/resized the window */
+ guint user_placed : 1;
+
/* Area to cover when in fullscreen mode. If _NET_WM_FULLSCREEN_MONITORS has
* been overridden (via a client message), the window will cover the union of
* these monitors. If not, this is the single monitor which the window's
diff --git a/src/core/window.c b/src/core/window.c
index 3327d9f..145b467 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -42,6 +42,7 @@
#include "group.h"
#include "window-props.h"
#include "constraints.h"
+#include "constraints-private.h"
#include "mutter-enum-types.h"
#include <X11/Xatom.h>
@@ -3850,6 +3851,9 @@ meta_window_move_resize_internal (MetaWindow *window,
/* The action has to be a move or a resize or both... */
g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION));
+ if (is_user_action)
+ window->user_placed = TRUE;
+
/* We don't need it in the idle queue anymore. */
meta_window_unqueue (window, META_QUEUE_MOVE_RESIZE);
@@ -9117,3 +9121,21 @@ meta_window_is_modal (MetaWindow *window)
return window->wm_state_modal;
}
+
+/**
+ * meta_window_is_user_placed:
+ * @window: a #MetaWindow
+ *
+ * Queries whether the size and position of the window was assigned by the
+ * window manager, or is due to user action.
+ *
+ * Return value: (transfer none): TRUE if the window was positioned or resized
+ * by the user.
+ */
+gboolean
+meta_window_is_user_placed (MetaWindow *window)
+{
+ g_return_val_if_fail (META_IS_WINDOW (window), FALSE);
+
+ return window->user_placed;
+}
diff --git a/src/include/compositor.h b/src/include/compositor.h
index 843ff55..5e5aa46 100644
--- a/src/include/compositor.h
+++ b/src/include/compositor.h
@@ -29,6 +29,7 @@
#include "boxes.h"
#include "window.h"
#include "workspace.h"
+#include "constraints.h"
typedef enum _MetaCompWindowType
{
@@ -183,4 +184,10 @@ void meta_compositor_sync_screen_size (MetaCompositor *compositor,
guint width,
guint height);
+gboolean meta_compositor_constrain_window (MetaCompositor *compositor,
+ MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only);
+
#endif /* META_COMPOSITOR_H */
diff --git a/src/include/constraints.h b/src/include/constraints.h
new file mode 100644
index 0000000..06c97dc
--- /dev/null
+++ b/src/include/constraints.h
@@ -0,0 +1,97 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/* Mutter size/position constraints */
+
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (C) 2005 Elijah Newren
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_CONSTRAINTS_H
+#define META_CONSTRAINTS_H
+
+#include "boxes.h"
+#include "frame.h"
+
+typedef enum
+{
+ PRIORITY_MINIMUM = 0, /* Dummy value used for loop start = min(all priorities) */
+ PRIORITY_ASPECT_RATIO = 0,
+ PRIORITY_ENTIRELY_VISIBLE_ON_SINGLE_MONITOR = 0,
+ PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1,
+ PRIORITY_SIZE_HINTS_INCREMENTS = 1,
+ PRIORITY_MAXIMIZATION = 2,
+ PRIORITY_FULLSCREEN = 2,
+ PRIORITY_SIZE_HINTS_LIMITS = 3,
+ PRIORITY_TITLEBAR_VISIBLE = 4,
+ PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA = 4,
+ PRIORITY_MAXIMUM = 5 /* Value used for loop end = max(all priorities)
+ * Compositor plugins can use this value to override
+ * all other constraints
+ */
+} ConstraintPriority;
+
+typedef enum
+{
+ ACTION_MOVE,
+ ACTION_RESIZE,
+ ACTION_MOVE_AND_RESIZE
+} ConstraintActionType;
+
+typedef struct
+{
+ MetaRectangle orig;
+ MetaRectangle current;
+ MetaFrameGeometry *fgeom;
+ ConstraintActionType action_type;
+ gboolean is_user_action;
+
+ /* I know that these two things probably look similar at first, but they
+ * have much different uses. See doc/how-constraints-works.txt for for
+ * explanation of the differences and similarity between resize_gravity
+ * and fixed_directions
+ */
+ int resize_gravity;
+ FixedDirections fixed_directions;
+
+ /* work_area_monitor - current monitor region minus struts
+ * entire_monitor - current monitor, including strut regions
+ */
+ MetaRectangle work_area_monitor;
+ MetaRectangle entire_monitor;
+
+ /* Spanning rectangles for the non-covered (by struts) region of the
+ * screen and also for just the current monitor
+ */
+ GList *usable_screen_region;
+ GList *usable_monitor_region;
+} ConstraintInfo;
+
+void meta_constraints_unextend_by_frame (MetaRectangle *rect,
+ const MetaFrameGeometry *fgeom);
+
+void meta_constraints_extend_by_frame (MetaRectangle *rect,
+ const MetaFrameGeometry *fgeom);
+
+void meta_constraints_get_size_limits (const MetaWindow *window,
+ const MetaFrameGeometry *fgeom,
+ gboolean include_frame,
+ MetaRectangle *min_size,
+ MetaRectangle *max_size);
+
+#endif
diff --git a/src/include/frame.h b/src/include/frame.h
index eeb5726..5db4d8f 100644
--- a/src/include/frame.h
+++ b/src/include/frame.h
@@ -26,6 +26,15 @@
#include "types.h"
+struct _MetaFrameGeometry
+{
+ /* border sizes (space between frame and child) */
+ int left_width;
+ int right_width;
+ int top_height;
+ int bottom_height;
+};
+
Window meta_frame_get_xwindow (MetaFrame *frame);
#endif
diff --git a/src/include/mutter-plugin.h b/src/include/mutter-plugin.h
index cab678c..8778c5c 100644
--- a/src/include/mutter-plugin.h
+++ b/src/include/mutter-plugin.h
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (c) 2008 Intel Corp.
+ * Copyright (c) 2008, 2010 Intel Corp.
*
* Author: Tomas Frydrych <tf linux intel com>
*
@@ -25,6 +25,7 @@
#define MUTTER_PLUGIN_H_
#include "types.h"
+#include "constraints.h"
#include "compositor.h"
#include "compositor-mutter.h"
#include "mutter-shadow.h"
@@ -119,6 +120,12 @@ struct _MutterPluginClass
MutterShadow * (*get_shadow) (MutterPlugin *plugin,
MutterWindow *window);
+
+ gboolean (*constrain_window) (MutterPlugin *plugin,
+ MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only);
};
struct _MutterPluginInfo
diff --git a/src/include/types.h b/src/include/types.h
index 3fc60c9..96ff612 100644
--- a/src/include/types.h
+++ b/src/include/types.h
@@ -25,6 +25,7 @@
typedef struct _MetaCompositor MetaCompositor;
typedef struct _MetaDisplay MetaDisplay;
typedef struct _MetaFrame MetaFrame;
+typedef struct _MetaFrameGeometry MetaFrameGeometry;
typedef struct _MetaScreen MetaScreen;
typedef struct _MetaWindow MetaWindow;
typedef struct _MetaWorkspace MetaWorkspace;
diff --git a/src/include/window.h b/src/include/window.h
index d14e76e..bf20454 100644
--- a/src/include/window.h
+++ b/src/include/window.h
@@ -125,4 +125,6 @@ guint32 meta_window_get_user_time (MetaWindow *window);
int meta_window_get_pid (MetaWindow *window);
const char *meta_window_get_client_machine (MetaWindow *window);
gboolean meta_window_is_modal (MetaWindow *window);
+gboolean meta_window_is_user_placed (MetaWindow *window);
+
#endif
diff --git a/src/ui/frames.h b/src/ui/frames.h
index ad8d361..ed341aa 100644
--- a/src/ui/frames.h
+++ b/src/ui/frames.h
@@ -55,6 +55,58 @@ typedef enum
META_FRAME_CONTROL_CLIENT_AREA
} MetaFrameControl;
+/**
+ * Calculated actual geometry of the frame
+ */
+struct _MetaFrameGeometry
+{
+ int left_width;
+ int right_width;
+ int top_height;
+ int bottom_height;
+
+ int width;
+ int height;
+
+ GdkRectangle title_rect;
+
+ int left_titlebar_edge;
+ int right_titlebar_edge;
+ int top_titlebar_edge;
+ int bottom_titlebar_edge;
+
+ /* used for a memset hack */
+#define ADDRESS_OF_BUTTON_RECTS(fgeom) (((char*)(fgeom)) + G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
+#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, right_right_background) + sizeof (GdkRectangle) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
+
+ /* The button rects (if changed adjust memset hack) */
+ MetaButtonSpace close_rect;
+ MetaButtonSpace max_rect;
+ MetaButtonSpace min_rect;
+ MetaButtonSpace menu_rect;
+ MetaButtonSpace shade_rect;
+ MetaButtonSpace above_rect;
+ MetaButtonSpace stick_rect;
+ MetaButtonSpace unshade_rect;
+ MetaButtonSpace unabove_rect;
+ MetaButtonSpace unstick_rect;
+
+#define MAX_MIDDLE_BACKGROUNDS (MAX_BUTTONS_PER_CORNER - 2)
+ GdkRectangle left_left_background;
+ GdkRectangle left_middle_backgrounds[MAX_MIDDLE_BACKGROUNDS];
+ GdkRectangle left_right_background;
+ GdkRectangle right_left_background;
+ GdkRectangle right_middle_backgrounds[MAX_MIDDLE_BACKGROUNDS];
+ GdkRectangle right_right_background;
+ /* End of button rects (if changed adjust memset hack) */
+
+ /* Round corners */
+ guint top_left_corner_rounded_radius;
+ guint top_right_corner_rounded_radius;
+ guint bottom_left_corner_rounded_radius;
+ guint bottom_right_corner_rounded_radius;
+};
+
/* This is one widget that manages all the window frames
* as subwindows.
*/
diff --git a/src/ui/theme.c b/src/ui/theme.c
index ae640d9..902a9b5 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -57,6 +57,7 @@
#include "theme-parser.h"
#include "util.h"
#include "gradient.h"
+#include "frames.h"
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>
diff --git a/src/ui/theme.h b/src/ui/theme.h
index ddf777d..6b3ea1d 100644
--- a/src/ui/theme.h
+++ b/src/ui/theme.h
@@ -27,6 +27,8 @@
#include "boxes.h"
#include "gradient.h"
#include "common.h"
+#include "types.h"
+
#include <gtk/gtk.h>
typedef struct _MetaFrameStyle MetaFrameStyle;
@@ -38,7 +40,6 @@ typedef struct _MetaAlphaGradientSpec MetaAlphaGradientSpec;
typedef struct _MetaColorSpec MetaColorSpec;
typedef struct _MetaFrameLayout MetaFrameLayout;
typedef struct _MetaButtonSpace MetaButtonSpace;
-typedef struct _MetaFrameGeometry MetaFrameGeometry;
typedef struct _MetaTheme MetaTheme;
typedef struct _MetaPositionExprEnv MetaPositionExprEnv;
typedef struct _MetaDrawInfo MetaDrawInfo;
@@ -163,58 +164,6 @@ struct _MetaButtonSpace
GdkRectangle clickable;
};
-/**
- * Calculated actual geometry of the frame
- */
-struct _MetaFrameGeometry
-{
- int left_width;
- int right_width;
- int top_height;
- int bottom_height;
-
- int width;
- int height;
-
- GdkRectangle title_rect;
-
- int left_titlebar_edge;
- int right_titlebar_edge;
- int top_titlebar_edge;
- int bottom_titlebar_edge;
-
- /* used for a memset hack */
-#define ADDRESS_OF_BUTTON_RECTS(fgeom) (((char*)(fgeom)) + G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
-#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, right_right_background) + sizeof (GdkRectangle) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
-
- /* The button rects (if changed adjust memset hack) */
- MetaButtonSpace close_rect;
- MetaButtonSpace max_rect;
- MetaButtonSpace min_rect;
- MetaButtonSpace menu_rect;
- MetaButtonSpace shade_rect;
- MetaButtonSpace above_rect;
- MetaButtonSpace stick_rect;
- MetaButtonSpace unshade_rect;
- MetaButtonSpace unabove_rect;
- MetaButtonSpace unstick_rect;
-
-#define MAX_MIDDLE_BACKGROUNDS (MAX_BUTTONS_PER_CORNER - 2)
- GdkRectangle left_left_background;
- GdkRectangle left_middle_backgrounds[MAX_MIDDLE_BACKGROUNDS];
- GdkRectangle left_right_background;
- GdkRectangle right_left_background;
- GdkRectangle right_middle_backgrounds[MAX_MIDDLE_BACKGROUNDS];
- GdkRectangle right_right_background;
- /* End of button rects (if changed adjust memset hack) */
-
- /* Round corners */
- guint top_left_corner_rounded_radius;
- guint top_right_corner_rounded_radius;
- guint bottom_left_corner_rounded_radius;
- guint bottom_right_corner_rounded_radius;
-};
-
typedef enum
{
META_IMAGE_FILL_SCALE, /* default, needs to be all-bits-zero for g_new0 */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]