Switch over to new constraints code, unquestionably introduces some bugs,
2003-02-27 Havoc Pennington <hp@redhat.com> Switch over to new constraints code, unquestionably introduces some bugs, but should get us on the right path. * src/window.c (meta_window_get_work_area_all_xineramas): create this function again as it turned out to be legitimate for window position constraint (adjust_for_gravity): use the width/height from the configure request to compute the requested move (meta_window_move_resize_internal): use meta_window_constrain (update_size_hints): clamp max size to MAXSHORT to avoid worrying about overflow stuff * src/constraints.c (meta_window_constrain): don't base placement on uninitialized variables, general hacking * src/Makefile.am (metacity_SOURCES): add constraints.c, constraints.h * src/constraints.c (meta_window_constrain): update the cut-and-paste aspect ratio code to have latest bugfixes
This commit is contained in:
parent
4481be72d1
commit
5f75334d57
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
|||||||
|
2003-02-27 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
Switch over to new constraints code, unquestionably introduces
|
||||||
|
some bugs, but should get us on the right path.
|
||||||
|
|
||||||
|
* src/window.c (meta_window_get_work_area_all_xineramas): create
|
||||||
|
this function again as it turned out to be legitimate for window
|
||||||
|
position constraint
|
||||||
|
(adjust_for_gravity): use the width/height from the configure
|
||||||
|
request to compute the requested move
|
||||||
|
(meta_window_move_resize_internal): use meta_window_constrain
|
||||||
|
(update_size_hints): clamp max size to MAXSHORT to avoid worrying
|
||||||
|
about overflow stuff
|
||||||
|
|
||||||
|
* src/constraints.c (meta_window_constrain): don't base placement
|
||||||
|
on uninitialized variables, general hacking
|
||||||
|
|
||||||
|
* src/Makefile.am (metacity_SOURCES): add constraints.c,
|
||||||
|
constraints.h
|
||||||
|
|
||||||
|
* src/constraints.c (meta_window_constrain): update the
|
||||||
|
cut-and-paste aspect ratio code to have latest bugfixes
|
||||||
|
|
||||||
2003-03-08 Rob Adams <robadams@ucla.edu>
|
2003-03-08 Rob Adams <robadams@ucla.edu>
|
||||||
|
|
||||||
* src/window-props.c (reload_normal_hints): Check that window min
|
* src/window-props.c (reload_normal_hints): Check that window min
|
||||||
|
@ -14,6 +14,8 @@ metacity_SOURCES= \
|
|||||||
bell.h \
|
bell.h \
|
||||||
bell.c \
|
bell.c \
|
||||||
common.h \
|
common.h \
|
||||||
|
constraints.c \
|
||||||
|
constraints.h \
|
||||||
core.c \
|
core.c \
|
||||||
core.h \
|
core.h \
|
||||||
delete.c \
|
delete.c \
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Metacity size/position constraints */
|
/* Metacity size/position constraints */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Red Hat, Inc.
|
* Copyright (C) 2002, 2003 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -19,6 +19,7 @@
|
|||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
#include "constraints.h"
|
#include "constraints.h"
|
||||||
#include "place.h"
|
#include "place.h"
|
||||||
|
|
||||||
@ -106,6 +107,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FLOOR(value, base) ( ((int) ((value) / (base))) * (base) )
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
@ -113,7 +116,7 @@ typedef struct
|
|||||||
const MetaXineramaScreenInfo *xinerama;
|
const MetaXineramaScreenInfo *xinerama;
|
||||||
MetaRectangle work_area_xinerama;
|
MetaRectangle work_area_xinerama;
|
||||||
MetaRectangle work_area_screen;
|
MetaRectangle work_area_screen;
|
||||||
int nw_x, nw_y, se_x, se_y;
|
int nw_x, nw_y, se_x, se_y; /* these are whole-screen not xinerama */
|
||||||
} ConstraintInfo;
|
} ConstraintInfo;
|
||||||
|
|
||||||
/* (FIXME instead of TITLEBAR_LENGTH_ONSCREEN, get the actual
|
/* (FIXME instead of TITLEBAR_LENGTH_ONSCREEN, get the actual
|
||||||
@ -157,6 +160,7 @@ typedef void (* MetaConstrainMoveFunc) (MetaWindow *window,
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
const char *name;
|
||||||
MetaConstraintAppliesFunc applies_func;
|
MetaConstraintAppliesFunc applies_func;
|
||||||
MetaConstrainTopFunc top_func;
|
MetaConstrainTopFunc top_func;
|
||||||
MetaConstrainBottomFunc bottom_func;
|
MetaConstrainBottomFunc bottom_func;
|
||||||
@ -251,6 +255,7 @@ constraint_desktop_move_func (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const Constraint constraint_desktop = {
|
static const Constraint constraint_desktop = {
|
||||||
|
"Desktop",
|
||||||
constraint_desktop_applies_func,
|
constraint_desktop_applies_func,
|
||||||
constraint_desktop_top_func,
|
constraint_desktop_top_func,
|
||||||
constraint_desktop_bottom_func,
|
constraint_desktop_bottom_func,
|
||||||
@ -337,6 +342,36 @@ constraint_onscreen_applies_func (MetaWindow *window)
|
|||||||
window->type != META_WINDOW_DOCK;
|
window->type != META_WINDOW_DOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_outermost_onscreen_positions (MetaWindow *window,
|
||||||
|
const ConstraintInfo *info,
|
||||||
|
const MetaRectangle *orig,
|
||||||
|
int *leftmost_x,
|
||||||
|
int *rightmost_x,
|
||||||
|
int *topmost_y,
|
||||||
|
int *bottommost_y)
|
||||||
|
{
|
||||||
|
if (leftmost_x)
|
||||||
|
*leftmost_x = info->nw_x + TITLEBAR_LENGTH_ONSCREEN - orig->width;
|
||||||
|
|
||||||
|
if (rightmost_x)
|
||||||
|
*rightmost_x = info->se_x - TITLEBAR_LENGTH_ONSCREEN;
|
||||||
|
|
||||||
|
if (topmost_y)
|
||||||
|
*topmost_y = info->nw_y + info->fgeom.top_height;
|
||||||
|
|
||||||
|
if (bottommost_y)
|
||||||
|
{
|
||||||
|
/* 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 - TITLEBAR_LENGTH_ONSCREEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
constraint_onscreen_top_func (MetaWindow *window,
|
constraint_onscreen_top_func (MetaWindow *window,
|
||||||
const ConstraintInfo *info,
|
const ConstraintInfo *info,
|
||||||
@ -344,8 +379,12 @@ constraint_onscreen_top_func (MetaWindow *window,
|
|||||||
int *y_delta)
|
int *y_delta)
|
||||||
{
|
{
|
||||||
int min_dy;
|
int min_dy;
|
||||||
|
int topmost_y;
|
||||||
|
|
||||||
min_dy = info->nw_y + info->fgeom.top_height - orig->y;
|
get_outermost_onscreen_positions (window, info, orig,
|
||||||
|
NULL, NULL, &topmost_y, NULL);
|
||||||
|
|
||||||
|
min_dy = topmost_y - orig->y;
|
||||||
|
|
||||||
if (*y_delta < min_dy)
|
if (*y_delta < min_dy)
|
||||||
*y_delta = min_dy;
|
*y_delta = min_dy;
|
||||||
@ -358,8 +397,12 @@ constraint_onscreen_bottom_func (MetaWindow *window,
|
|||||||
int *y_delta)
|
int *y_delta)
|
||||||
{
|
{
|
||||||
int max_dy;
|
int max_dy;
|
||||||
|
int bottommost_y;
|
||||||
|
|
||||||
max_dy = info->se_y - info->fgeom.top_height - orig->y;
|
get_outermost_onscreen_positions (window, info, orig,
|
||||||
|
NULL, NULL, NULL, &bottommost_y);
|
||||||
|
|
||||||
|
max_dy = bottommost_y - orig->y;
|
||||||
|
|
||||||
if (*y_delta > max_dy)
|
if (*y_delta > max_dy)
|
||||||
*y_delta = max_dy;
|
*y_delta = max_dy;
|
||||||
@ -372,9 +415,12 @@ constraint_onscreen_vcenter_func (MetaWindow *window,
|
|||||||
int *y_delta)
|
int *y_delta)
|
||||||
{
|
{
|
||||||
int max_dy;
|
int max_dy;
|
||||||
|
int topmost_y;
|
||||||
|
|
||||||
max_dy = info->nw_y + info->fgeom.top_height - orig->y;
|
get_outermost_onscreen_positions (window, info, orig,
|
||||||
max_dy = ABS (max_dy);
|
NULL, NULL, &topmost_y, NULL);
|
||||||
|
|
||||||
|
max_dy = orig->y - topmost_y;
|
||||||
|
|
||||||
if (*y_delta > max_dy)
|
if (*y_delta > max_dy)
|
||||||
*y_delta = max_dy;
|
*y_delta = max_dy;
|
||||||
@ -387,8 +433,12 @@ constraint_onscreen_left_func (MetaWindow *window,
|
|||||||
int *x_delta)
|
int *x_delta)
|
||||||
{
|
{
|
||||||
int min_dx;
|
int min_dx;
|
||||||
|
int leftmost_x;
|
||||||
|
|
||||||
min_dx = info->nw_x + info->fgeom.left_width + TITLEBAR_WIDTH_ONSCREEN - orig->x;
|
get_outermost_onscreen_positions (window, info, orig,
|
||||||
|
&leftmost_x, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
min_dx = leftmost_x - orig->x;
|
||||||
|
|
||||||
if (*x_delta < min_dx)
|
if (*x_delta < min_dx)
|
||||||
*x_delta = min_dx;
|
*x_delta = min_dx;
|
||||||
@ -401,8 +451,12 @@ constraint_onscreen_right_func (MetaWindow *window,
|
|||||||
int *x_delta)
|
int *x_delta)
|
||||||
{
|
{
|
||||||
int max_dx;
|
int max_dx;
|
||||||
|
int rightmost_x;
|
||||||
|
|
||||||
max_dx = info->se_x - TITLEBAR_WIDTH_ONSCREEN - orig->x;
|
get_outermost_onscreen_positions (window, info, orig,
|
||||||
|
NULL, &rightmost_x, NULL, NULL);
|
||||||
|
|
||||||
|
max_dx = rightmost_x - orig->x;
|
||||||
|
|
||||||
if (*x_delta > max_dx)
|
if (*x_delta > max_dx)
|
||||||
*x_delta = max_dx;
|
*x_delta = max_dx;
|
||||||
@ -415,9 +469,12 @@ constraint_onscreen_hcenter_func (MetaWindow *window,
|
|||||||
int *x_delta)
|
int *x_delta)
|
||||||
{
|
{
|
||||||
int max_dx;
|
int max_dx;
|
||||||
|
int leftmost_x;
|
||||||
|
|
||||||
max_dx = info->nw_x + info->fgeom.left_width + TITLEBAR_WIDTH_ONSCREEN - orig->x;
|
get_outermost_onscreen_positions (window, info, orig,
|
||||||
max_dx = ABS (max_dx);
|
&leftmost_x, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
max_dx = orig->x - leftmost_x;
|
||||||
|
|
||||||
if (*x_delta > max_dx)
|
if (*x_delta > max_dx)
|
||||||
*x_delta = max_dx;
|
*x_delta = max_dx;
|
||||||
@ -432,14 +489,14 @@ constraint_onscreen_move_func (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
int min_delta;
|
int min_delta;
|
||||||
int max_delta;
|
int max_delta;
|
||||||
|
int leftmost_x, rightmost_x, topmost_y, bottommost_y;
|
||||||
|
|
||||||
min_delta = info->nw_y + info->fgeom.top_height - orig->y;
|
get_outermost_onscreen_positions (window, info, orig,
|
||||||
|
&leftmost_x, &rightmost_x,
|
||||||
if (window->frame) /* if frame, the titlebar is always above the y pos */
|
&topmost_y, &bottommost_y);
|
||||||
max_delta = info->se_y - orig->y;
|
|
||||||
else /* else keep some client area pixels on the screen */
|
|
||||||
max_delta = info->se_y - orig->y - TITLEBAR_WIDTH_ONSCREEN;
|
|
||||||
|
|
||||||
|
min_delta = topmost_y - orig->y;
|
||||||
|
max_delta = bottommost_y - orig->y;
|
||||||
|
|
||||||
/* Note that min delta (top left) has priority over
|
/* Note that min delta (top left) has priority over
|
||||||
* max delta (bottom right) to facilitate keeping
|
* max delta (bottom right) to facilitate keeping
|
||||||
@ -450,8 +507,8 @@ constraint_onscreen_move_func (MetaWindow *window,
|
|||||||
if (*y_delta < min_delta)
|
if (*y_delta < min_delta)
|
||||||
*y_delta = min_delta;
|
*y_delta = min_delta;
|
||||||
|
|
||||||
min_delta = info->nw_x + TITLEBAR_WIDTH_ONSCREEN - orig->x;
|
min_delta = leftmost_x - orig->x;
|
||||||
max_delta = info->se_x - orig->x - TITLEBAR_WIDTH_ONSCREEN;
|
max_delta = rightmost_x - orig->x;
|
||||||
|
|
||||||
if (*x_delta > max_delta)
|
if (*x_delta > max_delta)
|
||||||
*x_delta = max_delta;
|
*x_delta = max_delta;
|
||||||
@ -460,6 +517,7 @@ constraint_onscreen_move_func (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const Constraint constraint_onscreen = {
|
static const Constraint constraint_onscreen = {
|
||||||
|
"Onscreen",
|
||||||
constraint_onscreen_applies_func,
|
constraint_onscreen_applies_func,
|
||||||
constraint_onscreen_top_func,
|
constraint_onscreen_top_func,
|
||||||
constraint_onscreen_bottom_func,
|
constraint_onscreen_bottom_func,
|
||||||
@ -480,7 +538,7 @@ static const Constraint constraint_onscreen = {
|
|||||||
* meta_window_constrain, because it involves both dimensions, and
|
* meta_window_constrain, because it involves both dimensions, and
|
||||||
* thus messes up our generic framework.
|
* thus messes up our generic framework.
|
||||||
*
|
*
|
||||||
* Left resize:
|
* Left resize can be solved for dx like this:
|
||||||
* new_width = orig_width - dx
|
* new_width = orig_width - dx
|
||||||
* new_x = orig_x + dx
|
* new_x = orig_x + dx
|
||||||
*
|
*
|
||||||
@ -508,7 +566,27 @@ constraint_hints_top_func (MetaWindow *window,
|
|||||||
const MetaRectangle *orig,
|
const MetaRectangle *orig,
|
||||||
int *y_delta)
|
int *y_delta)
|
||||||
{
|
{
|
||||||
|
int min_dy;
|
||||||
|
int max_dy;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
max_dy = orig->height - window->size_hints.min_height;
|
||||||
|
min_dy = orig->height - window->size_hints.max_height;
|
||||||
|
|
||||||
|
g_assert (max_dy >= min_dy);
|
||||||
|
|
||||||
|
if (*y_delta > max_dy)
|
||||||
|
*y_delta = max_dy;
|
||||||
|
if (*y_delta < min_dy)
|
||||||
|
*y_delta = min_dy;
|
||||||
|
|
||||||
|
/* shrink to base + N * inc
|
||||||
|
*/
|
||||||
|
height = orig->height - *y_delta;
|
||||||
|
height = window->size_hints.base_height +
|
||||||
|
FLOOR (height - window->size_hints.base_height, window->size_hints.height_inc);
|
||||||
|
|
||||||
|
*y_delta = orig->height - height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -517,7 +595,27 @@ constraint_hints_bottom_func (MetaWindow *window,
|
|||||||
const MetaRectangle *orig,
|
const MetaRectangle *orig,
|
||||||
int *y_delta)
|
int *y_delta)
|
||||||
{
|
{
|
||||||
|
int min_dy;
|
||||||
|
int max_dy;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
min_dy = window->size_hints.min_height - orig->height;
|
||||||
|
max_dy = window->size_hints.max_height - orig->height;
|
||||||
|
|
||||||
|
g_assert (max_dy >= min_dy);
|
||||||
|
|
||||||
|
if (*y_delta > max_dy)
|
||||||
|
*y_delta = max_dy;
|
||||||
|
if (*y_delta < min_dy)
|
||||||
|
*y_delta = min_dy;
|
||||||
|
|
||||||
|
/* shrink to base + N * inc
|
||||||
|
*/
|
||||||
|
height = orig->height + *y_delta;
|
||||||
|
height = window->size_hints.base_height +
|
||||||
|
FLOOR (height - window->size_hints.base_height, window->size_hints.height_inc);
|
||||||
|
|
||||||
|
*y_delta = height - orig->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -526,7 +624,32 @@ constraint_hints_vcenter_func (MetaWindow *window,
|
|||||||
const MetaRectangle *orig,
|
const MetaRectangle *orig,
|
||||||
int *y_delta)
|
int *y_delta)
|
||||||
{
|
{
|
||||||
|
int min_dy;
|
||||||
|
int max_dy;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
/* Remember our delta is negative to shrink window, positive to
|
||||||
|
* grow it, and the actual resize is y_delta * 2 (which is broken,
|
||||||
|
* but that's how it currently is)
|
||||||
|
*/
|
||||||
|
|
||||||
|
min_dy = (window->size_hints.min_height - orig->height) / 2;
|
||||||
|
max_dy = (window->size_hints.max_height - orig->height) / 2;
|
||||||
|
|
||||||
|
g_assert (max_dy >= min_dy);
|
||||||
|
|
||||||
|
if (*y_delta > max_dy)
|
||||||
|
*y_delta = max_dy;
|
||||||
|
if (*y_delta < min_dy)
|
||||||
|
*y_delta = min_dy;
|
||||||
|
|
||||||
|
/* shrink to base + N * inc
|
||||||
|
*/
|
||||||
|
height = orig->height + *y_delta * 2;
|
||||||
|
height = window->size_hints.base_height +
|
||||||
|
FLOOR (height - window->size_hints.base_height, window->size_hints.height_inc);
|
||||||
|
|
||||||
|
*y_delta = (height - orig->height) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -542,6 +665,8 @@ constraint_hints_left_func (MetaWindow *window,
|
|||||||
max_dx = orig->width - window->size_hints.min_width;
|
max_dx = orig->width - window->size_hints.min_width;
|
||||||
min_dx = orig->width - window->size_hints.max_width;
|
min_dx = orig->width - window->size_hints.max_width;
|
||||||
|
|
||||||
|
g_assert (max_dx >= min_dx);
|
||||||
|
|
||||||
if (*x_delta > max_dx)
|
if (*x_delta > max_dx)
|
||||||
*x_delta = max_dx;
|
*x_delta = max_dx;
|
||||||
if (*x_delta < min_dx)
|
if (*x_delta < min_dx)
|
||||||
@ -562,7 +687,27 @@ constraint_hints_right_func (MetaWindow *window,
|
|||||||
const MetaRectangle *orig,
|
const MetaRectangle *orig,
|
||||||
int *x_delta)
|
int *x_delta)
|
||||||
{
|
{
|
||||||
|
int min_dx;
|
||||||
|
int max_dx;
|
||||||
|
int width;
|
||||||
|
|
||||||
|
min_dx = window->size_hints.min_width - orig->width;
|
||||||
|
max_dx = window->size_hints.max_width - orig->width;
|
||||||
|
|
||||||
|
g_assert (max_dx >= min_dx);
|
||||||
|
|
||||||
|
if (*x_delta > max_dx)
|
||||||
|
*x_delta = max_dx;
|
||||||
|
if (*x_delta < min_dx)
|
||||||
|
*x_delta = min_dx;
|
||||||
|
|
||||||
|
/* shrink to base + N * inc
|
||||||
|
*/
|
||||||
|
width = orig->width + *x_delta;
|
||||||
|
width = window->size_hints.base_width +
|
||||||
|
FLOOR (width - window->size_hints.base_width, window->size_hints.width_inc);
|
||||||
|
|
||||||
|
*x_delta = width - orig->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -571,7 +716,32 @@ constraint_hints_hcenter_func (MetaWindow *window,
|
|||||||
const MetaRectangle *orig,
|
const MetaRectangle *orig,
|
||||||
int *x_delta)
|
int *x_delta)
|
||||||
{
|
{
|
||||||
|
int min_dx;
|
||||||
|
int max_dx;
|
||||||
|
int width;
|
||||||
|
|
||||||
|
/* Remember our delta is negative to shrink window, positive to
|
||||||
|
* grow it, and the actual resize is x_delta * 2 (which is broken,
|
||||||
|
* but that's how it currently is)
|
||||||
|
*/
|
||||||
|
|
||||||
|
min_dx = (window->size_hints.min_width - orig->width) / 2;
|
||||||
|
max_dx = (window->size_hints.max_width - orig->width) / 2;
|
||||||
|
|
||||||
|
g_assert (max_dx >= min_dx);
|
||||||
|
|
||||||
|
if (*x_delta > max_dx)
|
||||||
|
*x_delta = max_dx;
|
||||||
|
if (*x_delta < min_dx)
|
||||||
|
*x_delta = min_dx;
|
||||||
|
|
||||||
|
/* shrink to base + N * inc
|
||||||
|
*/
|
||||||
|
width = orig->width + *x_delta * 2;
|
||||||
|
width = window->size_hints.base_width +
|
||||||
|
FLOOR (width - window->size_hints.base_width, window->size_hints.width_inc);
|
||||||
|
|
||||||
|
*x_delta = (width - orig->width) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -585,6 +755,7 @@ constraint_hints_move_func (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const Constraint constraint_hints = {
|
static const Constraint constraint_hints = {
|
||||||
|
"Hints",
|
||||||
constraint_hints_applies_func,
|
constraint_hints_applies_func,
|
||||||
constraint_hints_top_func,
|
constraint_hints_top_func,
|
||||||
constraint_hints_bottom_func,
|
constraint_hints_bottom_func,
|
||||||
@ -618,10 +789,18 @@ constrain_move (MetaWindow *window,
|
|||||||
|
|
||||||
while (*cp)
|
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))
|
if ((* (*cp)->applies_func) (window))
|
||||||
(* (*cp)->move_func) (window, info, orig,
|
(* (*cp)->move_func) (window, info, orig,
|
||||||
&x_delta, &y_delta);
|
&x_delta, &y_delta);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"After: %d %d (Move constraint '%s')\n",
|
||||||
|
x_delta, y_delta, (*cp)->name);
|
||||||
|
|
||||||
++cp;
|
++cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,17 +821,25 @@ constrain_resize_left (MetaWindow *window,
|
|||||||
|
|
||||||
while (*cp)
|
while (*cp)
|
||||||
{
|
{
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Before: %d (Left constraint '%s')\n",
|
||||||
|
x_delta, (*cp)->name);
|
||||||
|
|
||||||
if ((* (*cp)->applies_func) (window))
|
if ((* (*cp)->applies_func) (window))
|
||||||
(* (*cp)->left_func) (window, info, orig,
|
(* (*cp)->left_func) (window, info, orig,
|
||||||
&x_delta);
|
&x_delta);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"After: %d (Left constraint '%s')\n",
|
||||||
|
x_delta, (*cp)->name);
|
||||||
|
|
||||||
++cp;
|
++cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Moving mouse from 10 to 5 means current - orig means 5 - 10 means
|
/* Moving mouse from 10 to 5 means current - orig means 5 - 10 means
|
||||||
* a delta of -5
|
* a delta of -5
|
||||||
*/
|
*/
|
||||||
new->x = orig->x - x_delta;
|
new->x = orig->x + x_delta;
|
||||||
new->width = orig->width - x_delta;
|
new->width = orig->width - x_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -669,10 +856,18 @@ constrain_resize_hcenter (MetaWindow *window,
|
|||||||
|
|
||||||
while (*cp)
|
while (*cp)
|
||||||
{
|
{
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Before: %d (HCenter constraint '%s')\n",
|
||||||
|
x_delta, (*cp)->name);
|
||||||
|
|
||||||
if ((* (*cp)->applies_func) (window))
|
if ((* (*cp)->applies_func) (window))
|
||||||
(* (*cp)->hcenter_func) (window, info, orig,
|
(* (*cp)->hcenter_func) (window, info, orig,
|
||||||
&x_delta);
|
&x_delta);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"After: %d (HCenter constraint '%s')\n",
|
||||||
|
x_delta, (*cp)->name);
|
||||||
|
|
||||||
++cp;
|
++cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -681,6 +876,9 @@ constrain_resize_hcenter (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
new->x = orig->x - x_delta;
|
new->x = orig->x - x_delta;
|
||||||
new->width = orig->width + x_delta * 2;
|
new->width = orig->width + x_delta * 2;
|
||||||
|
/* FIXME above implies that with center gravity you have to grow
|
||||||
|
* in increments of two
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -696,10 +894,18 @@ constrain_resize_right (MetaWindow *window,
|
|||||||
|
|
||||||
while (*cp)
|
while (*cp)
|
||||||
{
|
{
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Before: %d (Right constraint '%s')\n",
|
||||||
|
x_delta, (*cp)->name);
|
||||||
|
|
||||||
if ((* (*cp)->applies_func) (window))
|
if ((* (*cp)->applies_func) (window))
|
||||||
(* (*cp)->right_func) (window, info, orig,
|
(* (*cp)->right_func) (window, info, orig,
|
||||||
&x_delta);
|
&x_delta);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"After: %d (Right constraint '%s')\n",
|
||||||
|
x_delta, (*cp)->name);
|
||||||
|
|
||||||
++cp;
|
++cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,14 +925,22 @@ constrain_resize_top (MetaWindow *window,
|
|||||||
|
|
||||||
while (*cp)
|
while (*cp)
|
||||||
{
|
{
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Before: %d (Top constraint '%s')\n",
|
||||||
|
y_delta, (*cp)->name);
|
||||||
|
|
||||||
if ((* (*cp)->applies_func) (window))
|
if ((* (*cp)->applies_func) (window))
|
||||||
(* (*cp)->top_func) (window, info, orig,
|
(* (*cp)->top_func) (window, info, orig,
|
||||||
&y_delta);
|
&y_delta);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"After: %d (Top constraint '%s')\n",
|
||||||
|
y_delta, (*cp)->name);
|
||||||
|
|
||||||
++cp;
|
++cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->y = orig->y - y_delta;
|
new->y = orig->y + y_delta;
|
||||||
new->height = orig->height - y_delta;
|
new->height = orig->height - y_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,10 +957,18 @@ constrain_resize_vcenter (MetaWindow *window,
|
|||||||
|
|
||||||
while (*cp)
|
while (*cp)
|
||||||
{
|
{
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Before: %d (VCenter constraint '%s')\n",
|
||||||
|
y_delta, (*cp)->name);
|
||||||
|
|
||||||
if ((* (*cp)->applies_func) (window))
|
if ((* (*cp)->applies_func) (window))
|
||||||
(* (*cp)->vcenter_func) (window, info, orig,
|
(* (*cp)->vcenter_func) (window, info, orig,
|
||||||
&y_delta);
|
&y_delta);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"After: %d (VCenter constraint '%s')\n",
|
||||||
|
y_delta, (*cp)->name);
|
||||||
|
|
||||||
++cp;
|
++cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,6 +977,9 @@ constrain_resize_vcenter (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
new->y = orig->y - y_delta;
|
new->y = orig->y - y_delta;
|
||||||
new->height = orig->height + y_delta * 2;
|
new->height = orig->height + y_delta * 2;
|
||||||
|
/* FIXME above implies that with center gravity you have to grow
|
||||||
|
* in increments of two
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -770,14 +995,22 @@ constrain_resize_bottom (MetaWindow *window,
|
|||||||
|
|
||||||
while (*cp)
|
while (*cp)
|
||||||
{
|
{
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Before: %d (Bottom constraint '%s')\n",
|
||||||
|
y_delta, (*cp)->name);
|
||||||
|
|
||||||
if ((* (*cp)->applies_func) (window))
|
if ((* (*cp)->applies_func) (window))
|
||||||
(* (*cp)->bottom_func) (window, info, orig,
|
(* (*cp)->bottom_func) (window, info, orig,
|
||||||
&y_delta);
|
&y_delta);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"After: %d (Bottom constraint '%s')\n",
|
||||||
|
y_delta, (*cp)->name);
|
||||||
|
|
||||||
++cp;
|
++cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->height = orig->y + y_delta;
|
new->height = orig->height + y_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -786,7 +1019,6 @@ update_position_limits (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
int nw_x, nw_y;
|
int nw_x, nw_y;
|
||||||
int se_x, se_y;
|
int se_x, se_y;
|
||||||
int offscreen_w, offscreen_h;
|
|
||||||
|
|
||||||
nw_x = info->work_area_screen.x;
|
nw_x = info->work_area_screen.x;
|
||||||
nw_y = info->work_area_screen.y;
|
nw_y = info->work_area_screen.y;
|
||||||
@ -841,6 +1073,15 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
ConstraintInfo info;
|
ConstraintInfo info;
|
||||||
MetaRectangle current;
|
MetaRectangle current;
|
||||||
|
|
||||||
|
#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,
|
||||||
|
x_direction, y_direction, x_delta, y_delta,
|
||||||
|
orig->x, orig->y, orig->width, orig->height);
|
||||||
|
|
||||||
/* Create a fake frame geometry if none really exists */
|
/* Create a fake frame geometry if none really exists */
|
||||||
if (orig_fgeom && !window->fullscreen)
|
if (orig_fgeom && !window->fullscreen)
|
||||||
info.fgeom = *orig_fgeom;
|
info.fgeom = *orig_fgeom;
|
||||||
@ -852,8 +1093,8 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
info.fgeom.right_width = 0;
|
info.fgeom.right_width = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_window_get_work_area (window, TRUE, &info.work_area_xinerama);
|
meta_window_get_work_area_current_xinerama (window, &info.work_area_xinerama);
|
||||||
meta_window_get_work_area (window, FALSE, &info.work_area_screen);
|
meta_window_get_work_area_all_xineramas (window, &info.work_area_screen);
|
||||||
|
|
||||||
info.window = window;
|
info.window = window;
|
||||||
info.xinerama = meta_screen_get_xinerama_for_window (window->screen,
|
info.xinerama = meta_screen_get_xinerama_for_window (window->screen,
|
||||||
@ -877,12 +1118,18 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
meta_window_place (window, orig_fgeom, x, y, &x, &y);
|
meta_window_place (window, orig_fgeom, current.x, current.y,
|
||||||
|
&x, &y);
|
||||||
|
|
||||||
constrain_move (window, &info, ¤t,
|
constrain_move (window, &info, ¤t,
|
||||||
x - current.x,
|
x - current.x,
|
||||||
y - current.y,
|
y - current.y,
|
||||||
new);
|
new);
|
||||||
|
current = *new;
|
||||||
|
|
||||||
|
/* Ignore any non-placement movement */
|
||||||
|
x_move_delta = 0;
|
||||||
|
y_move_delta = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Maximization, fullscreen, etc. are defined as a move followed by
|
/* Maximization, fullscreen, etc. are defined as a move followed by
|
||||||
@ -891,41 +1138,53 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
if (window->fullscreen)
|
if (window->fullscreen)
|
||||||
{
|
{
|
||||||
|
int center_x;
|
||||||
|
|
||||||
|
center_x = info.xinerama->x_origin + (info.xinerama->width / 2);
|
||||||
|
center_x -= OUTER_WIDTH (current) / 2;
|
||||||
|
|
||||||
constrain_move (window, &info, ¤t,
|
constrain_move (window, &info, ¤t,
|
||||||
info.xinerama->x_origin - current.x,
|
center_x - current.x,
|
||||||
info.xinerama->y_origin - current.y,
|
info.xinerama->y_origin - current.y + info.fgeom.top_height,
|
||||||
new);
|
new);
|
||||||
|
|
||||||
current = *new;
|
current = *new;
|
||||||
|
|
||||||
constrain_resize_bottom (window, &info, ¤t,
|
constrain_resize_bottom (window, &info, ¤t,
|
||||||
info.xinerama->height - current.height,
|
(info.xinerama->height - OUTER_HEIGHT (current)),
|
||||||
new);
|
new);
|
||||||
|
|
||||||
current = *new;
|
current = *new;
|
||||||
|
|
||||||
constrain_resize_hcenter (window, &info, ¤t,
|
constrain_resize_hcenter (window, &info, ¤t,
|
||||||
(info.xinerama->width - current.width) / 2,
|
(info.xinerama->width - OUTER_WIDTH (current)) / 2,
|
||||||
new);
|
new);
|
||||||
|
current = *new;
|
||||||
}
|
}
|
||||||
else if (window->maximized)
|
else if (window->maximized)
|
||||||
{
|
{
|
||||||
|
int center_x;
|
||||||
|
|
||||||
|
center_x = info.work_area_xinerama.x + (info.work_area_xinerama.width / 2);
|
||||||
|
center_x -= OUTER_WIDTH (current) / 2;
|
||||||
|
|
||||||
constrain_move (window, &info, ¤t,
|
constrain_move (window, &info, ¤t,
|
||||||
info.work_area_xinerama.x - current.x,
|
center_x - current.x,
|
||||||
info.work_area_xinerama.y - current.y,
|
info.work_area_xinerama.y - current.y + info.fgeom.top_height,
|
||||||
new);
|
new);
|
||||||
|
|
||||||
current = *new;
|
current = *new;
|
||||||
|
|
||||||
constrain_resize_bottom (window, &info, ¤t,
|
constrain_resize_bottom (window, &info, ¤t,
|
||||||
info.work_area_xinerama.height - current.height,
|
(info.work_area_xinerama.height - OUTER_HEIGHT (current)),
|
||||||
new);
|
new);
|
||||||
|
|
||||||
current = *new;
|
current = *new;
|
||||||
|
|
||||||
constrain_resize_hcenter (window, &info, ¤t,
|
constrain_resize_hcenter (window, &info, ¤t,
|
||||||
(info.work_area_xinerama.width - current.width) / 2,
|
(info.work_area_xinerama.width - OUTER_WIDTH (current)) / 2,
|
||||||
new);
|
new);
|
||||||
|
current = *new;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -966,12 +1225,12 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
y_delta, new);
|
y_delta, new);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
current = *new;
|
current = *new;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Now we have to sort out the aspect ratio */
|
/* Now we have to sort out the aspect ratio */
|
||||||
#define FLOOR(value, base) ( ((int) ((value) / (base))) * (base) )
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* width
|
* width
|
||||||
@ -990,7 +1249,9 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
/* Use the standard cut-and-pasted-between-every-WM code: */
|
/* Use the standard cut-and-pasted-between-every-WM code: */
|
||||||
if (min_aspect * height > width)
|
if (min_aspect * height > width)
|
||||||
{
|
{
|
||||||
delta = FLOOR (height - width * min_aspect, window->size_hints.height_inc);
|
int delta;
|
||||||
|
|
||||||
|
delta = FLOOR (height - width / min_aspect, window->size_hints.height_inc);
|
||||||
if (height - delta >= window->size_hints.min_height)
|
if (height - delta >= window->size_hints.min_height)
|
||||||
height -= delta;
|
height -= delta;
|
||||||
else
|
else
|
||||||
@ -1003,6 +1264,8 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
|
|
||||||
if (max_aspect * height < width)
|
if (max_aspect * height < width)
|
||||||
{
|
{
|
||||||
|
int delta;
|
||||||
|
|
||||||
delta = FLOOR (width - height * max_aspect, window->size_hints.width_inc);
|
delta = FLOOR (width - height * max_aspect, window->size_hints.width_inc);
|
||||||
if (width - delta >= window->size_hints.min_width)
|
if (width - delta >= window->size_hints.min_width)
|
||||||
width -= delta;
|
width -= delta;
|
||||||
@ -1060,9 +1323,21 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#undef FLOOR
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
new->x, new->y, new->width, new->height,
|
||||||
|
orig->x, orig->y, orig->width, orig->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaResizeDirection
|
MetaResizeDirection
|
||||||
|
653
src/window.c
653
src/window.c
@ -38,6 +38,7 @@
|
|||||||
#include "xprops.h"
|
#include "xprops.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "window-props.h"
|
#include "window-props.h"
|
||||||
|
#include "constraints.h"
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -65,18 +66,6 @@ typedef enum
|
|||||||
|
|
||||||
static int destroying_windows_disallowed = 0;
|
static int destroying_windows_disallowed = 0;
|
||||||
|
|
||||||
static void constrain_size (MetaWindow *window,
|
|
||||||
MetaFrameGeometry *fgeom,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int *new_width,
|
|
||||||
int *new_height);
|
|
||||||
static void constrain_position (MetaWindow *window,
|
|
||||||
MetaFrameGeometry *fgeom,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int *new_x,
|
|
||||||
int *new_y);
|
|
||||||
|
|
||||||
static void update_net_wm_state (MetaWindow *window);
|
static void update_net_wm_state (MetaWindow *window);
|
||||||
static void update_mwm_hints (MetaWindow *window);
|
static void update_mwm_hints (MetaWindow *window);
|
||||||
@ -103,14 +92,6 @@ static GList* meta_window_get_workspaces (MetaWindow *window);
|
|||||||
|
|
||||||
static void meta_window_save_rect (MetaWindow *window);
|
static void meta_window_save_rect (MetaWindow *window);
|
||||||
|
|
||||||
static void adjust_for_gravity (MetaWindow *window,
|
|
||||||
MetaFrameGeometry *fgeom,
|
|
||||||
gboolean coords_assume_border,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int *xp,
|
|
||||||
int *yp);
|
|
||||||
|
|
||||||
static void meta_window_move_resize_internal (MetaWindow *window,
|
static void meta_window_move_resize_internal (MetaWindow *window,
|
||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
int resize_gravity,
|
int resize_gravity,
|
||||||
@ -2012,13 +1993,17 @@ meta_window_activate (MetaWindow *window,
|
|||||||
meta_window_focus (window, timestamp);
|
meta_window_focus (window, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns values suitable for meta_window_move */
|
/* returns values suitable for meta_window_move
|
||||||
|
* i.e. static gravity
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
adjust_for_gravity (MetaWindow *window,
|
adjust_for_gravity (MetaWindow *window,
|
||||||
MetaFrameGeometry *fgeom,
|
MetaFrameGeometry *fgeom,
|
||||||
gboolean coords_assume_border,
|
gboolean coords_assume_border,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
int *xp,
|
int *xp,
|
||||||
int *yp)
|
int *yp)
|
||||||
{
|
{
|
||||||
@ -2036,15 +2021,15 @@ adjust_for_gravity (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
child_x = fgeom->left_width;
|
child_x = fgeom->left_width;
|
||||||
child_y = fgeom->top_height;
|
child_y = fgeom->top_height;
|
||||||
frame_width = child_x + window->rect.width + fgeom->right_width;
|
frame_width = child_x + width + fgeom->right_width;
|
||||||
frame_height = child_y + window->rect.height + fgeom->bottom_height;
|
frame_height = child_y + height + fgeom->bottom_height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
child_x = 0;
|
child_x = 0;
|
||||||
child_y = 0;
|
child_y = 0;
|
||||||
frame_width = window->rect.width;
|
frame_width = width;
|
||||||
frame_height = window->rect.height;
|
frame_height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're computing position to pass to window_move, which is
|
/* We're computing position to pass to window_move, which is
|
||||||
@ -2061,36 +2046,36 @@ adjust_for_gravity (MetaWindow *window,
|
|||||||
ref_y = y;
|
ref_y = y;
|
||||||
break;
|
break;
|
||||||
case NorthGravity:
|
case NorthGravity:
|
||||||
ref_x = x + window->rect.width / 2 + bw;
|
ref_x = x + width / 2 + bw;
|
||||||
ref_y = y;
|
ref_y = y;
|
||||||
break;
|
break;
|
||||||
case NorthEastGravity:
|
case NorthEastGravity:
|
||||||
ref_x = x + window->rect.width + bw * 2;
|
ref_x = x + width + bw * 2;
|
||||||
ref_y = y;
|
ref_y = y;
|
||||||
break;
|
break;
|
||||||
case WestGravity:
|
case WestGravity:
|
||||||
ref_x = x;
|
ref_x = x;
|
||||||
ref_y = y + window->rect.height / 2 + bw;
|
ref_y = y + height / 2 + bw;
|
||||||
break;
|
break;
|
||||||
case CenterGravity:
|
case CenterGravity:
|
||||||
ref_x = x + window->rect.width / 2 + bw;
|
ref_x = x + width / 2 + bw;
|
||||||
ref_y = y + window->rect.height / 2 + bw;
|
ref_y = y + height / 2 + bw;
|
||||||
break;
|
break;
|
||||||
case EastGravity:
|
case EastGravity:
|
||||||
ref_x = x + window->rect.width + bw * 2;
|
ref_x = x + width + bw * 2;
|
||||||
ref_y = y + window->rect.height / 2 + bw;
|
ref_y = y + height / 2 + bw;
|
||||||
break;
|
break;
|
||||||
case SouthWestGravity:
|
case SouthWestGravity:
|
||||||
ref_x = x;
|
ref_x = x;
|
||||||
ref_y = y + window->rect.height + bw * 2;
|
ref_y = y + height + bw * 2;
|
||||||
break;
|
break;
|
||||||
case SouthGravity:
|
case SouthGravity:
|
||||||
ref_x = x + window->rect.width / 2 + bw;
|
ref_x = x + width / 2 + bw;
|
||||||
ref_y = y + window->rect.height + bw * 2;
|
ref_y = y + height + bw * 2;
|
||||||
break;
|
break;
|
||||||
case SouthEastGravity:
|
case SouthEastGravity:
|
||||||
ref_x = x + window->rect.width + bw * 2;
|
ref_x = x + width + bw * 2;
|
||||||
ref_y = y + window->rect.height + bw * 2;
|
ref_y = y + height + bw * 2;
|
||||||
break;
|
break;
|
||||||
case StaticGravity:
|
case StaticGravity:
|
||||||
default:
|
default:
|
||||||
@ -2151,6 +2136,47 @@ static_gravity_works (MetaDisplay *display)
|
|||||||
return display->static_gravity_works;
|
return display->static_gravity_works;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_mouse_deltas_for_resize (MetaWindow *window,
|
||||||
|
int resize_gravity,
|
||||||
|
int w,
|
||||||
|
int h,
|
||||||
|
int *x_delta,
|
||||||
|
int *y_delta)
|
||||||
|
{
|
||||||
|
switch (meta_x_direction_from_gravity (resize_gravity))
|
||||||
|
{
|
||||||
|
case META_RESIZE_LEFT_OR_TOP:
|
||||||
|
*x_delta = window->rect.width - w;
|
||||||
|
break;
|
||||||
|
case META_RESIZE_RIGHT_OR_BOTTOM:
|
||||||
|
*x_delta = w - window->rect.width;
|
||||||
|
break;
|
||||||
|
case META_RESIZE_CENTER:
|
||||||
|
/* FIXME this implies that with center gravity you have to grow
|
||||||
|
* in increments of two
|
||||||
|
*/
|
||||||
|
*x_delta = (w - window->rect.width) / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (meta_y_direction_from_gravity (resize_gravity))
|
||||||
|
{
|
||||||
|
case META_RESIZE_LEFT_OR_TOP:
|
||||||
|
*y_delta = window->rect.height - h;
|
||||||
|
break;
|
||||||
|
case META_RESIZE_RIGHT_OR_BOTTOM:
|
||||||
|
*y_delta = h - window->rect.height;
|
||||||
|
break;
|
||||||
|
case META_RESIZE_CENTER:
|
||||||
|
/* FIXME this implies that with center gravity you have to grow
|
||||||
|
* in increments of two
|
||||||
|
*/
|
||||||
|
*y_delta = (h - window->rect.height) / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_move_resize_internal (MetaWindow *window,
|
meta_window_move_resize_internal (MetaWindow *window,
|
||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
@ -2168,8 +2194,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
gboolean need_move_frame = FALSE;
|
gboolean need_move_frame = FALSE;
|
||||||
gboolean need_resize_client = FALSE;
|
gboolean need_resize_client = FALSE;
|
||||||
gboolean need_resize_frame = FALSE;
|
gboolean need_resize_frame = FALSE;
|
||||||
int size_dx;
|
|
||||||
int size_dy;
|
|
||||||
int frame_size_dx;
|
int frame_size_dx;
|
||||||
int frame_size_dy;
|
int frame_size_dy;
|
||||||
gboolean is_configure_request;
|
gboolean is_configure_request;
|
||||||
@ -2182,6 +2206,10 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
int client_move_x;
|
int client_move_x;
|
||||||
int client_move_y;
|
int client_move_y;
|
||||||
|
int x_delta;
|
||||||
|
int y_delta;
|
||||||
|
MetaRectangle new_rect;
|
||||||
|
MetaRectangle old_rect;
|
||||||
|
|
||||||
is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0;
|
is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0;
|
||||||
do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0;
|
do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0;
|
||||||
@ -2190,32 +2218,62 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
/* We don't need it in the idle queue anymore. */
|
/* We don't need it in the idle queue anymore. */
|
||||||
meta_window_unqueue_move_resize (window);
|
meta_window_unqueue_move_resize (window);
|
||||||
|
|
||||||
{
|
old_rect = window->rect;
|
||||||
int oldx, oldy;
|
meta_window_get_position (window, &old_rect.x, &old_rect.y);
|
||||||
meta_window_get_position (window, &oldx, &oldy);
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
"Move/resize %s to %d,%d %dx%d%s%s from %d,%d %dx%d\n",
|
"Move/resize %s to %d,%d %dx%d%s%s from %d,%d %dx%d\n",
|
||||||
window->desc, root_x_nw, root_y_nw, w, h,
|
window->desc, root_x_nw, root_y_nw, w, h,
|
||||||
is_configure_request ? " (configure request)" : "",
|
is_configure_request ? " (configure request)" : "",
|
||||||
is_user_action ? " (user move/resize)" : "",
|
is_user_action ? " (user move/resize)" : "",
|
||||||
oldx, oldy, window->rect.width, window->rect.height);
|
old_rect.x, old_rect.y, old_rect.width, old_rect.height);
|
||||||
}
|
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
meta_frame_calc_geometry (window->frame,
|
meta_frame_calc_geometry (window->frame,
|
||||||
&fgeom);
|
&fgeom);
|
||||||
|
|
||||||
constrain_size (window, &fgeom, w, h, &w, &h);
|
if (is_configure_request || do_gravity_adjust)
|
||||||
|
{
|
||||||
|
adjust_for_gravity (window,
|
||||||
|
window->frame ? &fgeom : NULL,
|
||||||
|
/* configure request coords assume
|
||||||
|
* the border width existed
|
||||||
|
*/
|
||||||
|
is_configure_request,
|
||||||
|
root_x_nw,
|
||||||
|
root_y_nw,
|
||||||
|
w, h,
|
||||||
|
&root_x_nw,
|
||||||
|
&root_y_nw);
|
||||||
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
"Constrained resize of %s to %d x %d\n", window->desc, w, h);
|
"Compensated position for gravity, new pos %d,%d\n",
|
||||||
|
root_x_nw, root_y_nw);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_mouse_deltas_for_resize (window, resize_gravity, w, h,
|
||||||
|
&x_delta, &y_delta);
|
||||||
|
|
||||||
|
meta_window_constrain (window,
|
||||||
|
&fgeom,
|
||||||
|
&old_rect,
|
||||||
|
root_x_nw - old_rect.x,
|
||||||
|
root_y_nw - old_rect.y,
|
||||||
|
meta_x_direction_from_gravity (resize_gravity),
|
||||||
|
x_delta,
|
||||||
|
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;
|
||||||
|
root_y_nw = new_rect.y;
|
||||||
|
|
||||||
if (w != window->rect.width ||
|
if (w != window->rect.width ||
|
||||||
h != window->rect.height)
|
h != window->rect.height)
|
||||||
need_resize_client = TRUE;
|
need_resize_client = TRUE;
|
||||||
|
|
||||||
size_dx = w - window->rect.width;
|
|
||||||
size_dy = h - window->rect.height;
|
|
||||||
|
|
||||||
window->rect.width = w;
|
window->rect.width = w;
|
||||||
window->rect.height = h;
|
window->rect.height = h;
|
||||||
|
|
||||||
@ -2249,73 +2307,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
frame_size_dy = 0;
|
frame_size_dy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_configure_request || do_gravity_adjust)
|
|
||||||
{
|
|
||||||
adjust_for_gravity (window,
|
|
||||||
window->frame ? &fgeom : NULL,
|
|
||||||
/* configure request coords assume
|
|
||||||
* the border width existed
|
|
||||||
*/
|
|
||||||
is_configure_request,
|
|
||||||
root_x_nw,
|
|
||||||
root_y_nw,
|
|
||||||
&root_x_nw,
|
|
||||||
&root_y_nw);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
|
||||||
"Compensated position for gravity, new pos %d,%d\n",
|
|
||||||
root_x_nw, root_y_nw);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* There can be somewhat bogus interactions between gravity
|
|
||||||
* and the position constraints (with position contraints
|
|
||||||
* basically breaking gravity). Not sure how to fix this.
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (resize_gravity)
|
|
||||||
{
|
|
||||||
/* If client is staying fixed on the east during resize, then we
|
|
||||||
* have to move the west edge.
|
|
||||||
*/
|
|
||||||
case NorthEastGravity:
|
|
||||||
case EastGravity:
|
|
||||||
case SouthEastGravity:
|
|
||||||
root_x_nw -= size_dx;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* centered horizontally */
|
|
||||||
case NorthGravity:
|
|
||||||
case SouthGravity:
|
|
||||||
case CenterGravity:
|
|
||||||
root_x_nw -= size_dx / 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (resize_gravity)
|
|
||||||
{
|
|
||||||
/* If client is staying fixed on the south during resize,
|
|
||||||
* we have to move the north edge
|
|
||||||
*/
|
|
||||||
case SouthGravity:
|
|
||||||
case SouthEastGravity:
|
|
||||||
case SouthWestGravity:
|
|
||||||
root_y_nw -= size_dy;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* centered vertically */
|
|
||||||
case EastGravity:
|
|
||||||
case WestGravity:
|
|
||||||
case CenterGravity:
|
|
||||||
root_y_nw -= size_dy / 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For nice effect, when growing the window we want to move/resize
|
/* For nice effect, when growing the window we want to move/resize
|
||||||
* the frame first, when shrinking the window we want to move/resize
|
* the frame first, when shrinking the window we want to move/resize
|
||||||
* the client first. If we grow one way and shrink the other,
|
* the client first. If we grow one way and shrink the other,
|
||||||
@ -2331,15 +2322,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
* enough to set CWX | CWWidth but pass in the current size/pos.
|
* enough to set CWX | CWWidth but pass in the current size/pos.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
constrain_position (window,
|
|
||||||
window->frame ? &fgeom : NULL,
|
|
||||||
root_x_nw, root_y_nw,
|
|
||||||
&root_x_nw, &root_y_nw);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
|
||||||
"Constrained position to %d,%d\n",
|
|
||||||
root_x_nw, root_y_nw);
|
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
int new_x, new_y;
|
int new_x, new_y;
|
||||||
@ -2473,6 +2455,9 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
if (use_static_gravity)
|
if (use_static_gravity)
|
||||||
{
|
{
|
||||||
|
int size_dx = w - window->rect.width;
|
||||||
|
int size_dy = h - window->rect.height;
|
||||||
|
|
||||||
if ((size_dx + size_dy) >= 0)
|
if ((size_dx + size_dy) >= 0)
|
||||||
configure_frame_first = FALSE;
|
configure_frame_first = FALSE;
|
||||||
else
|
else
|
||||||
@ -5386,360 +5371,6 @@ recalc_window_features (MetaWindow *window)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
constrain_size (MetaWindow *window,
|
|
||||||
MetaFrameGeometry *fgeom,
|
|
||||||
int width, int height,
|
|
||||||
int *new_width, int *new_height)
|
|
||||||
{
|
|
||||||
/* This is partially borrowed from GTK (LGPL), which in turn
|
|
||||||
* partially borrowed from fvwm,
|
|
||||||
*
|
|
||||||
* Copyright 1993, Robert Nation
|
|
||||||
* You may use this code for any purpose, as long as the original
|
|
||||||
* copyright remains in the source code and all documentation
|
|
||||||
*
|
|
||||||
* which in turn borrows parts of the algorithm from uwm
|
|
||||||
*/
|
|
||||||
int delta;
|
|
||||||
double min_aspect, max_aspect;
|
|
||||||
int minw, minh, maxw, maxh, fullw, fullh;
|
|
||||||
|
|
||||||
/* frame member variables should NEVER be used in here */
|
|
||||||
|
|
||||||
#define FLOOR(value, base) ( ((int) ((value) / (base))) * (base) )
|
|
||||||
|
|
||||||
/* Get the allowed size ranges, considering maximized, etc. */
|
|
||||||
if (window->fullscreen)
|
|
||||||
{
|
|
||||||
const MetaXineramaScreenInfo *xinerama;
|
|
||||||
|
|
||||||
xinerama = meta_screen_get_xinerama_for_window (window->screen,
|
|
||||||
window);
|
|
||||||
|
|
||||||
|
|
||||||
fullw = xinerama->width;
|
|
||||||
fullh = xinerama->height;
|
|
||||||
}
|
|
||||||
else if (window->type == META_WINDOW_DESKTOP ||
|
|
||||||
window->type == META_WINDOW_DOCK)
|
|
||||||
{
|
|
||||||
|
|
||||||
fullw = window->screen->width;
|
|
||||||
fullh = window->screen->height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MetaRectangle work_area;
|
|
||||||
|
|
||||||
meta_window_get_work_area_current_xinerama (window, &work_area);
|
|
||||||
|
|
||||||
fullw = work_area.width;
|
|
||||||
fullh = work_area.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->frame && !window->fullscreen)
|
|
||||||
{
|
|
||||||
fullw -= (fgeom->left_width + fgeom->right_width);
|
|
||||||
fullh -= (fgeom->top_height + fgeom->bottom_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
maxw = window->size_hints.max_width;
|
|
||||||
maxh = window->size_hints.max_height;
|
|
||||||
|
|
||||||
if (window->maximized || window->fullscreen)
|
|
||||||
{
|
|
||||||
maxw = MIN (maxw, fullw);
|
|
||||||
maxh = MIN (maxh, fullh);
|
|
||||||
}
|
|
||||||
|
|
||||||
minw = window->size_hints.min_width;
|
|
||||||
minh = window->size_hints.min_height;
|
|
||||||
|
|
||||||
/* Check that fullscreen doesn't go under app-specified min size, if
|
|
||||||
* so snap back to min size
|
|
||||||
*/
|
|
||||||
if (maxw < minw)
|
|
||||||
maxw = minw;
|
|
||||||
if (maxh < minh)
|
|
||||||
maxh = minh;
|
|
||||||
|
|
||||||
if (window->maximized || window->fullscreen)
|
|
||||||
{
|
|
||||||
minw = MAX (minw, fullw);
|
|
||||||
minh = MAX (minh, fullh);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check that fullscreen doesn't exceed max width hint,
|
|
||||||
* if so then snap back to max width hint
|
|
||||||
*/
|
|
||||||
if (minw > maxw)
|
|
||||||
minw = maxw;
|
|
||||||
if (minh > maxh)
|
|
||||||
minh = maxh;
|
|
||||||
|
|
||||||
/* clamp width and height to min and max values
|
|
||||||
*/
|
|
||||||
width = CLAMP (width, minw, maxw);
|
|
||||||
|
|
||||||
height = CLAMP (height, minh, maxh);
|
|
||||||
|
|
||||||
/* shrink to base + N * inc
|
|
||||||
*/
|
|
||||||
width = window->size_hints.base_width +
|
|
||||||
FLOOR (width - window->size_hints.base_width, window->size_hints.width_inc);
|
|
||||||
height = window->size_hints.base_height +
|
|
||||||
FLOOR (height - window->size_hints.base_height, window->size_hints.height_inc);
|
|
||||||
|
|
||||||
/* constrain aspect ratio, according to:
|
|
||||||
*
|
|
||||||
* width
|
|
||||||
* min_aspect <= -------- <= max_aspect
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
if (min_aspect * height > width)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef FLOOR
|
|
||||||
|
|
||||||
*new_width = width;
|
|
||||||
*new_height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
constrain_position (MetaWindow *window,
|
|
||||||
MetaFrameGeometry *fgeom,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int *new_x,
|
|
||||||
int *new_y)
|
|
||||||
{
|
|
||||||
/* frame member variables should NEVER be used in here, only
|
|
||||||
* MetaFrameGeometry
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!window->placed && window->calc_placement)
|
|
||||||
meta_window_place (window, fgeom, x, y, &x, &y);
|
|
||||||
|
|
||||||
if (window->type == META_WINDOW_DESKTOP)
|
|
||||||
{
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
else if (window->type == META_WINDOW_DOCK)
|
|
||||||
{
|
|
||||||
; /* let it do whatever */
|
|
||||||
}
|
|
||||||
else if (window->fullscreen)
|
|
||||||
{
|
|
||||||
const MetaXineramaScreenInfo *xinerama;
|
|
||||||
|
|
||||||
xinerama = meta_screen_get_xinerama_for_window (window->screen,
|
|
||||||
window);
|
|
||||||
|
|
||||||
x = xinerama->x_origin;
|
|
||||||
y = xinerama->y_origin;
|
|
||||||
|
|
||||||
/* If the window's geometry gridding (e.g. for a terminal)
|
|
||||||
* prevents fullscreen, center the window within
|
|
||||||
* the screen area.
|
|
||||||
*/
|
|
||||||
x += (xinerama->width - window->rect.width) / 2;
|
|
||||||
|
|
||||||
/* If the window is somehow larger than the screen be paranoid
|
|
||||||
* and fix the resulting negative coords
|
|
||||||
*/
|
|
||||||
if (x < xinerama->x_origin)
|
|
||||||
x = xinerama->x_origin;
|
|
||||||
}
|
|
||||||
else if (window->maximized)
|
|
||||||
{
|
|
||||||
const MetaXineramaScreenInfo* xsi;
|
|
||||||
MetaRectangle work_area;
|
|
||||||
|
|
||||||
xsi = meta_screen_get_xinerama_for_rect (window->screen,
|
|
||||||
&window->saved_rect);
|
|
||||||
|
|
||||||
meta_window_get_work_area_for_xinerama (window,
|
|
||||||
xsi->number,
|
|
||||||
&work_area);
|
|
||||||
|
|
||||||
x = work_area.x;
|
|
||||||
y = work_area.y;
|
|
||||||
if (window->frame)
|
|
||||||
{
|
|
||||||
x += fgeom->left_width;
|
|
||||||
y += fgeom->top_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the window's geometry gridding (e.g. for a terminal)
|
|
||||||
* prevents full maximization, center the window within
|
|
||||||
* the maximized area horizontally.
|
|
||||||
*/
|
|
||||||
x += (work_area.width - window->rect.width -
|
|
||||||
(window->frame ? (fgeom->left_width + fgeom->right_width) : 0)) / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int nw_x, nw_y;
|
|
||||||
int se_x, se_y;
|
|
||||||
int offscreen_w, offscreen_h;
|
|
||||||
MetaRectangle work_area;
|
|
||||||
MetaRectangle window_area;
|
|
||||||
const MetaXineramaScreenInfo* xsi;
|
|
||||||
|
|
||||||
/* this is the rect for the window if it were where we're moving
|
|
||||||
* it now
|
|
||||||
*/
|
|
||||||
meta_window_get_outer_rect (window, &window_area);
|
|
||||||
window_area.x = x;
|
|
||||||
window_area.y = y;
|
|
||||||
if (fgeom)
|
|
||||||
{
|
|
||||||
window_area.x -= fgeom->left_width;
|
|
||||||
window_area.y -= fgeom->top_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
xsi = meta_screen_get_xinerama_for_rect (window->screen, &window_area);
|
|
||||||
meta_window_get_work_area_for_xinerama (window,
|
|
||||||
xsi->number,
|
|
||||||
&work_area);
|
|
||||||
|
|
||||||
/* (FIXME instead of TITLEBAR_LENGTH_ONSCREEN, get the actual
|
|
||||||
* size of the menu control?).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define TITLEBAR_LENGTH_ONSCREEN 36
|
|
||||||
|
|
||||||
/* find furthest northwest point the window can occupy */
|
|
||||||
nw_x = work_area.x;
|
|
||||||
nw_y = work_area.y;
|
|
||||||
|
|
||||||
/* FIXME note this means framed windows can go off the left
|
|
||||||
* but not unframed windows.
|
|
||||||
*/
|
|
||||||
if (window->frame)
|
|
||||||
{
|
|
||||||
/* Must keep TITLEBAR_LENGTH_ONSCREEN onscreen when moving left */
|
|
||||||
nw_x -= fgeom->left_width + window->rect.width + fgeom->right_width - TITLEBAR_LENGTH_ONSCREEN;
|
|
||||||
/* Can't move off the top */
|
|
||||||
nw_y += fgeom->top_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find bottom-right corner of workarea */
|
|
||||||
se_x = work_area.x + work_area.width;
|
|
||||||
se_y = work_area.y + work_area.height;
|
|
||||||
|
|
||||||
/* if the window's size exceeds the screen size,
|
|
||||||
* we allow it to go off the top/left far enough
|
|
||||||
* to get the right/bottom edges onscreen.
|
|
||||||
*/
|
|
||||||
offscreen_w = nw_x + window->rect.width;
|
|
||||||
offscreen_h = nw_y + window->rect.height;
|
|
||||||
if (window->frame)
|
|
||||||
{
|
|
||||||
offscreen_w += fgeom->right_width;
|
|
||||||
offscreen_h += fgeom->bottom_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
offscreen_w = offscreen_w - se_x;
|
|
||||||
offscreen_h = offscreen_h - se_y;
|
|
||||||
|
|
||||||
/* Now change NW limit to reflect amount offscreen in SE direction */
|
|
||||||
if (offscreen_w > 0)
|
|
||||||
nw_x -= offscreen_w;
|
|
||||||
|
|
||||||
/* do it for top of window for undecorated windows,
|
|
||||||
* since losing the titlebar isn't really an issue anyway,
|
|
||||||
* and it fixes fullscreen mode for stuff like Xine.
|
|
||||||
* but don't lose the titlebar on decorated windows.
|
|
||||||
*/
|
|
||||||
if (!window->decorated && offscreen_h > 0)
|
|
||||||
nw_y -= offscreen_h;
|
|
||||||
|
|
||||||
/* Limit movement off the right/bottom.
|
|
||||||
* Remember, we're constraining StaticGravity position.
|
|
||||||
*/
|
|
||||||
if (window->frame)
|
|
||||||
{
|
|
||||||
se_x -= TITLEBAR_LENGTH_ONSCREEN;
|
|
||||||
se_y -= 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* for frameless windows, just require an arbitrary little
|
|
||||||
* chunk to be onscreen
|
|
||||||
*/
|
|
||||||
se_x -= TITLEBAR_LENGTH_ONSCREEN;
|
|
||||||
se_y -= TITLEBAR_LENGTH_ONSCREEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we have a micro-screen or huge frames maybe nw/se got
|
|
||||||
* swapped
|
|
||||||
*/
|
|
||||||
if (nw_x > se_x)
|
|
||||||
{
|
|
||||||
int tmp = nw_x;
|
|
||||||
nw_x = se_x;
|
|
||||||
se_x = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nw_y > se_y)
|
|
||||||
{
|
|
||||||
int tmp = nw_y;
|
|
||||||
nw_y = se_y;
|
|
||||||
se_y = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clamp window to the given positions.
|
|
||||||
* Do the SE clamp first, so that the NW clamp has precedence
|
|
||||||
* and we don't tend to lose the titlebar for too-large
|
|
||||||
* windows.
|
|
||||||
*/
|
|
||||||
if (x > se_x)
|
|
||||||
x = se_x;
|
|
||||||
if (y > se_y)
|
|
||||||
y = se_y;
|
|
||||||
|
|
||||||
if (x < nw_x)
|
|
||||||
x = nw_x;
|
|
||||||
if (y < nw_y)
|
|
||||||
y = nw_y;
|
|
||||||
|
|
||||||
#undef TITLEBAR_LENGTH_ONSCREEN
|
|
||||||
}
|
|
||||||
|
|
||||||
*new_x = x;
|
|
||||||
*new_y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
menu_callback (MetaWindowMenu *menu,
|
menu_callback (MetaWindowMenu *menu,
|
||||||
Display *xdisplay,
|
Display *xdisplay,
|
||||||
@ -6350,7 +5981,7 @@ meta_window_set_gravity (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_work_area (MetaWindow *window,
|
get_work_area_xinerama (MetaWindow *window,
|
||||||
MetaRectangle *area,
|
MetaRectangle *area,
|
||||||
int which_xinerama)
|
int which_xinerama)
|
||||||
{
|
{
|
||||||
@ -6403,8 +6034,9 @@ get_work_area (MetaWindow *window,
|
|||||||
area->height = xinerama_height - top_strut - bottom_strut;
|
area->height = xinerama_height - top_strut - bottom_strut;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Window %s has work area %d,%d %d x %d\n",
|
"Window %s xinerama %d has work area %d,%d %d x %d\n",
|
||||||
window->desc, area->x, area->y, area->width, area->height);
|
window->desc, which_xinerama,
|
||||||
|
area->x, area->y, area->width, area->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -6427,11 +6059,66 @@ meta_window_get_work_area_for_xinerama (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (which_xinerama >= 0);
|
g_return_if_fail (which_xinerama >= 0);
|
||||||
|
|
||||||
get_work_area (window,
|
get_work_area_xinerama (window,
|
||||||
area,
|
area,
|
||||||
which_xinerama);
|
which_xinerama);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_get_work_area_all_xineramas (MetaWindow *window,
|
||||||
|
MetaRectangle *area)
|
||||||
|
{
|
||||||
|
MetaRectangle space_area;
|
||||||
|
GList *tmp;
|
||||||
|
int left_strut;
|
||||||
|
int right_strut;
|
||||||
|
int top_strut;
|
||||||
|
int bottom_strut;
|
||||||
|
int screen_origin_x;
|
||||||
|
int screen_origin_y;
|
||||||
|
int screen_width;
|
||||||
|
int screen_height;
|
||||||
|
|
||||||
|
screen_origin_x = 0;
|
||||||
|
screen_origin_y = 0;
|
||||||
|
screen_width = window->screen->width;
|
||||||
|
screen_height = window->screen->height;
|
||||||
|
|
||||||
|
left_strut = 0;
|
||||||
|
right_strut = 0;
|
||||||
|
top_strut = 0;
|
||||||
|
bottom_strut = 0;
|
||||||
|
|
||||||
|
tmp = meta_window_get_workspaces (window);
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
meta_workspace_get_work_area_all_xineramas (tmp->data,
|
||||||
|
&space_area);
|
||||||
|
|
||||||
|
left_strut = MAX (left_strut, space_area.x - screen_origin_x);
|
||||||
|
right_strut = MAX (right_strut,
|
||||||
|
(screen_width -
|
||||||
|
(space_area.x - screen_origin_x) -
|
||||||
|
space_area.width));
|
||||||
|
top_strut = MAX (top_strut, space_area.y - screen_origin_y);
|
||||||
|
bottom_strut = MAX (bottom_strut,
|
||||||
|
(screen_height -
|
||||||
|
(space_area.y - screen_origin_y) -
|
||||||
|
space_area.height));
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
area->x = screen_origin_x + left_strut;
|
||||||
|
area->y = screen_origin_y + top_strut;
|
||||||
|
area->width = screen_width - left_strut - right_strut;
|
||||||
|
area->height = screen_height - top_strut - bottom_strut;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
|
"Window %s has whole-screen work area %d,%d %d x %d\n",
|
||||||
|
window->desc, area->x, area->y, area->width, area->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_window_same_application (MetaWindow *window,
|
meta_window_same_application (MetaWindow *window,
|
||||||
MetaWindow *other_window)
|
MetaWindow *other_window)
|
||||||
|
@ -424,6 +424,8 @@ void meta_window_get_work_area_current_xinerama (MetaWindow *window,
|
|||||||
void meta_window_get_work_area_for_xinerama (MetaWindow *window,
|
void meta_window_get_work_area_for_xinerama (MetaWindow *window,
|
||||||
int which_xinerama,
|
int which_xinerama,
|
||||||
MetaRectangle *area);
|
MetaRectangle *area);
|
||||||
|
void meta_window_get_work_area_all_xineramas (MetaWindow *window,
|
||||||
|
MetaRectangle *area);
|
||||||
|
|
||||||
|
|
||||||
gboolean meta_window_same_application (MetaWindow *window,
|
gboolean meta_window_same_application (MetaWindow *window,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
int gravities[10] = {
|
int gravities[10] = {
|
||||||
NorthWestGravity,
|
NorthWestGravity,
|
||||||
@ -15,17 +16,68 @@ int gravities[10] = {
|
|||||||
StaticGravity
|
StaticGravity
|
||||||
};
|
};
|
||||||
|
|
||||||
Window windows[10];
|
typedef struct
|
||||||
|
{
|
||||||
|
int x, y, width, height;
|
||||||
|
} Rectangle;
|
||||||
|
|
||||||
int x_offset[3] = { 0, -50, -100 };
|
Window windows[10];
|
||||||
int y_offset[3] = { 0, -50, -100 };
|
int doubled[10] = { 0, };
|
||||||
|
Rectangle window_rects[10];
|
||||||
|
|
||||||
|
#define WINDOW_WIDTH 100
|
||||||
|
#define WINDOW_HEIGHT 100
|
||||||
|
|
||||||
|
int x_offset[3] = { 0, - WINDOW_WIDTH/2, -WINDOW_WIDTH };
|
||||||
|
int y_offset[3] = { 0, - WINDOW_HEIGHT/2, -WINDOW_HEIGHT };
|
||||||
double screen_x_fraction[3] = { 0, 0.5, 1.0 };
|
double screen_x_fraction[3] = { 0, 0.5, 1.0 };
|
||||||
double screen_y_fraction[3] = { 0, 0.5, 1.0 };
|
double screen_y_fraction[3] = { 0, 0.5, 1.0 };
|
||||||
int screen_width;
|
int screen_width;
|
||||||
int screen_height;
|
int screen_height;
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
window_gravity_to_string (int gravity)
|
||||||
|
{
|
||||||
|
switch (gravity)
|
||||||
|
{
|
||||||
|
case NorthWestGravity:
|
||||||
|
return "NorthWestGravity";
|
||||||
|
break;
|
||||||
|
case NorthGravity:
|
||||||
|
return "NorthGravity";
|
||||||
|
break;
|
||||||
|
case NorthEastGravity:
|
||||||
|
return "NorthEastGravity";
|
||||||
|
break;
|
||||||
|
case WestGravity:
|
||||||
|
return "WestGravity";
|
||||||
|
break;
|
||||||
|
case CenterGravity:
|
||||||
|
return "CenterGravity";
|
||||||
|
break;
|
||||||
|
case EastGravity:
|
||||||
|
return "EastGravity";
|
||||||
|
break;
|
||||||
|
case SouthWestGravity:
|
||||||
|
return "SouthWestGravity";
|
||||||
|
break;
|
||||||
|
case SouthGravity:
|
||||||
|
return "SouthGravity";
|
||||||
|
break;
|
||||||
|
case SouthEastGravity:
|
||||||
|
return "SouthEastGravity";
|
||||||
|
break;
|
||||||
|
case StaticGravity:
|
||||||
|
return "StaticGravity";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "NorthWestGravity";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calculate_position (int i, int *x, int *y)
|
calculate_position (int i, int doubled, int *x, int *y)
|
||||||
{
|
{
|
||||||
if (i == 9)
|
if (i == 9)
|
||||||
{
|
{
|
||||||
@ -34,9 +86,30 @@ calculate_position (int i, int *x, int *y)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*x = screen_x_fraction[i % 3] * screen_width + x_offset[i % 3];
|
int xoff = x_offset[i % 3];
|
||||||
*y = screen_y_fraction[i / 3] * screen_height + y_offset[i / 3];
|
int yoff = y_offset[i / 3];
|
||||||
|
if (doubled)
|
||||||
|
{
|
||||||
|
xoff *= 2;
|
||||||
|
yoff *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*x = screen_x_fraction[i % 3] * screen_width + xoff;
|
||||||
|
*y = screen_y_fraction[i / 3] * screen_height + yoff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
find_window (Window window)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<10; i++)
|
||||||
|
{
|
||||||
|
if (windows[i] == window)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
@ -58,25 +131,42 @@ int main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
calculate_position (i, &x, &y);
|
calculate_position (i, doubled[i], &x, &y);
|
||||||
|
|
||||||
w = XCreateSimpleWindow (d, RootWindow (d, screen),
|
w = XCreateSimpleWindow (d, RootWindow (d, screen),
|
||||||
x, y, 100, 100, 0,
|
x, y, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
|
||||||
WhitePixel (d, screen), WhitePixel (d, screen));
|
WhitePixel (d, screen), WhitePixel (d, screen));
|
||||||
|
|
||||||
windows[i] = w;
|
windows[i] = w;
|
||||||
|
window_rects[i].x = x;
|
||||||
|
window_rects[i].y = y;
|
||||||
|
window_rects[i].width = WINDOW_WIDTH;
|
||||||
|
window_rects[i].height = WINDOW_HEIGHT;
|
||||||
|
|
||||||
XSelectInput (d, w, ButtonPressMask);
|
XSelectInput (d, w, ButtonPressMask | ExposureMask | StructureNotifyMask);
|
||||||
|
|
||||||
hints.flags = USPosition | PMinSize | PMaxSize | PWinGravity;
|
hints.flags = USPosition | PMinSize | PMaxSize | PWinGravity;
|
||||||
|
|
||||||
hints.min_width = 100;
|
hints.min_width = WINDOW_WIDTH / 2;
|
||||||
hints.min_height = 100;
|
hints.min_height = WINDOW_HEIGHT / 2;
|
||||||
hints.max_width = 200;
|
|
||||||
hints.max_height = 200;
|
#if 1
|
||||||
|
/* we constrain max size below the "doubled" size so that
|
||||||
|
* the WM will have to deal with constraints
|
||||||
|
* at the same time it's dealing with configure request
|
||||||
|
*/
|
||||||
|
hints.max_width = WINDOW_WIDTH * 2 - WINDOW_WIDTH / 2;
|
||||||
|
hints.max_height = WINDOW_HEIGHT * 2 - WINDOW_HEIGHT / 2;
|
||||||
|
#else
|
||||||
|
hints.max_width = WINDOW_WIDTH * 2 + WINDOW_WIDTH / 2;
|
||||||
|
hints.max_height = WINDOW_HEIGHT * 2 + WINDOW_HEIGHT / 2;
|
||||||
|
#endif
|
||||||
hints.win_gravity = gravities[i];
|
hints.win_gravity = gravities[i];
|
||||||
|
|
||||||
XSetWMNormalHints (d, w, &hints);
|
XSetWMNormalHints (d, w, &hints);
|
||||||
|
|
||||||
|
XStoreName (d, w, window_gravity_to_string (hints.win_gravity));
|
||||||
|
|
||||||
XMapWindow (d, w);
|
XMapWindow (d, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,23 +174,104 @@ int main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
XNextEvent (d, &ev);
|
XNextEvent (d, &ev);
|
||||||
|
|
||||||
if (ev.xany.type == ButtonPress)
|
if (ev.xany.type == ConfigureNotify)
|
||||||
{
|
{
|
||||||
for (i=0; i<10; i++)
|
i = find_window (ev.xconfigure.window);
|
||||||
|
|
||||||
|
if (i >= 0)
|
||||||
{
|
{
|
||||||
if (windows[i] == ev.xbutton.window)
|
Window ignored;
|
||||||
|
|
||||||
|
window_rects[i].width = ev.xconfigure.width;
|
||||||
|
window_rects[i].height = ev.xconfigure.height;
|
||||||
|
|
||||||
|
XClearArea (d, windows[i], 0, 0,
|
||||||
|
ev.xconfigure.width,
|
||||||
|
ev.xconfigure.height,
|
||||||
|
True);
|
||||||
|
|
||||||
|
if (!ev.xconfigure.send_event)
|
||||||
|
XTranslateCoordinates (d, windows[i], DefaultRootWindow (d),
|
||||||
|
0, 0,
|
||||||
|
&window_rects[i].x, &window_rects[i].y,
|
||||||
|
&ignored);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
|
window_rects[i].x = ev.xconfigure.x;
|
||||||
|
window_rects[i].y = ev.xconfigure.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ev.xany.type == Expose)
|
||||||
|
{
|
||||||
|
i = find_window (ev.xexpose.window);
|
||||||
|
|
||||||
|
if (i >= 0)
|
||||||
|
{
|
||||||
|
GC gc;
|
||||||
|
XGCValues values;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
values.foreground = BlackPixel (d, screen);
|
||||||
|
|
||||||
|
gc = XCreateGC (d, windows[i],
|
||||||
|
GCForeground, &values);
|
||||||
|
|
||||||
|
sprintf (buf,
|
||||||
|
"%d,%d",
|
||||||
|
window_rects[i].x,
|
||||||
|
window_rects[i].y);
|
||||||
|
|
||||||
|
XDrawString (d, windows[i], gc, 10, 15,
|
||||||
|
buf, strlen (buf));
|
||||||
|
|
||||||
|
sprintf (buf,
|
||||||
|
"%dx%d",
|
||||||
|
window_rects[i].width,
|
||||||
|
window_rects[i].height);
|
||||||
|
|
||||||
|
XDrawString (d, windows[i], gc, 10, 35,
|
||||||
|
buf, strlen (buf));
|
||||||
|
|
||||||
|
XFreeGC (d, gc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ev.xany.type == ButtonPress)
|
||||||
|
{
|
||||||
|
i = find_window (ev.xbutton.window);
|
||||||
|
|
||||||
|
if (i >= 0)
|
||||||
|
{
|
||||||
|
/* Button 1 = move, 2 = resize, 3 = both at once */
|
||||||
|
|
||||||
if (ev.xbutton.button == Button1)
|
if (ev.xbutton.button == Button1)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
calculate_position (i, &x, &y);
|
calculate_position (i, doubled[i], &x, &y);
|
||||||
w = XMoveWindow (d, windows[i], x, y);
|
XMoveWindow (d, windows[i], x, y);
|
||||||
}
|
}
|
||||||
else
|
else if (ev.xbutton.button == Button2)
|
||||||
{
|
{
|
||||||
w = XResizeWindow (d, windows[i], 200, 200);
|
if (doubled[i])
|
||||||
|
XResizeWindow (d, windows[i], WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
else
|
||||||
|
XResizeWindow (d, windows[i], WINDOW_WIDTH*2, WINDOW_HEIGHT*2);
|
||||||
|
|
||||||
|
doubled[i] = !doubled[i];
|
||||||
}
|
}
|
||||||
|
else if (ev.xbutton.button == Button3)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
calculate_position (i, !doubled[i], &x, &y);
|
||||||
|
|
||||||
|
if (doubled[i])
|
||||||
|
XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
else
|
||||||
|
XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH*2, WINDOW_HEIGHT*2);
|
||||||
|
|
||||||
|
doubled[i] = !doubled[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user