mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
Update constraints code to support the new _NET_WM_STRUT_PARTIAL EWMH
2003-06-10 Rob Adams <robadams@ucla.edu> Update constraints code to support the new _NET_WM_STRUT_PARTIAL EWMH draft specification. See #86682. Also, fix a bug involving work area invalidation on metacity startup. Fix for #108497. Finally, some minor fixes for full screen windows. * src/window.h: Add new MetaStruts structure to store strut rects for a window. Remove has_struts and do_not_cover flag, and support new MetaStruts instead of the four ints. * src/window.c (meta_window_new): change initialization to work with new struts. Also, move meta_window_update_struts call to after the workspaces are initialized to fix #108497. Remove do_not_cover and related code. (process_property_notify): add strut_partial (update_struts): change function name to meta_window_update_struts and expose in external MetaWindow API. Support partial width struts and the new strut rects. * src/workspace.h: add new GSLists containing pointers to all relevant struts for this workspace. * src/workspace.c (meta_workspace_new): initialize the list of strut rects for this workspace. (meta_workspace_free): free the strut rect lists (ensure_work_areas_validated): support new struts and new strut rect lists. Unleash the per-xinerama work areas. * src/constraints.c (get_outermost_onscreen_positions): Use the current window position along with the new per-workspace strut rects to compute the constraints that apply to a particular window. (constraint_hint_applies_func): don't do hints constraints on fullscreen windows (update_position_limits): for maximized windows use the work areas to set the position limits; for other windows rely on the struts constraints to be computed later in get_outermost_onscreen_positions (meta_window_constrain): don't apply aspect ratio hints to full screen windows * src/display.c (meta_display_open): add _NET_WM_STRUT_PARTIAL atom (meta_rectangle_equal): new helper function for MetaRectangles (event_queue_callback): #ifndef out if USE_GDK_DISPLAY not set to avoid compiler warning * src/display.h: add atom_net_wm_strut_partial, and add meta_rectangle_equal. * src/screen.c (meta_screen_rect_intersects_xinerama): change _window_intersects_ to _rect_intersects_ which is more useful now. (meta_screen_resize_func): update struts on windows with struts since struts are relative to the screen size, and this function is called when the screen size updates. * src/screen.h (meta_screen_rect_intersects_xinerama): change _window_intersects_ to _rect_intersects_ which is more useful now. * src/window-props.c (meta_display_init_window_prop_hooks): add hook for strut_partial * src/tools/metacity-window-demo.c: Support partial-width struts on the dock window tests for metacity testing purposes.
This commit is contained in:
parent
3a39036dcb
commit
971f3f1207
65
ChangeLog
65
ChangeLog
@ -1,3 +1,68 @@
|
||||
2003-06-10 Rob Adams <robadams@ucla.edu>
|
||||
|
||||
Update constraints code to support the new _NET_WM_STRUT_PARTIAL
|
||||
EWMH draft specification. See #86682. Also, fix a bug involving
|
||||
work area invalidation on metacity startup. Fix for #108497.
|
||||
Finally, some minor fixes for full screen windows.
|
||||
|
||||
* src/window.h: Add new MetaStruts structure to store strut rects
|
||||
for a window. Remove has_struts and do_not_cover flag, and
|
||||
support new MetaStruts instead of the four ints.
|
||||
|
||||
* src/window.c (meta_window_new): change initialization to work
|
||||
with new struts. Also, move meta_window_update_struts call to
|
||||
after the workspaces are initialized to fix #108497. Remove
|
||||
do_not_cover and related code.
|
||||
(process_property_notify): add strut_partial
|
||||
(update_struts): change function name to meta_window_update_struts
|
||||
and expose in external MetaWindow API. Support partial width
|
||||
struts and the new strut rects.
|
||||
|
||||
* src/workspace.h: add new GSLists containing pointers to all
|
||||
relevant struts for this workspace.
|
||||
|
||||
* src/workspace.c (meta_workspace_new): initialize the list of
|
||||
strut rects for this workspace.
|
||||
(meta_workspace_free): free the strut rect lists
|
||||
(ensure_work_areas_validated): support new struts and new strut
|
||||
rect lists. Unleash the per-xinerama work areas.
|
||||
|
||||
* src/constraints.c (get_outermost_onscreen_positions): Use the
|
||||
current window position along with the new per-workspace strut
|
||||
rects to compute the constraints that apply to a particular
|
||||
window.
|
||||
(constraint_hint_applies_func): don't do hints constraints on
|
||||
fullscreen windows
|
||||
(update_position_limits): for maximized windows use the work areas
|
||||
to set the position limits; for other windows rely on the struts
|
||||
constraints to be computed later in
|
||||
get_outermost_onscreen_positions
|
||||
(meta_window_constrain): don't apply aspect ratio hints to full
|
||||
screen windows
|
||||
|
||||
* src/display.c (meta_display_open): add _NET_WM_STRUT_PARTIAL atom
|
||||
(meta_rectangle_equal): new helper function for MetaRectangles
|
||||
(event_queue_callback): #ifndef out if USE_GDK_DISPLAY not set to
|
||||
avoid compiler warning
|
||||
|
||||
* src/display.h: add atom_net_wm_strut_partial, and add
|
||||
meta_rectangle_equal.
|
||||
|
||||
* src/screen.c (meta_screen_rect_intersects_xinerama): change
|
||||
_window_intersects_ to _rect_intersects_ which is more useful now.
|
||||
(meta_screen_resize_func): update struts on windows with struts
|
||||
since struts are relative to the screen size, and this function is
|
||||
called when the screen size updates.
|
||||
|
||||
* src/screen.h (meta_screen_rect_intersects_xinerama): change
|
||||
_window_intersects_ to _rect_intersects_ which is more useful now.
|
||||
|
||||
* src/window-props.c (meta_display_init_window_prop_hooks): add
|
||||
hook for strut_partial
|
||||
|
||||
* src/tools/metacity-window-demo.c: Support partial-width struts
|
||||
on the dock window tests for metacity testing purposes.
|
||||
|
||||
2003-06-22 Samúel Jón Gunnarsson <sammi@techattack.nu>
|
||||
|
||||
* configure.in: Added "is" to ALL_LINGUAS
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include <config.h>
|
||||
#include "constraints.h"
|
||||
#include "window.h"
|
||||
#include "workspace.h"
|
||||
#include "place.h"
|
||||
|
||||
/* The way this code works was suggested by Owen Taylor.
|
||||
@ -123,7 +125,7 @@ typedef struct
|
||||
* size of the menu control?).
|
||||
*/
|
||||
|
||||
#define TITLEBAR_LENGTH_ONSCREEN 36
|
||||
#define TITLEBAR_LENGTH_ONSCREEN 75
|
||||
|
||||
typedef gboolean (* MetaConstraintAppliesFunc) (MetaWindow *window);
|
||||
|
||||
@ -301,7 +303,7 @@ static const Constraint constraint_desktop = {
|
||||
* behavior, but not doing that for now.
|
||||
*
|
||||
* Top resize works the same as left resize. Right/bottom resize don't have a limit
|
||||
* because the constraint is designed to keep the top right corner of the
|
||||
* because the constraint is designed to keep the top left corner of the
|
||||
* window or its titlebar on the screen, and right/bottom resize will never move that
|
||||
* area. Center resize is almost like left/top but dx has the opposite sign
|
||||
* and new_width = orig_width + 2dx.
|
||||
@ -347,31 +349,153 @@ static void
|
||||
get_outermost_onscreen_positions (MetaWindow *window,
|
||||
const ConstraintInfo *info,
|
||||
const MetaRectangle *orig,
|
||||
int delta_x,
|
||||
int delta_y,
|
||||
int *leftmost_x,
|
||||
int *rightmost_x,
|
||||
int *topmost_y,
|
||||
int *bottommost_y)
|
||||
{
|
||||
GList *workspaces;
|
||||
GList *tmp;
|
||||
GSList *stmp;
|
||||
MetaRectangle current;
|
||||
|
||||
/* to handle struts, we get the list of workspaces for the window
|
||||
* and traverse all the struts in each of the cached strut lists for
|
||||
* the workspaces. Note that because the workarea has already been
|
||||
* computed, these strut lists should already be up to date. No
|
||||
* memory allocation should take place in this function for
|
||||
* performance.
|
||||
*/
|
||||
|
||||
current = *orig;
|
||||
current.x += delta_x;
|
||||
current.y += delta_y;
|
||||
|
||||
workspaces = meta_window_get_workspaces (window);
|
||||
tmp = workspaces;
|
||||
|
||||
if (leftmost_x)
|
||||
*leftmost_x = info->nw_x - orig->width +
|
||||
MIN (TITLEBAR_LENGTH_ONSCREEN, orig->width);
|
||||
|
||||
{
|
||||
*leftmost_x = info->nw_x;
|
||||
while (tmp)
|
||||
{
|
||||
stmp = ((MetaWorkspace*) tmp->data)->left_struts;
|
||||
while (stmp)
|
||||
{
|
||||
MetaRectangle *rect = (MetaRectangle*) stmp->data;
|
||||
/* the strut only matters if the title bar is
|
||||
* overlapping the strut rect.
|
||||
*/
|
||||
if (((current.y - info->fgeom.top_height >= rect->y) &&
|
||||
(current.y - info->fgeom.top_height <= rect->y + rect->height)) ||
|
||||
((current.y >= rect->y) &&
|
||||
(current.y <= rect->y + rect->height)))
|
||||
{
|
||||
*leftmost_x = MAX (*leftmost_x, rect->width);
|
||||
}
|
||||
|
||||
stmp = stmp->next;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
*leftmost_x = *leftmost_x - current.width +
|
||||
MIN (TITLEBAR_LENGTH_ONSCREEN, current.width);
|
||||
}
|
||||
|
||||
tmp = workspaces;
|
||||
if (rightmost_x)
|
||||
*rightmost_x = info->se_x - MIN (TITLEBAR_LENGTH_ONSCREEN, orig->width);
|
||||
{
|
||||
*rightmost_x = info->se_x;
|
||||
while (tmp)
|
||||
{
|
||||
stmp = ((MetaWorkspace*) tmp->data)->right_struts;
|
||||
while (stmp)
|
||||
{
|
||||
MetaRectangle *rect = (MetaRectangle*) stmp->data;
|
||||
/* the strut only matters if the title bar is
|
||||
* overlapping the strut rect.
|
||||
*/
|
||||
if (((current.y - info->fgeom.top_height >= rect->y) &&
|
||||
(current.y - info->fgeom.top_height <= rect->y + rect->height)) ||
|
||||
((current.y >= rect->y) &&
|
||||
(current.y <= rect->y + rect->height)))
|
||||
{
|
||||
*rightmost_x = MIN (*rightmost_x, rect->x);
|
||||
}
|
||||
|
||||
stmp = stmp->next;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
*rightmost_x = *rightmost_x -
|
||||
MIN (TITLEBAR_LENGTH_ONSCREEN, current.width);
|
||||
}
|
||||
|
||||
tmp = workspaces;
|
||||
if (topmost_y)
|
||||
*topmost_y = info->nw_y + info->fgeom.top_height;
|
||||
{
|
||||
*topmost_y = info->nw_y;
|
||||
while (tmp)
|
||||
{
|
||||
stmp = ((MetaWorkspace*) tmp->data)->top_struts;
|
||||
while (stmp)
|
||||
{
|
||||
MetaRectangle *rect = (MetaRectangle*) stmp->data;
|
||||
/* here the strut matters if the titlebar is overlapping
|
||||
* the window horizontally
|
||||
*/
|
||||
if ((current.x <= rect->x + rect->width) &&
|
||||
(current.x + current.width >= rect->x))
|
||||
{
|
||||
*topmost_y = MAX (*topmost_y, rect->height);
|
||||
}
|
||||
|
||||
stmp = stmp->next;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
*topmost_y = *topmost_y + info->fgeom.top_height;
|
||||
}
|
||||
|
||||
tmp = workspaces;
|
||||
if (bottommost_y)
|
||||
{
|
||||
*bottommost_y = info->se_y;
|
||||
while (tmp)
|
||||
{
|
||||
stmp = ((MetaWorkspace*) tmp->data)->bottom_struts;
|
||||
while (stmp)
|
||||
{
|
||||
MetaRectangle *rect = (MetaRectangle*) stmp->data;
|
||||
/* here the strut matters if the titlebar is overlapping
|
||||
* the window horizontally
|
||||
*/
|
||||
if ((current.x <= rect->x + rect->width) &&
|
||||
(current.x + current.width >= rect->x))
|
||||
{
|
||||
*bottommost_y = MIN (*bottommost_y, rect->y);
|
||||
}
|
||||
|
||||
stmp = stmp->next;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* If no frame, keep random TITLEBAR_LENGTH_ONSCREEN pixels on the
|
||||
* screen.
|
||||
*/
|
||||
if (window->frame)
|
||||
*bottommost_y = info->se_y;
|
||||
else
|
||||
*bottommost_y = info->se_y -
|
||||
MIN (TITLEBAR_LENGTH_ONSCREEN, orig->height);
|
||||
if (!window->frame)
|
||||
*bottommost_y = *bottommost_y -
|
||||
MIN (TITLEBAR_LENGTH_ONSCREEN, current.height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -384,7 +508,7 @@ constraint_onscreen_top_func (MetaWindow *window,
|
||||
int min_dy;
|
||||
int topmost_y;
|
||||
|
||||
get_outermost_onscreen_positions (window, info, orig,
|
||||
get_outermost_onscreen_positions (window, info, orig, 0, *y_delta,
|
||||
NULL, NULL, &topmost_y, NULL);
|
||||
|
||||
min_dy = topmost_y - orig->y;
|
||||
@ -402,7 +526,7 @@ constraint_onscreen_bottom_func (MetaWindow *window,
|
||||
int max_dy;
|
||||
int bottommost_y;
|
||||
|
||||
get_outermost_onscreen_positions (window, info, orig,
|
||||
get_outermost_onscreen_positions (window, info, orig, 0, *y_delta,
|
||||
NULL, NULL, NULL, &bottommost_y);
|
||||
|
||||
max_dy = bottommost_y - orig->y;
|
||||
@ -420,7 +544,7 @@ constraint_onscreen_vcenter_func (MetaWindow *window,
|
||||
int max_dy;
|
||||
int topmost_y;
|
||||
|
||||
get_outermost_onscreen_positions (window, info, orig,
|
||||
get_outermost_onscreen_positions (window, info, orig, 0, *y_delta,
|
||||
NULL, NULL, &topmost_y, NULL);
|
||||
|
||||
max_dy = orig->y - topmost_y;
|
||||
@ -438,7 +562,7 @@ constraint_onscreen_left_func (MetaWindow *window,
|
||||
int min_dx;
|
||||
int leftmost_x;
|
||||
|
||||
get_outermost_onscreen_positions (window, info, orig,
|
||||
get_outermost_onscreen_positions (window, info, orig, *x_delta, 0,
|
||||
&leftmost_x, NULL, NULL, NULL);
|
||||
|
||||
min_dx = leftmost_x - orig->x;
|
||||
@ -456,7 +580,7 @@ constraint_onscreen_right_func (MetaWindow *window,
|
||||
int max_dx;
|
||||
int rightmost_x;
|
||||
|
||||
get_outermost_onscreen_positions (window, info, orig,
|
||||
get_outermost_onscreen_positions (window, info, orig, *x_delta, 0,
|
||||
NULL, &rightmost_x, NULL, NULL);
|
||||
|
||||
max_dx = rightmost_x - orig->x;
|
||||
@ -474,7 +598,7 @@ constraint_onscreen_hcenter_func (MetaWindow *window,
|
||||
int max_dx;
|
||||
int leftmost_x;
|
||||
|
||||
get_outermost_onscreen_positions (window, info, orig,
|
||||
get_outermost_onscreen_positions (window, info, orig, *x_delta, 0,
|
||||
&leftmost_x, NULL, NULL, NULL);
|
||||
|
||||
max_dx = orig->x - leftmost_x;
|
||||
@ -494,7 +618,7 @@ constraint_onscreen_move_func (MetaWindow *window,
|
||||
int max_delta;
|
||||
int leftmost_x, rightmost_x, topmost_y, bottommost_y;
|
||||
|
||||
get_outermost_onscreen_positions (window, info, orig,
|
||||
get_outermost_onscreen_positions (window, info, orig, *x_delta, *y_delta,
|
||||
&leftmost_x, &rightmost_x,
|
||||
&topmost_y, &bottommost_y);
|
||||
|
||||
@ -560,7 +684,7 @@ static const Constraint constraint_onscreen = {
|
||||
static gboolean
|
||||
constraint_hints_applies_func (MetaWindow *window)
|
||||
{
|
||||
return TRUE;
|
||||
return (!window->fullscreen);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -787,25 +911,32 @@ constrain_move (MetaWindow *window,
|
||||
MetaRectangle *new)
|
||||
{
|
||||
const Constraint **cp;
|
||||
int old_x, old_y;
|
||||
|
||||
cp = &all_constraints[0];
|
||||
|
||||
while (*cp)
|
||||
{
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Before: %d %d (Move constraint '%s')\n",
|
||||
x_delta, y_delta, (*cp)->name);
|
||||
|
||||
if ((* (*cp)->applies_func) (window))
|
||||
(* (*cp)->move_func) (window, info, orig,
|
||||
&x_delta, &y_delta);
|
||||
do {
|
||||
old_x = x_delta;
|
||||
old_y = y_delta;
|
||||
cp = &all_constraints[0];
|
||||
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"After: %d %d (Move constraint '%s')\n",
|
||||
x_delta, y_delta, (*cp)->name);
|
||||
while (*cp)
|
||||
{
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Before: %d %d (Move constraint '%s')\n",
|
||||
x_delta, y_delta, (*cp)->name);
|
||||
|
||||
if ((* (*cp)->applies_func) (window))
|
||||
(* (*cp)->move_func) (window, info, orig,
|
||||
&x_delta, &y_delta);
|
||||
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"After: %d %d (Move constraint '%s')\n",
|
||||
x_delta, y_delta, (*cp)->name);
|
||||
|
||||
++cp;
|
||||
}
|
||||
++cp;
|
||||
}
|
||||
|
||||
} while ((old_x != x_delta) || (old_y != y_delta));
|
||||
|
||||
new->x = orig->x + x_delta;
|
||||
new->y = orig->y + y_delta;
|
||||
@ -1023,12 +1154,24 @@ update_position_limits (MetaWindow *window,
|
||||
int nw_x, nw_y;
|
||||
int se_x, se_y;
|
||||
|
||||
nw_x = info->work_area_screen.x;
|
||||
nw_y = info->work_area_screen.y;
|
||||
if (window->maximized)
|
||||
{
|
||||
nw_x = MIN (info->work_area_xinerama.x, info->work_area_screen.x);
|
||||
nw_y = MIN (info->work_area_xinerama.y, info->work_area_screen.y);
|
||||
|
||||
/* find bottom-right corner of workarea */
|
||||
se_x = info->work_area_screen.x + info->work_area_screen.width;
|
||||
se_y = info->work_area_screen.y + info->work_area_screen.height;
|
||||
/* find bottom-right corner of workarea */
|
||||
se_x = MAX (info->work_area_xinerama.x + info->work_area_xinerama.width,
|
||||
info->work_area_screen.x + info->work_area_screen.width);
|
||||
se_y = MAX (info->work_area_xinerama.y + info->work_area_xinerama.height,
|
||||
info->work_area_screen.y + info->work_area_screen.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
nw_x = 0;
|
||||
nw_y = 0;
|
||||
se_x = window->screen->width;
|
||||
se_y = window->screen->height;
|
||||
}
|
||||
|
||||
/* If we have a micro-screen or huge frames maybe nw/se got
|
||||
* swapped
|
||||
@ -1078,7 +1221,7 @@ meta_window_constrain (MetaWindow *window,
|
||||
|
||||
#define OUTER_WIDTH(rect) ((rect).width + info.fgeom.left_width + info.fgeom.right_width)
|
||||
#define OUTER_HEIGHT(rect) ((rect).height + info.fgeom.top_height + info.fgeom.bottom_height)
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Constraining %s x_move_delta = %d y_move_delta = %d x_direction = %d y_direction = %d x_delta = %d y_delta = %d orig %d,%d %dx%d\n",
|
||||
window->desc, x_move_delta, y_move_delta,
|
||||
@ -1252,108 +1395,108 @@ meta_window_constrain (MetaWindow *window,
|
||||
|
||||
#if 0
|
||||
/* Now we have to sort out the aspect ratio */
|
||||
{
|
||||
/*
|
||||
* width
|
||||
* min_aspect <= -------- <= max_aspect
|
||||
* height
|
||||
*/
|
||||
double min_aspect, max_aspect;
|
||||
int width, height;
|
||||
if (!window->fullscreen)
|
||||
{
|
||||
/*
|
||||
* width
|
||||
* min_aspect <= -------- <= max_aspect
|
||||
* height
|
||||
*/
|
||||
double min_aspect, max_aspect;
|
||||
int width, height;
|
||||
|
||||
min_aspect = window->size_hints.min_aspect.x / (double) window->size_hints.min_aspect.y;
|
||||
max_aspect = window->size_hints.max_aspect.x / (double) window->size_hints.max_aspect.y;
|
||||
|
||||
width = current.width;
|
||||
height = current.height;
|
||||
|
||||
min_aspect = window->size_hints.min_aspect.x / (double) window->size_hints.min_aspect.y;
|
||||
max_aspect = window->size_hints.max_aspect.x / (double) window->size_hints.max_aspect.y;
|
||||
|
||||
width = current.width;
|
||||
height = current.height;
|
||||
|
||||
/* Use the standard cut-and-pasted-between-every-WM code: */
|
||||
if (min_aspect * height > width)
|
||||
{
|
||||
int delta;
|
||||
|
||||
delta = FLOOR (height - width / min_aspect, window->size_hints.height_inc);
|
||||
if (height - delta >= window->size_hints.min_height)
|
||||
height -= delta;
|
||||
else
|
||||
{
|
||||
delta = FLOOR (height * min_aspect - width, window->size_hints.width_inc);
|
||||
if (width + delta <= window->size_hints.max_width)
|
||||
width += delta;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_aspect * height < width)
|
||||
{
|
||||
int delta;
|
||||
|
||||
delta = FLOOR (width - height * max_aspect, window->size_hints.width_inc);
|
||||
if (width - delta >= window->size_hints.min_width)
|
||||
width -= delta;
|
||||
else
|
||||
{
|
||||
delta = FLOOR (width / max_aspect - height, window->size_hints.height_inc);
|
||||
if (height + delta <= window->size_hints.max_height)
|
||||
height += delta;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert into terms of the direction of resize and reapply the
|
||||
* earlier constraints; this means aspect ratio becomes the
|
||||
* least-important of the constraints. If we wanted aspect to be
|
||||
* the most important, we could just not do this next bit.
|
||||
*/
|
||||
|
||||
if (current.width != width)
|
||||
{
|
||||
x_delta = width - current.width; /* positive delta to increase width */
|
||||
switch (x_direction)
|
||||
{
|
||||
case META_RESIZE_LEFT_OR_TOP:
|
||||
constrain_resize_left (window, &info, ¤t,
|
||||
- x_delta, new);
|
||||
break;
|
||||
case META_RESIZE_CENTER:
|
||||
constrain_resize_hcenter (window, &info, ¤t,
|
||||
/* Use the standard cut-and-pasted-between-every-WM code: */
|
||||
if (min_aspect * height > width)
|
||||
{
|
||||
int delta;
|
||||
|
||||
delta = FLOOR (height - width / min_aspect, window->size_hints.height_inc);
|
||||
if (height - delta >= window->size_hints.min_height)
|
||||
height -= delta;
|
||||
else
|
||||
{
|
||||
delta = FLOOR (height * min_aspect - width, window->size_hints.width_inc);
|
||||
if (width + delta <= window->size_hints.max_width)
|
||||
width += delta;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_aspect * height < width)
|
||||
{
|
||||
int delta;
|
||||
|
||||
delta = FLOOR (width - height * max_aspect, window->size_hints.width_inc);
|
||||
if (width - delta >= window->size_hints.min_width)
|
||||
width -= delta;
|
||||
else
|
||||
{
|
||||
delta = FLOOR (width / max_aspect - height, window->size_hints.height_inc);
|
||||
if (height + delta <= window->size_hints.max_height)
|
||||
height += delta;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert into terms of the direction of resize and reapply the
|
||||
* earlier constraints; this means aspect ratio becomes the
|
||||
* least-important of the constraints. If we wanted aspect to be
|
||||
* the most important, we could just not do this next bit.
|
||||
*/
|
||||
|
||||
if (current.width != width)
|
||||
{
|
||||
x_delta = width - current.width; /* positive delta to increase width */
|
||||
switch (x_direction)
|
||||
{
|
||||
case META_RESIZE_LEFT_OR_TOP:
|
||||
constrain_resize_left (window, &info, ¤t,
|
||||
- x_delta, new);
|
||||
break;
|
||||
case META_RESIZE_CENTER:
|
||||
constrain_resize_hcenter (window, &info, ¤t,
|
||||
x_delta, new);
|
||||
break;
|
||||
case META_RESIZE_RIGHT_OR_BOTTOM:
|
||||
constrain_resize_right (window, &info, ¤t,
|
||||
x_delta, new);
|
||||
break;
|
||||
case META_RESIZE_RIGHT_OR_BOTTOM:
|
||||
constrain_resize_right (window, &info, ¤t,
|
||||
x_delta, new);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (current.height != height)
|
||||
{
|
||||
y_delta = height - current.height; /* positive to increase height */
|
||||
|
||||
switch (y_direction)
|
||||
{
|
||||
case META_RESIZE_LEFT_OR_TOP:
|
||||
constrain_resize_top (window, &info, ¤t,
|
||||
- y_delta, new);
|
||||
break;
|
||||
case META_RESIZE_CENTER:
|
||||
constrain_resize_vcenter (window, &info, ¤t,
|
||||
y_delta, new);
|
||||
break;
|
||||
case META_RESIZE_RIGHT_OR_BOTTOM:
|
||||
constrain_resize_bottom (window, &info, ¤t,
|
||||
y_delta, new);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current = *new;
|
||||
|
||||
if (current.height != height)
|
||||
{
|
||||
y_delta = height - current.height; /* positive to increase height */
|
||||
g_print ("3 x_delta = %d y_delta = %d pos = %d,%d size = %dx%d\n",
|
||||
x_delta, y_delta,
|
||||
current.x, current.y, current.width, current.height);
|
||||
}
|
||||
|
||||
switch (y_direction)
|
||||
{
|
||||
case META_RESIZE_LEFT_OR_TOP:
|
||||
constrain_resize_top (window, &info, ¤t,
|
||||
- y_delta, new);
|
||||
break;
|
||||
case META_RESIZE_CENTER:
|
||||
constrain_resize_vcenter (window, &info, ¤t,
|
||||
y_delta, new);
|
||||
break;
|
||||
case META_RESIZE_RIGHT_OR_BOTTOM:
|
||||
constrain_resize_bottom (window, &info, ¤t,
|
||||
y_delta, new);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current = *new;
|
||||
}
|
||||
|
||||
|
||||
g_print ("3 x_delta = %d y_delta = %d pos = %d,%d size = %dx%d\n",
|
||||
x_delta, y_delta,
|
||||
current.x, current.y, current.width, current.height);
|
||||
#endif
|
||||
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Constrained %s new %d,%d %dx%d old %d,%d %dx%d\n",
|
||||
window->desc,
|
||||
|
@ -77,6 +77,11 @@ static GSList *all_displays = NULL;
|
||||
|
||||
static void meta_spew_event (MetaDisplay *display,
|
||||
XEvent *event);
|
||||
#ifndef USE_GDK_DISPLAY
|
||||
static void event_queue_callback (XEvent *event,
|
||||
gpointer data);
|
||||
#endif
|
||||
|
||||
static gboolean event_callback (XEvent *event,
|
||||
gpointer data);
|
||||
static Window event_get_modified_window (MetaDisplay *display,
|
||||
@ -263,7 +268,8 @@ meta_display_open (const char *name)
|
||||
"_GNOME_PANEL_ACTION",
|
||||
"_GNOME_PANEL_ACTION_MAIN_MENU",
|
||||
"_GNOME_PANEL_ACTION_RUN_DIALOG",
|
||||
"_METACITY_SENTINEL"
|
||||
"_METACITY_SENTINEL",
|
||||
"_NET_WM_STRUT_PARTIAL"
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
|
||||
@ -406,6 +412,7 @@ meta_display_open (const char *name)
|
||||
display->atom_gnome_panel_action_main_menu = atoms[77];
|
||||
display->atom_gnome_panel_action_run_dialog = atoms[78];
|
||||
display->atom_metacity_sentinel = atoms[79];
|
||||
display->atom_net_wm_strut_partial = atoms[80];
|
||||
|
||||
display->prop_hooks = NULL;
|
||||
meta_display_init_window_prop_hooks (display);
|
||||
@ -875,6 +882,15 @@ meta_display_is_double_click (MetaDisplay *display)
|
||||
|
||||
static gboolean dump_events = TRUE;
|
||||
|
||||
#ifndef USE_GDK_DISPLAY
|
||||
static void
|
||||
event_queue_callback (XEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
event_callback (event, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
grab_op_is_mouse (MetaGrabOp op)
|
||||
{
|
||||
@ -1252,6 +1268,7 @@ event_callback (XEvent *event,
|
||||
if (window->frame)
|
||||
{
|
||||
window->frame->need_reapply_frame_shape = TRUE;
|
||||
meta_warning("from event callback\n");
|
||||
meta_window_queue_move_resize (window);
|
||||
}
|
||||
}
|
||||
@ -3202,6 +3219,7 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
|
||||
{
|
||||
MetaWindow *window = tmp->data;
|
||||
|
||||
meta_warning("from retheme\n");
|
||||
meta_window_queue_move_resize (window);
|
||||
if (window->frame)
|
||||
{
|
||||
@ -3324,8 +3342,8 @@ meta_display_ping_window (MetaDisplay *display,
|
||||
"Sending ping with timestamp %lu to window %s\n",
|
||||
timestamp, window->desc);
|
||||
meta_window_send_icccm_message (window,
|
||||
display->atom_net_wm_ping,
|
||||
timestamp);
|
||||
display->atom_net_wm_ping,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
/* process the pong from our ping */
|
||||
@ -3676,6 +3694,16 @@ meta_rectangle_intersect (MetaRectangle *src1,
|
||||
return return_val;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_rectangle_equal (const MetaRectangle *src1,
|
||||
const MetaRectangle *src2)
|
||||
{
|
||||
return ((src1->x == src2->x) &&
|
||||
(src1->y == src2->y) &&
|
||||
(src1->width == src2->width) &&
|
||||
(src1->height == src2->height));
|
||||
}
|
||||
|
||||
static MetaScreen*
|
||||
find_screen_for_selection (MetaDisplay *display,
|
||||
Window owner,
|
||||
|
@ -168,6 +168,7 @@ struct _MetaDisplay
|
||||
Atom atom_gnome_panel_action_main_menu;
|
||||
Atom atom_gnome_panel_action_run_dialog;
|
||||
Atom atom_metacity_sentinel;
|
||||
Atom atom_net_wm_strut_partial;
|
||||
|
||||
/* This is the actual window from focus events,
|
||||
* not the one we last set
|
||||
@ -433,6 +434,8 @@ gboolean meta_grab_op_is_resizing (MetaGrabOp op);
|
||||
gboolean meta_rectangle_intersect (MetaRectangle *src1,
|
||||
MetaRectangle *src2,
|
||||
MetaRectangle *dest);
|
||||
gboolean meta_rectangle_equal (const MetaRectangle *src1,
|
||||
const MetaRectangle *src2);
|
||||
|
||||
void meta_display_devirtualize_modifiers (MetaDisplay *display,
|
||||
MetaVirtualModifier modifiers,
|
||||
|
70
src/screen.c
70
src/screen.c
@ -81,8 +81,7 @@ set_wm_check_hint (MetaScreen *screen)
|
||||
static int
|
||||
set_supported_hint (MetaScreen *screen)
|
||||
{
|
||||
#define N_SUPPORTED 45
|
||||
#define N_WIN_SUPPORTED 1
|
||||
#define N_SUPPORTED 49
|
||||
Atom atoms[N_SUPPORTED];
|
||||
|
||||
atoms[0] = screen->display->atom_net_wm_name;
|
||||
@ -106,30 +105,34 @@ set_supported_hint (MetaScreen *screen)
|
||||
atoms[18] = screen->display->atom_net_client_list_stacking;
|
||||
atoms[19] = screen->display->atom_net_wm_state_skip_taskbar;
|
||||
atoms[20] = screen->display->atom_net_wm_state_skip_pager;
|
||||
atoms[21] = screen->display->atom_net_wm_icon;
|
||||
atoms[22] = screen->display->atom_net_wm_moveresize;
|
||||
atoms[23] = screen->display->atom_net_wm_state_hidden;
|
||||
atoms[24] = screen->display->atom_net_wm_window_type_utility;
|
||||
atoms[25] = screen->display->atom_net_wm_window_type_splash;
|
||||
atoms[26] = screen->display->atom_net_wm_state_fullscreen;
|
||||
atoms[27] = screen->display->atom_net_wm_ping;
|
||||
atoms[28] = screen->display->atom_net_active_window;
|
||||
atoms[29] = screen->display->atom_net_workarea;
|
||||
atoms[30] = screen->display->atom_net_showing_desktop;
|
||||
atoms[31] = screen->display->atom_net_desktop_layout;
|
||||
atoms[32] = screen->display->atom_net_desktop_names;
|
||||
atoms[33] = screen->display->atom_net_wm_allowed_actions;
|
||||
atoms[34] = screen->display->atom_net_wm_action_move;
|
||||
atoms[35] = screen->display->atom_net_wm_action_resize;
|
||||
atoms[36] = screen->display->atom_net_wm_action_shade;
|
||||
atoms[37] = screen->display->atom_net_wm_action_stick;
|
||||
atoms[38] = screen->display->atom_net_wm_action_maximize_horz;
|
||||
atoms[39] = screen->display->atom_net_wm_action_maximize_vert;
|
||||
atoms[40] = screen->display->atom_net_wm_action_change_desktop;
|
||||
atoms[41] = screen->display->atom_net_wm_action_close;
|
||||
atoms[42] = screen->display->atom_net_wm_state_above;
|
||||
atoms[43] = screen->display->atom_net_wm_state_below;
|
||||
atoms[44] = screen->display->atom_net_startup_id;
|
||||
atoms[21] = screen->display->atom_net_wm_icon_name;
|
||||
atoms[22] = screen->display->atom_net_wm_icon;
|
||||
atoms[23] = screen->display->atom_net_wm_icon_geometry;
|
||||
atoms[24] = screen->display->atom_net_wm_moveresize;
|
||||
atoms[25] = screen->display->atom_net_active_window;
|
||||
atoms[26] = screen->display->atom_net_wm_strut;
|
||||
atoms[27] = screen->display->atom_net_wm_state_hidden;
|
||||
atoms[28] = screen->display->atom_net_wm_window_type_utility;
|
||||
atoms[29] = screen->display->atom_net_wm_window_type_splash;
|
||||
atoms[30] = screen->display->atom_net_wm_state_fullscreen;
|
||||
atoms[31] = screen->display->atom_net_wm_ping;
|
||||
atoms[32] = screen->display->atom_net_wm_pid;
|
||||
atoms[33] = screen->display->atom_net_workarea;
|
||||
atoms[34] = screen->display->atom_net_showing_desktop;
|
||||
atoms[35] = screen->display->atom_net_desktop_layout;
|
||||
atoms[36] = screen->display->atom_net_desktop_names;
|
||||
atoms[37] = screen->display->atom_net_wm_allowed_actions;
|
||||
atoms[38] = screen->display->atom_net_wm_action_move;
|
||||
atoms[39] = screen->display->atom_net_wm_action_resize;
|
||||
atoms[40] = screen->display->atom_net_wm_action_shade;
|
||||
atoms[41] = screen->display->atom_net_wm_action_stick;
|
||||
atoms[42] = screen->display->atom_net_wm_action_maximize_horz;
|
||||
atoms[43] = screen->display->atom_net_wm_action_maximize_vert;
|
||||
atoms[44] = screen->display->atom_net_wm_action_change_desktop;
|
||||
atoms[45] = screen->display->atom_net_wm_action_close;
|
||||
atoms[46] = screen->display->atom_net_wm_state_above;
|
||||
atoms[47] = screen->display->atom_net_wm_state_below;
|
||||
atoms[48] = screen->display->atom_net_startup_id;
|
||||
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom_net_supported,
|
||||
@ -1461,21 +1464,18 @@ meta_screen_get_natural_xinerama_list (MetaScreen *screen,
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_screen_window_intersects_xinerama (MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
int which_xinerama)
|
||||
meta_screen_rect_intersects_xinerama (MetaScreen *screen,
|
||||
MetaRectangle *rect,
|
||||
int which_xinerama)
|
||||
{
|
||||
MetaRectangle window_rect;
|
||||
MetaRectangle dest, screen_rect;
|
||||
|
||||
meta_window_get_outer_rect (window, &window_rect);
|
||||
|
||||
screen_rect.x = screen->xinerama_infos[which_xinerama].x_origin;
|
||||
screen_rect.y = screen->xinerama_infos[which_xinerama].y_origin;
|
||||
screen_rect.width = screen->xinerama_infos[which_xinerama].width;
|
||||
screen_rect.height = screen->xinerama_infos[which_xinerama].height;
|
||||
|
||||
if (meta_rectangle_intersect (&screen_rect, &window_rect, &dest))
|
||||
if (meta_rectangle_intersect (&screen_rect, rect, &dest))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
@ -2105,6 +2105,10 @@ meta_screen_resize_func (MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
void *user_data)
|
||||
{
|
||||
if (window->struts)
|
||||
{
|
||||
meta_window_update_struts (window);
|
||||
}
|
||||
meta_window_queue_move_resize (window);
|
||||
}
|
||||
|
||||
|
@ -148,9 +148,9 @@ const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_rect (MetaScreen
|
||||
const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
||||
MetaWindow *window);
|
||||
|
||||
gboolean meta_screen_window_intersects_xinerama (MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
int which_xinerama);
|
||||
gboolean meta_screen_rect_intersects_xinerama (MetaScreen *screen,
|
||||
MetaRectangle *window,
|
||||
int which_xinerama);
|
||||
|
||||
const MetaXineramaScreenInfo* meta_screen_get_xinerama_neighbor (MetaScreen *screen,
|
||||
int which_xinerama,
|
||||
|
@ -33,19 +33,27 @@ set_gdk_window_struts (GdkWindow *window,
|
||||
int top,
|
||||
int bottom)
|
||||
{
|
||||
long vals[4];
|
||||
long vals[12];
|
||||
|
||||
vals[0] = left;
|
||||
vals[1] = right;
|
||||
vals[2] = top;
|
||||
vals[3] = bottom;
|
||||
|
||||
vals[4] = 000;
|
||||
vals[5] = 400;
|
||||
vals[6] = 200;
|
||||
vals[7] = 600;
|
||||
vals[8] = 76;
|
||||
vals[9] = 676;
|
||||
vals[10] = 200;
|
||||
vals[11] = 800;
|
||||
|
||||
XChangeProperty (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XWINDOW (window),
|
||||
XInternAtom (GDK_WINDOW_XDISPLAY (window),
|
||||
"_NET_WM_STRUT", False),
|
||||
"_NET_WM_STRUT_PARTIAL", False),
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(guchar *)vals, 4);
|
||||
(guchar *)vals, 12);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -441,6 +449,7 @@ border_only_cb (gpointer callback_data,
|
||||
gtk_widget_show_all (window);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
changing_icon_cb (gpointer callback_data,
|
||||
guint callback_action,
|
||||
@ -462,6 +471,7 @@ changing_icon_cb (gpointer callback_data,
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
focus_in_event_cb (GtkWidget *window,
|
||||
@ -473,6 +483,8 @@ focus_in_event_cb (GtkWidget *window,
|
||||
widget = GTK_WIDGET (data);
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (widget), "Has focus");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -486,6 +498,8 @@ focus_out_event_cb (GtkWidget *window,
|
||||
widget = GTK_WIDGET (data);
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (widget), "Not focused");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
@ -583,26 +597,26 @@ make_dock (int type)
|
||||
switch (type)
|
||||
{
|
||||
case DOCK_LEFT:
|
||||
gtk_widget_set_size_request (window, DOCK_SIZE, gdk_screen_height ());
|
||||
gtk_window_move (GTK_WINDOW (window), 0, 0);
|
||||
gtk_widget_set_size_request (window, DOCK_SIZE, 400);
|
||||
gtk_window_move (GTK_WINDOW (window), 0, 000);
|
||||
set_gtk_window_struts (window, DOCK_SIZE, 0, 0, 0);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "LeftDock");
|
||||
break;
|
||||
case DOCK_RIGHT:
|
||||
gtk_widget_set_size_request (window, DOCK_SIZE, gdk_screen_height ());
|
||||
gtk_window_move (GTK_WINDOW (window), gdk_screen_width () - DOCK_SIZE, 0);
|
||||
gtk_widget_set_size_request (window, DOCK_SIZE, 400);
|
||||
gtk_window_move (GTK_WINDOW (window), gdk_screen_width () - DOCK_SIZE, 200);
|
||||
set_gtk_window_struts (window, 0, DOCK_SIZE, 0, 0);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "RightDock");
|
||||
break;
|
||||
case DOCK_TOP:
|
||||
gtk_widget_set_size_request (window, gdk_screen_width (), DOCK_SIZE);
|
||||
gtk_window_move (GTK_WINDOW (window), 0, 0);
|
||||
gtk_widget_set_size_request (window, 600, DOCK_SIZE);
|
||||
gtk_window_move (GTK_WINDOW (window), 76, 0);
|
||||
set_gtk_window_struts (window, 0, 0, DOCK_SIZE, 0);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "TopDock");
|
||||
break;
|
||||
case DOCK_BOTTOM:
|
||||
gtk_widget_set_size_request (window, gdk_screen_width (), DOCK_SIZE);
|
||||
gtk_window_move (GTK_WINDOW (window), 0, gdk_screen_height () - DOCK_SIZE);
|
||||
gtk_widget_set_size_request (window, 600, DOCK_SIZE);
|
||||
gtk_window_move (GTK_WINDOW (window), 200, gdk_screen_height () - DOCK_SIZE);
|
||||
set_gtk_window_struts (window, 0, 0, 0, DOCK_SIZE);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "BottomDock");
|
||||
break;
|
||||
|
@ -814,7 +814,7 @@ reload_wm_hints (MetaWindow *window,
|
||||
|
||||
|
||||
|
||||
#define N_HOOKS 22
|
||||
#define N_HOOKS 23
|
||||
|
||||
void
|
||||
meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
@ -914,6 +914,11 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom_net_wm_strut_partial;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom_net_startup_id;
|
||||
hooks[i].init_func = init_net_startup_id;
|
||||
hooks[i].reload_func = reload_net_startup_id;
|
||||
|
234
src/window.c
234
src/window.c
@ -64,7 +64,6 @@ static void update_transient_for (MetaWindow *window);
|
||||
static void update_sm_hints (MetaWindow *window);
|
||||
static void update_role (MetaWindow *window);
|
||||
static void update_net_wm_type (MetaWindow *window);
|
||||
static void update_struts (MetaWindow *window);
|
||||
static void recalc_window_type (MetaWindow *window);
|
||||
static void recalc_window_features (MetaWindow *window);
|
||||
static void invalidate_work_areas (MetaWindow *window);
|
||||
@ -77,8 +76,6 @@ static gboolean process_property_notify (MetaWindow *window,
|
||||
static void meta_window_show (MetaWindow *window);
|
||||
static void meta_window_hide (MetaWindow *window);
|
||||
|
||||
static GList* meta_window_get_workspaces (MetaWindow *window);
|
||||
|
||||
static void meta_window_save_rect (MetaWindow *window);
|
||||
|
||||
static void meta_window_move_resize_internal (MetaWindow *window,
|
||||
@ -479,11 +476,7 @@ meta_window_new (MetaDisplay *display,
|
||||
window->type = META_WINDOW_NORMAL;
|
||||
window->type_atom = None;
|
||||
|
||||
window->has_struts = FALSE;
|
||||
window->left_strut = 0;
|
||||
window->right_strut = 0;
|
||||
window->top_strut = 0;
|
||||
window->bottom_strut = 0;
|
||||
window->struts = NULL;
|
||||
|
||||
window->using_net_wm_name = FALSE;
|
||||
window->using_net_wm_icon_name = FALSE;
|
||||
@ -516,8 +509,6 @@ meta_window_new (MetaDisplay *display,
|
||||
g_assert (N_INITIAL_PROPS == i);
|
||||
|
||||
meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
|
||||
|
||||
update_struts (window);
|
||||
|
||||
update_net_wm_state (window);
|
||||
|
||||
@ -651,6 +642,8 @@ meta_window_new (MetaDisplay *display,
|
||||
|
||||
/* for the various on_all_workspaces = TRUE possible above */
|
||||
meta_window_set_current_workspace_hint (window);
|
||||
|
||||
meta_window_update_struts (window);
|
||||
|
||||
/* Put our state back where it should be,
|
||||
* passing TRUE for is_configure_request, ICCCM says
|
||||
@ -907,8 +900,11 @@ meta_window_free (MetaWindow *window)
|
||||
window->desc);
|
||||
}
|
||||
|
||||
if (window->has_struts)
|
||||
if (window->struts)
|
||||
{
|
||||
g_free (window->struts);
|
||||
window->struts = NULL;
|
||||
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Unmanaging window %s which has struts, so invalidating work areas\n",
|
||||
window->desc);
|
||||
@ -1679,7 +1675,7 @@ meta_window_show (MetaWindow *window)
|
||||
{
|
||||
set_net_wm_state (window);
|
||||
|
||||
if (window->has_struts)
|
||||
if (window->struts)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Mapped window %s with struts, so invalidating work areas\n",
|
||||
@ -1732,7 +1728,7 @@ meta_window_hide (MetaWindow *window)
|
||||
{
|
||||
set_net_wm_state (window);
|
||||
|
||||
if (window->has_struts)
|
||||
if (window->struts)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Unmapped window %s with struts, so invalidating work areas\n",
|
||||
@ -2307,7 +2303,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
meta_y_direction_from_gravity (resize_gravity),
|
||||
y_delta,
|
||||
&new_rect);
|
||||
|
||||
|
||||
w = new_rect.width;
|
||||
h = new_rect.height;
|
||||
root_x_nw = new_rect.x;
|
||||
@ -4118,10 +4114,11 @@ process_property_notify (MetaWindow *window,
|
||||
event->atom);
|
||||
meta_window_queue_update_icon (window);
|
||||
}
|
||||
else if (event->atom == window->display->atom_net_wm_strut)
|
||||
else if ((event->atom == window->display->atom_net_wm_strut) ||
|
||||
(event->atom == window->display->atom_net_wm_strut_partial))
|
||||
{
|
||||
meta_verbose ("Property notify on %s for _NET_WM_STRUT\n", window->desc);
|
||||
update_struts (window);
|
||||
meta_window_update_struts (window);
|
||||
}
|
||||
else if (event->atom == window->display->atom_net_startup_id)
|
||||
{
|
||||
@ -4788,7 +4785,7 @@ meta_window_queue_update_icon (MetaWindow *window)
|
||||
update_icon_pending = g_slist_prepend (update_icon_pending, window);
|
||||
}
|
||||
|
||||
static GList*
|
||||
GList*
|
||||
meta_window_get_workspaces (MetaWindow *window)
|
||||
{
|
||||
if (window->on_all_workspaces)
|
||||
@ -4811,68 +4808,102 @@ invalidate_work_areas (MetaWindow *window)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_struts (MetaWindow *window)
|
||||
void
|
||||
meta_window_update_struts (MetaWindow *window)
|
||||
{
|
||||
gulong *struts = NULL;
|
||||
int nitems;
|
||||
gboolean old_has_struts;
|
||||
int old_left;
|
||||
int old_right;
|
||||
int old_top;
|
||||
int old_bottom;
|
||||
gboolean new_has_struts;
|
||||
|
||||
MetaRectangle old_left;
|
||||
MetaRectangle old_right;
|
||||
MetaRectangle old_top;
|
||||
MetaRectangle old_bottom;
|
||||
|
||||
MetaRectangle new_left;
|
||||
MetaRectangle new_right;
|
||||
MetaRectangle new_top;
|
||||
MetaRectangle new_bottom;
|
||||
|
||||
meta_verbose ("Updating struts for %s\n", window->desc);
|
||||
|
||||
old_has_struts = window->has_struts;
|
||||
old_left = window->left_strut;
|
||||
old_right = window->right_strut;
|
||||
old_top = window->top_strut;
|
||||
old_bottom = window->bottom_strut;
|
||||
|
||||
window->has_struts = FALSE;
|
||||
window->left_strut = 0;
|
||||
window->right_strut = 0;
|
||||
window->top_strut = 0;
|
||||
window->bottom_strut = 0;
|
||||
if (window->struts)
|
||||
{
|
||||
old_has_struts = TRUE;
|
||||
old_left = window->struts->left;
|
||||
old_right = window->struts->right;
|
||||
old_top = window->struts->top;
|
||||
old_bottom = window->struts->bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
old_has_struts = FALSE;
|
||||
}
|
||||
|
||||
new_has_struts = FALSE;
|
||||
new_left.width = 0;
|
||||
new_left.x = 0;
|
||||
new_left.y = 0;
|
||||
new_left.height = window->screen->height;
|
||||
|
||||
new_right.width = 0;
|
||||
new_right.x = window->screen->width;
|
||||
new_right.y = 0;
|
||||
new_right.height = window->screen->height;
|
||||
|
||||
new_top.height = 0;
|
||||
new_top.y = 0;
|
||||
new_top.x = 0;
|
||||
new_top.width = window->screen->width;
|
||||
|
||||
new_bottom.height = 0;
|
||||
new_bottom.y = window->screen->height;
|
||||
new_bottom.x = 0;
|
||||
new_bottom.width = window->screen->width;
|
||||
|
||||
if (meta_prop_get_cardinal_list (window->display,
|
||||
window->xwindow,
|
||||
window->display->atom_net_wm_strut,
|
||||
window->display->atom_net_wm_strut_partial,
|
||||
&struts, &nitems))
|
||||
{
|
||||
if (nitems != 4)
|
||||
if (nitems != 12)
|
||||
{
|
||||
meta_verbose ("_NET_WM_STRUT on %s has %d values instead of 4\n",
|
||||
meta_verbose ("_NET_WM_STRUT_PARTIAL on %s has %d values instead of 12\n",
|
||||
window->desc, nitems);
|
||||
meta_XFree (struts);
|
||||
}
|
||||
|
||||
window->has_struts = TRUE;
|
||||
window->left_strut = struts[0];
|
||||
window->right_strut = struts[1];
|
||||
window->top_strut = struts[2];
|
||||
window->bottom_strut = struts[3];
|
||||
|
||||
meta_verbose ("_NET_WM_STRUT struts %d %d %d %d for window %s\n",
|
||||
window->left_strut, window->right_strut,
|
||||
window->top_strut, window->bottom_strut,
|
||||
window->desc);
|
||||
|
||||
if (window->left_strut < 0)
|
||||
window->left_strut = 0;
|
||||
if (window->right_strut < 0)
|
||||
window->right_strut = 0;
|
||||
if (window->top_strut < 0)
|
||||
window->top_strut = 0;
|
||||
if (window->bottom_strut < 0)
|
||||
window->bottom_strut = 0;
|
||||
|
||||
meta_verbose ("Using _NET_WM_STRUT struts %d %d %d %d for window %s\n",
|
||||
window->left_strut, window->right_strut,
|
||||
window->top_strut, window->bottom_strut,
|
||||
window->desc);
|
||||
|
||||
else
|
||||
{
|
||||
new_has_struts = TRUE;
|
||||
new_left.width = MIN ((int)struts[0],
|
||||
window->screen->width/2 - 75);
|
||||
new_right.width = MIN ((int)struts[1],
|
||||
window->screen->width/2 - 75);
|
||||
new_top.height = MIN ((int)struts[2],
|
||||
window->screen->height/2 - 75);
|
||||
new_bottom.height = MIN ((int)struts[3],
|
||||
window->screen->height/2 - 75);
|
||||
new_right.x = window->screen->width -
|
||||
new_right.width;
|
||||
new_bottom.y = window->screen->height -
|
||||
new_bottom.height;
|
||||
new_left.y = struts[4];
|
||||
new_left.height = struts[5] - new_left.y;
|
||||
new_right.y = struts[6];
|
||||
new_right.height = struts[7] - new_right.y;
|
||||
new_top.x = struts[8];
|
||||
new_top.width = struts[9] - new_top.x;
|
||||
new_bottom.x = struts[10];
|
||||
new_bottom.width = struts[11] - new_bottom.x;
|
||||
|
||||
meta_verbose ("_NET_WM_STRUT_PARTIAL struts %d %d %d %d for window %s\n",
|
||||
new_left.width,
|
||||
new_right.width,
|
||||
new_top.height,
|
||||
new_bottom.height,
|
||||
window->desc);
|
||||
|
||||
}
|
||||
meta_XFree (struts);
|
||||
}
|
||||
else
|
||||
@ -4881,12 +4912,75 @@ update_struts (MetaWindow *window)
|
||||
window->desc);
|
||||
}
|
||||
|
||||
if (old_has_struts != window->has_struts ||
|
||||
old_left != window->left_strut ||
|
||||
old_right != window->right_strut ||
|
||||
old_top != window->top_strut ||
|
||||
old_bottom != window->bottom_strut)
|
||||
{
|
||||
if (!new_has_struts)
|
||||
{
|
||||
if (meta_prop_get_cardinal_list (window->display,
|
||||
window->xwindow,
|
||||
window->display->atom_net_wm_strut,
|
||||
&struts, &nitems))
|
||||
{
|
||||
if (nitems != 4)
|
||||
{
|
||||
meta_verbose ("_NET_WM_STRUT on %s has %d values instead of 4\n",
|
||||
window->desc, nitems);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_has_struts = TRUE;
|
||||
new_left.width = MIN ((int)struts[0],
|
||||
window->screen->width/2 - 75);
|
||||
new_right.width = MIN ((int)struts[1],
|
||||
window->screen->width/2 - 75);
|
||||
new_top.height = MIN ((int)struts[2],
|
||||
window->screen->height/2 - 75);
|
||||
new_bottom.height = MIN ((int)struts[3],
|
||||
window->screen->height/2 - 75);
|
||||
new_left.x = 0;
|
||||
new_right.x = window->screen->width -
|
||||
new_right.width;
|
||||
new_top.y = 0;
|
||||
new_bottom.y = window->screen->height -
|
||||
new_bottom.height;
|
||||
|
||||
meta_verbose ("_NET_WM_STRUT struts %d %d %d %d for window %s\n",
|
||||
new_left.width,
|
||||
new_right.width,
|
||||
new_top.height,
|
||||
new_bottom.height,
|
||||
window->desc);
|
||||
|
||||
}
|
||||
meta_XFree (struts);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_verbose ("No _NET_WM_STRUT property for %s\n",
|
||||
window->desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (old_has_struts != new_has_struts ||
|
||||
(new_has_struts && old_has_struts &&
|
||||
(!meta_rectangle_equal(&old_left, &new_left) ||
|
||||
!meta_rectangle_equal(&old_right, &new_right) ||
|
||||
!meta_rectangle_equal(&old_top, &new_top) ||
|
||||
!meta_rectangle_equal(&old_bottom, &new_bottom))))
|
||||
{
|
||||
if (new_has_struts)
|
||||
{
|
||||
if (!window->struts)
|
||||
window->struts = g_new (MetaStruts, 1);
|
||||
|
||||
window->struts->left = new_left;
|
||||
window->struts->right = new_right;
|
||||
window->struts->top = new_top;
|
||||
window->struts->bottom = new_bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (window->struts);
|
||||
window->struts = NULL;
|
||||
}
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Invalidating work areas of window %s due to struts update\n",
|
||||
window->desc);
|
||||
|
24
src/window.h
24
src/window.h
@ -32,6 +32,7 @@
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
typedef struct _MetaGroup MetaGroup;
|
||||
typedef struct _MetaStruts MetaStruts;
|
||||
|
||||
typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window,
|
||||
void *data);
|
||||
@ -49,6 +50,15 @@ typedef enum
|
||||
META_WINDOW_SPLASHSCREEN
|
||||
} MetaWindowType;
|
||||
|
||||
struct _MetaStruts
|
||||
{
|
||||
/* struts */
|
||||
MetaRectangle left;
|
||||
MetaRectangle right;
|
||||
MetaRectangle top;
|
||||
MetaRectangle bottom;
|
||||
};
|
||||
|
||||
struct _MetaWindow
|
||||
{
|
||||
MetaDisplay *display;
|
||||
@ -211,8 +221,8 @@ struct _MetaWindow
|
||||
*/
|
||||
guint calc_placement : 1;
|
||||
|
||||
/* Has nonzero struts */
|
||||
guint has_struts : 1;
|
||||
/* Note: can be NULL */
|
||||
MetaStruts *struts;
|
||||
|
||||
/* Transient parent is a root window */
|
||||
guint transient_parent_is_root_window : 1;
|
||||
@ -271,12 +281,6 @@ struct _MetaWindow
|
||||
/* x/y/w/h here get filled with ConfigureRequest values */
|
||||
XSizeHints size_hints;
|
||||
|
||||
/* struts */
|
||||
int left_strut;
|
||||
int right_strut;
|
||||
int top_strut;
|
||||
int bottom_strut;
|
||||
|
||||
/* Managed by stack.c */
|
||||
MetaStackLayer layer;
|
||||
int stack_position; /* see comment in stack.h */
|
||||
@ -355,6 +359,8 @@ void meta_window_fill_vertical (MetaWindow *window);
|
||||
*/
|
||||
void meta_window_queue_move_resize (MetaWindow *window);
|
||||
|
||||
void meta_window_update_struts (MetaWindow *window);
|
||||
|
||||
/* this gets root coords */
|
||||
void meta_window_get_position (MetaWindow *window,
|
||||
int *x,
|
||||
@ -424,6 +430,8 @@ void meta_window_set_gravity (MetaWindow *window,
|
||||
void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
XEvent *event);
|
||||
|
||||
GList* meta_window_get_workspaces (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_visible_on_workspace (MetaWindow *window,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
|
118
src/workspace.c
118
src/workspace.c
@ -48,6 +48,11 @@ meta_workspace_new (MetaScreen *screen)
|
||||
workspace->all_work_areas.y = 0;
|
||||
workspace->all_work_areas.width = 0;
|
||||
workspace->all_work_areas.height = 0;
|
||||
|
||||
workspace->left_struts = NULL;
|
||||
workspace->right_struts = NULL;
|
||||
workspace->top_struts = NULL;
|
||||
workspace->bottom_struts = NULL;
|
||||
|
||||
return workspace;
|
||||
}
|
||||
@ -86,6 +91,12 @@ meta_workspace_free (MetaWorkspace *workspace)
|
||||
g_list_remove (workspace->screen->workspaces, workspace);
|
||||
|
||||
g_free (workspace->work_areas);
|
||||
|
||||
g_slist_free (workspace->left_struts);
|
||||
g_slist_free (workspace->right_struts);
|
||||
g_slist_free (workspace->top_struts);
|
||||
g_slist_free (workspace->bottom_struts);
|
||||
|
||||
g_free (workspace);
|
||||
|
||||
/* don't bother to reset names, pagers can just ignore
|
||||
@ -105,7 +116,7 @@ meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
meta_window_set_current_workspace_hint (window);
|
||||
|
||||
meta_window_queue_calc_showing (window);
|
||||
if (window->has_struts)
|
||||
if (window->struts)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Invalidating work area of workspace %d since we're adding window %s to it\n",
|
||||
@ -132,7 +143,7 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
|
||||
meta_window_queue_calc_showing (window);
|
||||
|
||||
if (window->has_struts)
|
||||
if (window->struts)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Invalidating work area of workspace %d since we're removing window %s from it\n",
|
||||
@ -375,6 +386,15 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
if (!workspace->work_areas_invalid)
|
||||
return;
|
||||
|
||||
g_slist_free (workspace->left_struts);
|
||||
workspace->left_struts = NULL;
|
||||
g_slist_free (workspace->right_struts);
|
||||
workspace->right_struts = NULL;
|
||||
g_slist_free (workspace->top_struts);
|
||||
workspace->top_struts = NULL;
|
||||
g_slist_free (workspace->bottom_struts);
|
||||
workspace->bottom_struts = NULL;
|
||||
|
||||
windows = meta_workspace_list_windows (workspace);
|
||||
|
||||
g_free (workspace->work_areas);
|
||||
@ -394,33 +414,76 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
if (w->has_struts &&
|
||||
(meta_screen_window_intersects_xinerama (w->screen, w, i)))
|
||||
if (w->struts)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Merging win %s with %d %d %d %d "
|
||||
"with %d %d %d %d\n",
|
||||
w->desc,
|
||||
w->left_strut, w->right_strut,
|
||||
w->top_strut, w->bottom_strut,
|
||||
w->struts->left.width, w->struts->right.width,
|
||||
w->struts->top.height, w->struts->bottom.height,
|
||||
left_strut, right_strut,
|
||||
top_strut, bottom_strut);
|
||||
|
||||
left_strut = MAX (left_strut,
|
||||
w->left_strut -
|
||||
workspace->screen->xinerama_infos[i].x_origin);
|
||||
all_left_strut = MAX (all_left_strut, w->left_strut);
|
||||
if ((i == 0) && (w->struts->left.width > 0))
|
||||
{
|
||||
workspace->left_struts = g_slist_prepend (workspace->left_struts,
|
||||
&w->struts->left);
|
||||
}
|
||||
|
||||
right_strut = MAX (right_strut, w->right_strut);
|
||||
all_right_strut = MAX (all_right_strut, w->right_strut);
|
||||
if (meta_screen_rect_intersects_xinerama (w->screen,
|
||||
&w->struts->left,
|
||||
i))
|
||||
{
|
||||
left_strut = MAX (left_strut,
|
||||
w->struts->left.width -
|
||||
workspace->screen->xinerama_infos[i].x_origin);
|
||||
all_left_strut = MAX (all_left_strut, w->struts->left.width);
|
||||
}
|
||||
|
||||
top_strut = MAX (top_strut,
|
||||
w->top_strut -
|
||||
workspace->screen->xinerama_infos[i].y_origin);
|
||||
all_top_strut = MAX (all_top_strut, w->top_strut);
|
||||
if ((i == 0) && (w->struts->right.width > 0))
|
||||
{
|
||||
workspace->right_struts = g_slist_prepend (workspace->right_struts,
|
||||
&w->struts->right);
|
||||
}
|
||||
|
||||
bottom_strut = MAX (bottom_strut, w->bottom_strut);
|
||||
all_bottom_strut = MAX (all_bottom_strut, w->bottom_strut);
|
||||
if (meta_screen_rect_intersects_xinerama (w->screen,
|
||||
&w->struts->right,
|
||||
i))
|
||||
{
|
||||
right_strut = MAX (right_strut, w->struts->right.width);
|
||||
all_right_strut = MAX (all_right_strut, w->struts->right.width);
|
||||
}
|
||||
|
||||
if ((i == 0) && (w->struts->top.height > 0))
|
||||
{
|
||||
workspace->top_struts = g_slist_prepend (workspace->top_struts,
|
||||
&w->struts->top);
|
||||
}
|
||||
|
||||
if (meta_screen_rect_intersects_xinerama (w->screen,
|
||||
&w->struts->top,
|
||||
i))
|
||||
{
|
||||
top_strut = MAX (top_strut,
|
||||
w->struts->top.height -
|
||||
workspace->screen->xinerama_infos[i].y_origin);
|
||||
all_top_strut = MAX (all_top_strut, w->struts->top.height);
|
||||
}
|
||||
|
||||
if ((i == 0) && (w->struts->bottom.height > 0))
|
||||
{
|
||||
workspace->bottom_struts = g_slist_prepend (workspace->bottom_struts,
|
||||
&w->struts->bottom);
|
||||
}
|
||||
|
||||
if (meta_screen_rect_intersects_xinerama (w->screen,
|
||||
&w->struts->bottom,
|
||||
i))
|
||||
{
|
||||
bottom_strut = MAX (bottom_strut, w->struts->bottom.height);
|
||||
all_bottom_strut = MAX (all_bottom_strut, w->struts->bottom.height);
|
||||
}
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
@ -451,10 +514,6 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
bottom_strut = top_strut;
|
||||
}
|
||||
|
||||
/* FIXME even if we take struts to apply only to xineramas
|
||||
* that the strut-specifying window overlaps, is it right
|
||||
* to make the struts *relative to* the xinerama?
|
||||
*/
|
||||
workspace->work_areas[i].x =
|
||||
left_strut + workspace->screen->xinerama_infos[i].x_origin;
|
||||
workspace->work_areas[i].y = top_strut +
|
||||
@ -467,7 +526,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
top_strut - bottom_strut;
|
||||
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Computed [unused] work area for workspace %d "
|
||||
"Computed work area for workspace %d "
|
||||
"xinerama %d: %d,%d %d x %d\n",
|
||||
meta_workspace_index (workspace),
|
||||
i,
|
||||
@ -507,19 +566,6 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
workspace->screen->width - all_left_strut - all_right_strut;
|
||||
workspace->all_work_areas.height =
|
||||
workspace->screen->height - all_top_strut - all_bottom_strut;
|
||||
|
||||
/* FIXME Here we disable all the per-xinerama work done earlier,
|
||||
* because we don't have a spec for how it should work yet.
|
||||
* If we do rely on which windows overlap what, work areas
|
||||
* will need to be invalidated when we change a strut-setting
|
||||
* window's size/position in move_resize_internal
|
||||
*/
|
||||
i = 0;
|
||||
while (i < workspace->screen->n_xinerama_infos)
|
||||
{
|
||||
workspace->work_areas[i] = workspace->all_work_areas;
|
||||
++i;
|
||||
}
|
||||
|
||||
workspace->work_areas_invalid = FALSE;
|
||||
|
||||
|
@ -42,8 +42,11 @@ struct _MetaWorkspace
|
||||
GList *windows;
|
||||
|
||||
MetaRectangle all_work_areas;
|
||||
|
||||
MetaRectangle *work_areas;
|
||||
GSList *left_struts;
|
||||
GSList *right_struts;
|
||||
GSList *top_struts;
|
||||
GSList *bottom_struts;
|
||||
guint work_areas_invalid : 1;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user