This commit is contained in:
rhp 2001-06-11 03:24:20 +00:00
parent f14221e842
commit 9cb0dc3d65
8 changed files with 414 additions and 149 deletions

View File

@ -370,6 +370,8 @@ meta_display_grab (MetaDisplay *display)
}
XSync (display->xdisplay, False);
display->server_grab_count += 1;
meta_verbose ("Grabbing display, grab count now %d\n",
display->server_grab_count);
}
void
@ -384,10 +386,13 @@ meta_display_ungrab (MetaDisplay *display)
/* FIXME we want to purge all pending "queued" stuff
* at this point, such as window hide/show
*/
XSync (display->xdisplay, False);
XUngrabServer (display->xdisplay);
}
XSync (display->xdisplay, False);
meta_verbose ("Ungrabbing display, grab count now %d\n",
display->server_grab_count);
}
MetaDisplay*
@ -532,16 +537,23 @@ event_queue_callback (MetaEventQueue *queue,
meta_window_free (window); /* Unmanage destroyed window */
break;
case UnmapNotify:
if (window && window->mapped)
if (window)
{
meta_verbose ("Window %s withdrawn\n",
window->desc);
meta_window_free (window); /* Unmanage withdrawn window */
if (window->unmaps_pending == 0)
{
meta_verbose ("Window %s withdrawn\n",
window->desc);
meta_window_free (window); /* Unmanage withdrawn window */
}
else
{
window->unmaps_pending -= 1;
meta_verbose ("Received pending unmap, %d now pending\n",
window->unmaps_pending);
}
}
break;
case MapNotify:
if (window)
window->mapped = TRUE;
break;
case MapRequest:
if (window == NULL)
@ -809,7 +821,7 @@ meta_spew_event (MetaDisplay *display,
break;
case EnterNotify:
name = "EnterNotify";
extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %d detail: %d\n",
extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %d detail: %d",
event->xcrossing.window,
event->xcrossing.root,
event->xcrossing.subwindow,
@ -818,7 +830,7 @@ meta_spew_event (MetaDisplay *display,
break;
case LeaveNotify:
name = "LeaveNotify";
extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %d detail: %d\n",
extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %d detail: %d",
event->xcrossing.window,
event->xcrossing.root,
event->xcrossing.subwindow,
@ -903,7 +915,29 @@ meta_spew_event (MetaDisplay *display,
name = "CirculateRequest";
break;
case PropertyNotify:
name = "PropertyNotify";
{
char *str;
const char *state;
name = "PropertyNotify";
meta_error_trap_push (display);
str = XGetAtomName (display->xdisplay,
event->xproperty.atom);
meta_error_trap_pop (display);
if (event->xproperty.state == PropertyNewValue)
state = "PropertyNewValue";
else if (event->xproperty.state == PropertyDelete)
state = "PropertyDelete";
else
state = "(????)";
extra = g_strdup_printf ("atom: %s state: %s",
str ? str : "(unknown atom)",
state);
XFree (str);
}
break;
case SelectionClear:
name = "SelectionClear";

View File

@ -84,74 +84,24 @@ meta_frame_init_info (MetaFrame *frame,
info->current_control_state = META_STATE_PRELIGHT;
}
/* returns values suitable for meta_window_move */
void
meta_frame_adjust_for_gravity (int win_gravity,
int frame_width,
int frame_height,
MetaFrameGeometry *fgeom,
int child_root_x,
int child_root_y,
int *win_root_x,
int *win_root_y)
static void
pango_hack_start (MetaDisplay *display)
{
int x, y;
/* NW coordinate of the frame. We should just
* compute NW coordinate to return from the start,
* but I wrote it this way first and am now lazy
*/
x = 0;
y = 0;
switch (win_gravity)
if (display->server_grab_count > 0)
{
case NorthWestGravity:
x = child_root_x;
y = child_root_y;
break;
case NorthGravity:
x = child_root_x - frame_width / 2;
y = child_root_y;
break;
case NorthEastGravity:
x = child_root_x - frame_width;
y = child_root_y;
break;
case WestGravity:
x = child_root_x;
y = child_root_y - frame_height / 2;
break;
case CenterGravity:
x = child_root_x - frame_width / 2;
y = child_root_y - frame_height / 2;
break;
case EastGravity:
x = child_root_x - frame_width;
y = child_root_y - frame_height / 2;
break;
case SouthWestGravity:
x = child_root_x;
y = child_root_y - frame_height;
break;
case SouthGravity:
x = child_root_x - frame_width / 2;
y = child_root_y - frame_height;
break;
case SouthEastGravity:
x = child_root_x - frame_width;
y = child_root_y - frame_height;
break;
case StaticGravity:
default:
x = child_root_x - fgeom->left_width;
y = child_root_y - fgeom->top_height;
break;
meta_verbose ("Pango workaround, ungrabbing server\n");
XUngrabServer (display->xdisplay);
}
}
*win_root_x = x + fgeom->left_width;
*win_root_y = y + fgeom->top_height;
static void
pango_hack_end (MetaDisplay *display)
{
if (display->server_grab_count > 0)
{
meta_verbose ("Pango workaround, regrabbing server\n");
XGrabServer (display->xdisplay);
}
}
void
@ -193,8 +143,10 @@ meta_frame_calc_geometry (MetaFrame *frame,
geom.shape_mask = None;
pango_hack_start (frame->window->display);
window->screen->engine->fill_frame_geometry (&info, &geom,
frame->theme_data);
pango_hack_end (frame->window->display);
*geomp = geom;
}
@ -243,6 +195,8 @@ meta_window_ensure_frame (MetaWindow *window)
MetaFrame *frame;
XSetWindowAttributes attrs;
g_return_if_fail (window->display->server_grab_count > 0);
if (window->frame)
return;
@ -286,16 +240,16 @@ meta_window_ensure_frame (MetaWindow *window)
/* Reparent the client window; it may be destroyed,
* thus the error trap. We'll get a destroy notify later
* and free everything. Comment in FVWM source code says
* we need the server grab or the child can get its MapNotify
* we need a server grab or the child can get its MapNotify
* before we've finished reparenting and getting the decoration
* window onscreen.
* window onscreen, so ensure_frame must be called with
* a grab.
*/
meta_display_grab (window->display);
meta_error_trap_push (window->display);
window->mapped = FALSE; /* the reparent will unmap the window,
* we don't want to take that as a withdraw
*/
window->unmaps_pending += 1;
XReparentWindow (window->display->xdisplay,
window->xwindow,
frame->xwindow,
@ -304,11 +258,6 @@ meta_window_ensure_frame (MetaWindow *window)
/* stick frame to the window */
window->frame = frame;
/* Ungrab server (FIXME after fixing Pango not to lock us up,
* we need to recalc geometry before ungrabbing)
*/
meta_display_ungrab (window->display);
}
void
@ -339,6 +288,7 @@ meta_window_destroy_frame (MetaWindow *window)
* can identify a withdraw initiated
* by the client.
*/
window->unmaps_pending += 1;
XReparentWindow (window->display->xdisplay,
window->xwindow,
window->screen->xroot,
@ -366,9 +316,11 @@ meta_frame_sync_to_window (MetaFrame *frame,
gboolean need_move,
gboolean need_resize)
{
meta_verbose ("Syncing frame geometry %d,%d %dx%d pixel %ld\n",
meta_verbose ("Syncing frame geometry %d,%d %dx%d (SE: %d,%d) pixel %ld\n",
frame->rect.x, frame->rect.y,
frame->rect.width, frame->rect.height,
frame->rect.x + frame->rect.width,
frame->rect.y + frame->rect.height,
frame->bg_pixel);
/* set bg to none to avoid flicker */
@ -439,9 +391,11 @@ meta_frame_draw_now (MetaFrame *frame,
info.drawable = p;
info.xoffset = - x;
info.yoffset = - y;
pango_hack_start (frame->window->display);
frame->window->screen->engine->expose_frame (&info,
0, 0, width, height,
frame->theme_data);
pango_hack_end (frame->window->display);
XCopyArea (frame->window->display->xdisplay,
@ -610,6 +564,7 @@ update_move (MetaFrame *frame,
dx = x - frame->grab->start_root_x;
dy = y - frame->grab->start_root_y;
frame->window->user_has_moved = TRUE;
meta_window_move (frame->window,
frame->grab->start_window_x + dx,
frame->grab->start_window_y + dy);
@ -624,6 +579,7 @@ update_resize_se (MetaFrame *frame,
dx = x - frame->grab->start_root_x;
dy = y - frame->grab->start_root_y;
frame->window->user_has_resized = TRUE;
meta_window_resize (frame->window,
frame->grab->start_window_x + dx,
frame->grab->start_window_y + dy);

View File

@ -76,15 +76,6 @@ void meta_frame_calc_geometry (MetaFrame *frame,
int child_width,
int child_height,
MetaFrameGeometry *geomp);
/* returns values suitable for meta_window_move */
void meta_frame_adjust_for_gravity (int win_gravity,
int frame_width,
int frame_height,
MetaFrameGeometry *fgeom,
int x,
int y,
int *win_root_x,
int *win_root_y);
void meta_frame_sync_to_window (MetaFrame *frame,
gboolean need_move,
gboolean need_resize);

View File

@ -9,7 +9,19 @@ elif test -z "$DEBUG"; then
DEBUG=gdb
fi
if test -z "$CLIENTS"; then
CLIENTS=0
fi
Xnest :1 -scrns $SCREENS -geometry 640x480 -bw 15 &
usleep 50000
if test $CLIENTS != 0; then
for I in `seq 1 $CLIENTS`; do
DISPLAY=:1 xterm -geometry 25x15 &
done
fi
DISPLAY=:1 xsetroot -solid royalblue3
METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 unst libtool --mode=execute $DEBUG ./metacity
killall Xnest

View File

@ -240,6 +240,7 @@ meta_screen_manage_all_windows (MetaScreen *screen)
return;
}
meta_stack_freeze (screen->stack);
i = 0;
while (i < n_children)
{
@ -247,6 +248,7 @@ meta_screen_manage_all_windows (MetaScreen *screen)
++i;
}
meta_stack_thaw (screen->stack);
meta_display_ungrab (screen->display);

View File

@ -29,6 +29,7 @@
#include <X11/Xatom.h>
static void constrain_size (MetaWindow *window,
MetaFrameGeometry *fgeom,
int width,
int height,
int *new_width,
@ -83,18 +84,31 @@ meta_window_new (MetaDisplay *display, Window xwindow)
meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
/* round trip */
/* Grab server */
meta_display_grab (display);
meta_error_trap_push (display);
if (XGetWindowAttributes (display->xdisplay,
xwindow, &attrs) == Success &&
attrs.override_redirect)
XGetWindowAttributes (display->xdisplay,
xwindow, &attrs);
if (meta_error_trap_pop (display))
{
meta_verbose ("Deciding not to manage override_redirect window 0x%lx\n", xwindow);
meta_error_trap_pop (display);
meta_verbose ("Failed to get attributes for window 0x%lx\n",
xwindow);
meta_display_ungrab (display);
return NULL;
}
if (attrs.override_redirect)
{
meta_verbose ("Deciding not to manage override_redirect window 0x%lx\n", xwindow);
meta_display_ungrab (display);
return NULL;
}
meta_error_trap_push (display);
XAddToSaveSet (display->xdisplay, xwindow);
XSelectInput (display->xdisplay, xwindow,
@ -110,10 +124,12 @@ meta_window_new (MetaDisplay *display, Window xwindow)
{
meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n",
xwindow);
meta_display_ungrab (display);
return NULL;
}
g_assert (!attrs.override_redirect);
window = g_new (MetaWindow, 1);
window->xwindow = xwindow;
@ -139,6 +155,9 @@ meta_window_new (MetaDisplay *display, Window xwindow)
g_assert (window->screen);
/* avoid tons of stack updates */
meta_stack_freeze (window->screen->stack);
/* Remember this rect is the actual window size */
window->rect.x = attrs.x;
window->rect.y = attrs.y;
@ -165,6 +184,9 @@ meta_window_new (MetaDisplay *display, Window xwindow)
window->frame = NULL;
window->has_focus = FALSE;
window->user_has_resized = FALSE;
window->user_has_moved = FALSE;
window->maximized = FALSE;
window->on_all_workspaces = FALSE;
window->shaded = FALSE;
@ -173,6 +195,8 @@ meta_window_new (MetaDisplay *display, Window xwindow)
window->iconic = FALSE;
window->mapped = FALSE;
window->unmaps_pending = 0;
window->decorated = TRUE;
window->has_close_func = TRUE;
window->has_minimize_func = TRUE;
@ -220,6 +244,7 @@ meta_window_new (MetaDisplay *display, Window xwindow)
* change it again.
*/
set_wm_state (window, window->iconic ? IconicState : NormalState);
set_net_wm_state (window);
if (window->decorated)
meta_window_ensure_frame (window);
@ -239,8 +264,13 @@ meta_window_new (MetaDisplay *display, Window xwindow)
meta_stack_add (window->screen->stack,
window);
/* Sync stack changes */
meta_stack_thaw (window->screen->stack);
meta_window_queue_calc_showing (window);
meta_display_ungrab (display);
return window;
}
@ -294,18 +324,54 @@ static int
set_wm_state (MetaWindow *window,
int state)
{
unsigned long data[1];
unsigned long data[2];
/* twm sets the icon window as data[1], I couldn't find that in
* ICCCM.
*/
data[0] = state;
data[1] = None;
meta_error_trap_push (window->display);
XChangeProperty (window->display->xdisplay, window->xwindow,
window->display->atom_wm_state,
window->display->atom_wm_state,
32, PropModeReplace, (guchar*) data, 1);
32, PropModeReplace, (guchar*) data, 2);
return meta_error_trap_pop (window->display);
}
static int
set_net_wm_state (MetaWindow *window)
{
int i;
unsigned long data[10];
i = 0;
if (window->shaded)
{
data[i] = window->display->atom_net_wm_state_shaded;
++i;
}
if (window->wm_state_modal)
{
data[i] = window->display->atom_net_wm_state_modal;
++i;
}
if (window->maximized)
{
data[i] = window->display->atom_net_wm_state_maximized_horz;
++i;
data[i] = window->display->atom_net_wm_state_maximized_vert;
++i;
}
meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i);
meta_error_trap_push (window->display);
XChangeProperty (window->display->xdisplay, window->xwindow,
window->display->atom_net_wm_state,
XA_ATOM,
32, PropModeReplace, (guchar*) data, i);
return meta_error_trap_pop (window->display);
}
@ -370,6 +436,7 @@ meta_window_show (MetaWindow *window)
{
meta_verbose ("%s actually needs unmap\n", window->desc);
window->mapped = FALSE;
window->unmaps_pending += 1;
meta_error_trap_push (window->display);
XUnmapWindow (window->display->xdisplay, window->xwindow);
meta_error_trap_pop (window->display);
@ -416,6 +483,7 @@ meta_window_hide (MetaWindow *window)
{
meta_verbose ("%s actually needs unmap\n", window->desc);
window->mapped = FALSE;
window->unmaps_pending += 1;
XUnmapWindow (window->display->xdisplay, window->xwindow);
}
@ -464,6 +532,8 @@ meta_window_maximize (MetaWindow *window)
/* move_resize with new maximization constraints
*/
meta_window_queue_move_resize (window);
set_net_wm_state (window);
}
}
@ -479,6 +549,8 @@ meta_window_unmaximize (MetaWindow *window)
window->saved_rect.y,
window->saved_rect.width,
window->saved_rect.height);
set_net_wm_state (window);
}
}
@ -490,6 +562,8 @@ meta_window_shade (MetaWindow *window)
window->shaded = TRUE;
meta_window_queue_move_resize (window);
meta_window_queue_calc_showing (window);
set_net_wm_state (window);
}
}
@ -504,6 +578,142 @@ meta_window_unshade (MetaWindow *window)
/* focus the window */
/* FIXME CurrentTime is bogus */
meta_window_focus (window, CurrentTime);
set_net_wm_state (window);
}
}
/* returns values suitable for meta_window_move */
void
adjust_for_gravity (MetaWindow *window,
MetaFrameGeometry *fgeom,
gboolean coords_assume_border,
int x,
int y,
int *xp,
int *yp)
{
int ref_x, ref_y;
int bw;
int child_x, child_y;
int frame_width, frame_height;
if (coords_assume_border)
bw = window->border_width;
else
bw = 0;
if (fgeom)
{
child_x = fgeom->left_width;
child_y = fgeom->top_height;
frame_width = child_x + window->rect.width + fgeom->right_width;
frame_height = child_y + window->rect.height + fgeom->bottom_height;
}
else
{
child_x = 0;
child_y = 0;
frame_width = window->rect.width;
frame_height = window->rect.height;
}
/* We're computing position to pass to window_move, which is
* the position of the client window (StaticGravity basically)
*
* (see WM spec description of gravity computation, but note that
* their formulas assume we're honoring the border width, rather
* than compensating for having turned it off)
*/
switch (window->size_hints.win_gravity)
{
case NorthWestGravity:
ref_x = x;
ref_y = y;
break;
case NorthGravity:
ref_x = x + window->rect.width / 2 + bw;
ref_y = y;
break;
case NorthEastGravity:
ref_x = x + window->rect.width + bw * 2;
ref_y = y;
break;
case WestGravity:
ref_x = x;
ref_y = y + window->rect.height / 2 + bw;
break;
case CenterGravity:
ref_x = x + window->rect.width / 2 + bw;
ref_y = y + window->rect.height / 2 + bw;
break;
case EastGravity:
ref_x = x + window->rect.width + bw * 2;
ref_y = y + window->rect.height / 2 + bw;
break;
case SouthWestGravity:
ref_x = x;
ref_y = y + window->rect.height + bw * 2;
break;
case SouthGravity:
ref_x = x + window->rect.width / 2 + bw;
ref_y = y + window->rect.height + bw * 2;
break;
case SouthEastGravity:
ref_x = x + window->rect.width + bw * 2;
ref_y = y + window->rect.height + bw * 2;
break;
case StaticGravity:
default:
ref_x = x;
ref_y = y;
break;
}
switch (window->size_hints.win_gravity)
{
case NorthWestGravity:
*xp = ref_x + child_x;
*yp = ref_y + child_y;
break;
case NorthGravity:
*xp = ref_x - frame_width / 2 + child_x;
*yp = ref_y + child_y;
break;
case NorthEastGravity:
*xp = ref_x - frame_width + child_x;
*yp = ref_y + child_y;
break;
case WestGravity:
*xp = ref_x + child_x;
*yp = ref_y - frame_height / 2 + child_y;
break;
case CenterGravity:
*xp = ref_x - frame_width / 2 + child_x;
*yp = ref_y - frame_height / 2 + child_y;
break;
case EastGravity:
*xp = ref_x - frame_width + child_x;
*yp = ref_y - frame_height / 2 + child_y;
break;
case SouthWestGravity:
*xp = ref_x + child_x;
*yp = ref_y - frame_height + child_y;
break;
case SouthGravity:
*xp = ref_x - frame_width / 2 + child_x;
*yp = ref_y - frame_height + child_y;
break;
case SouthEastGravity:
*xp = ref_x - frame_width + child_x;
*yp = ref_y - frame_height + child_y;
break;
case StaticGravity:
default:
*xp = ref_x;
*yp = ref_y;
break;
}
}
@ -524,10 +734,22 @@ meta_window_move_resize_internal (MetaWindow *window,
gboolean need_resize_client = FALSE;
gboolean need_resize_frame = FALSE;
meta_verbose ("Move/resize %s to %d,%d %dx%d\n",
window->desc, root_x_nw, root_y_nw, w, h);
meta_verbose ("Move/resize %s to %d,%d %dx%d%s\n",
window->desc, root_x_nw, root_y_nw, w, h,
is_configure_request ? " (configure request)" : "");
constrain_size (window, w, h, &w, &h);
/* FIXME we're passing old window size to calc_geometry,
* I believe the right fix is to remove window size
* args from calc_geometry and remove any dependency
* on that in frame code.
*/
if (window->frame)
meta_frame_calc_geometry (window->frame,
window->rect.width,
window->rect.height,
&fgeom);
constrain_size (window, &fgeom, w, h, &w, &h);
meta_verbose ("Constrained resize of %s to %d x %d\n", window->desc, w, h);
if (w != window->rect.width ||
@ -541,11 +763,6 @@ meta_window_move_resize_internal (MetaWindow *window,
{
int new_w, new_h;
meta_frame_calc_geometry (window->frame,
window->rect.width,
window->rect.height,
&fgeom);
new_w = window->rect.width + fgeom.left_width + fgeom.right_width;
if (window->shaded)
@ -563,21 +780,23 @@ meta_window_move_resize_internal (MetaWindow *window,
meta_verbose ("Calculated frame size %dx%d\n",
window->frame->rect.width,
window->frame->rect.height);
}
if (is_configure_request)
{
meta_frame_adjust_for_gravity (window->size_hints.win_gravity,
window->frame->rect.width,
window->frame->rect.height,
&fgeom,
root_x_nw,
root_y_nw,
&root_x_nw,
&root_y_nw);
if (is_configure_request)
{
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_verbose ("Compensated position for gravity, new pos %d,%d\n",
root_x_nw, root_y_nw);
}
meta_verbose ("Compensated position for gravity, new pos %d,%d\n",
root_x_nw, root_y_nw);
}
constrain_position (window,
@ -1079,6 +1298,18 @@ meta_window_client_message (MetaWindow *window,
meta_window_unmaximize (window);
}
if (first == display->atom_net_wm_state_modal ||
second == display->atom_net_wm_state_modal)
{
window->wm_state_modal =
(action == _NET_WM_STATE_ADD) ||
(action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal);
recalc_window_type (window);
meta_window_queue_move_resize (window);
set_net_wm_state (window);
}
return TRUE;
}
else if (event->xclient.message_type ==
@ -1244,6 +1475,9 @@ static int
update_size_hints (MetaWindow *window)
{
int x, y, w, h;
gulong supplied;
meta_verbose ("Updating WM_NORMAL_HINTS\n");
/* Save the last ConfigureRequest, which we put here.
* Values here set in the hints are supposed to
@ -1255,11 +1489,19 @@ update_size_hints (MetaWindow *window)
h = window->size_hints.height;
window->size_hints.flags = 0;
supplied = 0;
meta_error_trap_push (window->display);
XGetNormalHints (window->display->xdisplay,
window->xwindow,
&window->size_hints);
XGetWMNormalHints (window->display->xdisplay,
window->xwindow,
&window->size_hints,
&supplied);
/* as far as I can tell, "supplied" is just
* to check whether we had old-style normal hints
* without gravity, base size as returned by
* XGetNormalHints()
*/
/* Put it back. */
window->size_hints.x = x;
@ -1375,6 +1617,8 @@ update_size_hints (MetaWindow *window)
}
else
{
meta_verbose ("Window %s doesn't set gravity, using NW\n",
window->desc);
window->size_hints.win_gravity = NorthWestGravity;
window->size_hints.flags |= PWinGravity;
}
@ -1885,7 +2129,6 @@ update_transient_for (MetaWindow *window)
/* update stacking constraints */
meta_stack_update_transient (window->screen->stack, window);
meta_stack_update_layer (window->screen->stack, window);
return meta_error_trap_pop (window->display);
}
@ -2004,6 +2247,7 @@ recalc_window_type (MetaWindow *window)
static void
constrain_size (MetaWindow *window,
MetaFrameGeometry *fgeom,
int width, int height,
int *new_width, int *new_height)
{
@ -2029,13 +2273,19 @@ constrain_size (MetaWindow *window,
fullh = window->screen->active_workspace->workarea.height;
if (window->frame)
{
fullw -= window->frame->child_x + window->frame->right_width;
fullh -= window->frame->child_y + window->frame->bottom_height;
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)
/* If user hasn't resized or moved, then try to shrink the window to
* fit onscreen, while not violating the min size, just as
* we do for maximize
*/
if (window->maximized ||
!(window->user_has_resized || window->user_has_moved))
{
maxw = MIN (maxw, fullw);
maxh = MIN (maxh, fullh);
@ -2043,6 +2293,15 @@ constrain_size (MetaWindow *window,
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)
{
minw = MAX (minw, fullw);

View File

@ -78,16 +78,14 @@ struct _MetaWindow
*/
guint on_all_workspaces : 1;
/* Mapped is what we think the mapped state should be;
* so if we get UnmapNotify and mapped == TRUE then
* it's a withdraw, if mapped == FALSE the UnmapNotify
* is caused by us.
*/
guint mapped : 1 ;
/* Minimize is the state controlled by the minimize button */
guint minimized : 1;
/* Whether the window is mapped; actual server-side state
* see also unmaps_pending
*/
guint mapped : 1;
/* Iconic is the state in WM_STATE; happens for workspaces/shading
* in addition to minimize
*/
@ -117,6 +115,19 @@ struct _MetaWindow
*/
guint has_focus : 1;
/* Track whether the user has ever manually modified
* the window; if so, we remove some constraints
* that exist on program modifications.
*/
guint user_has_resized : 1;
guint user_has_moved : 1;
/* Number of UnmapNotify that are caused by us, if
* we get UnmapNotify with none pending then the client
* is withdrawing the window.
*/
int unmaps_pending;
/* The size we set the window to last (i.e. what we believe
* to be its actual size on the server). The x, y are
* the actual server-side x,y so are relative to the frame