mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
grab display across managing each screen; XGetInputFocus() on startup.
2002-07-20 Havoc Pennington <hp@pobox.com> * src/display.c (meta_display_open): grab display across managing each screen; XGetInputFocus() on startup. 2002-07-19 Havoc Pennington <hp@pobox.com> * src/window.c (meta_window_configure_request): disable configure requests during a user move/resize operation, mostly a workaround for stoopid apps.
This commit is contained in:
parent
6f6e533380
commit
78a2866980
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
2002-07-20 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
* src/display.c (meta_display_open): grab display across managing
|
||||||
|
each screen; XGetInputFocus() on startup.
|
||||||
|
|
||||||
|
2002-07-19 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
* src/window.c (meta_window_configure_request): disable configure
|
||||||
|
requests during a user move/resize operation, mostly a workaround
|
||||||
|
for stoopid apps.
|
||||||
|
|
||||||
2002-07-24 jacob berkman <jacob@ximian.com>
|
2002-07-24 jacob berkman <jacob@ximian.com>
|
||||||
|
|
||||||
* configure.in: fix x11 header checks when x11 is not in the
|
* configure.in: fix x11 header checks when x11 is not in the
|
||||||
|
147
src/constraints.c
Normal file
147
src/constraints.c
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/* Metacity size/position constraints */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2002 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <constraints.h>
|
||||||
|
|
||||||
|
/* The way this code works was suggested by Owen Taylor.
|
||||||
|
*
|
||||||
|
* For any move_resize, we determine which variables are "free
|
||||||
|
* variables" - stated another way, which edges of the window are
|
||||||
|
* moving. During the move resize, we only want to modify those
|
||||||
|
* variables; otherwise the constraint process can have peculiar side
|
||||||
|
* effects when the size and position constraints interact. For
|
||||||
|
* example, resizing a window from the top might go wrong when
|
||||||
|
* position constraints apply to the top edge, and result in the
|
||||||
|
* bottom edge moving downward while the top stays fixed.
|
||||||
|
*
|
||||||
|
* After selecting the variables we plan to vary, we define
|
||||||
|
* each constraint on the window in terms of those variables.
|
||||||
|
*
|
||||||
|
* Trivial example, say we are resizing vertically from the top of the
|
||||||
|
* window. In that case we are applying the user's mouse motion delta
|
||||||
|
* to an original size and position, note that dy is positive to
|
||||||
|
* resize downward:
|
||||||
|
*
|
||||||
|
* new_height = orig_height - dy;
|
||||||
|
* new_y = orig_y + dy;
|
||||||
|
*
|
||||||
|
* A constraint that the position can't go above the top panel would
|
||||||
|
* look like this:
|
||||||
|
*
|
||||||
|
* new_y > screen_top_bound
|
||||||
|
*
|
||||||
|
* Substitute:
|
||||||
|
*
|
||||||
|
* orig_y + dy > screen_top_bound
|
||||||
|
*
|
||||||
|
* Find the "boundary point" by changing to an equality:
|
||||||
|
*
|
||||||
|
* orig_y + dy = screen_top_bound
|
||||||
|
*
|
||||||
|
* Solve:
|
||||||
|
*
|
||||||
|
* dy = screen_top_bound - orig_y
|
||||||
|
*
|
||||||
|
* Plug that back into the size/position computations:
|
||||||
|
*
|
||||||
|
* new_y = orig_y + screen_top_bound - orig_y
|
||||||
|
* new_y = screen_top_bound
|
||||||
|
* new_height = orig_height - screen_top_bound + orig_y;
|
||||||
|
*
|
||||||
|
* This way the constraint is applied simultaneously to size/position,
|
||||||
|
* so you aren't running the risk of constraining one but still
|
||||||
|
* changing the other. i.e. we've converted an operation that may
|
||||||
|
* modify both the Y position and the height of the window into an
|
||||||
|
* operation that modifies a single variable, dy. That variable is
|
||||||
|
* then constrained, rather than the constraining the Y pos and height
|
||||||
|
* separately.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* To adjust for window gravity, such as a client moving itself to the
|
||||||
|
* southeast corner, we want to compute the gravity reference point
|
||||||
|
* - (screen_width,screen_height) in the SE corner case - using the
|
||||||
|
* size the client had in its configure request. But then we want
|
||||||
|
* to compute the actual position we intend to land on using
|
||||||
|
* the real constrained dimensions of the window.
|
||||||
|
*
|
||||||
|
* So for a window being placed in the SE corner and simultaneously
|
||||||
|
* resized, we get the gravity reference point, then compute where the
|
||||||
|
* window should go to maintain that ref. point at its current size
|
||||||
|
* instead of at the requested size, and conceptually move the window
|
||||||
|
* to the requested ref. point but at its current size, without
|
||||||
|
* applying any constraints. Then we constrain it with the top and
|
||||||
|
* left edges as the edges that vary, with a dx/dy that are the delta
|
||||||
|
* from the current size to the requested size.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void (* MetaConstraintFunc) (MetaWindow *window,
|
||||||
|
MetaFrameGeometry *fgeom,
|
||||||
|
const MetaRectangle *orig,
|
||||||
|
MetaRectangle *new);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
VERTICAL_TOP,
|
||||||
|
VERTICAL_BOTTOM,
|
||||||
|
VERTICAL_CENTER
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
HORIZONTAL_LEFT,
|
||||||
|
HORIZONTAL_RIGHT,
|
||||||
|
HORIZONTAL_CENTER
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Maximization constraint:
|
||||||
|
*
|
||||||
|
* new_x = workarea_x + frame_left
|
||||||
|
* new_y = workarea_y + frame_top
|
||||||
|
* new_w = workarea_w - frame_left - frame_right
|
||||||
|
* new_h = workarea_h - frame_top - frame_bottom
|
||||||
|
*
|
||||||
|
* No need to do anything hard because it just locks specific
|
||||||
|
* size/pos
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_constrain (MetaWindow *window,
|
||||||
|
MetaFrameGeometry *fgeom,
|
||||||
|
int resize_gravity,
|
||||||
|
const MetaRectangle *orig,
|
||||||
|
MetaRectangle *new)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
44
src/constraints.h
Normal file
44
src/constraints.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* Metacity size/position constraints */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2002 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_CONSTRAINTS_H
|
||||||
|
#define META_CONSTRAINTS_H
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
|
void meta_window_constrain (MetaWindow *window,
|
||||||
|
MetaFrameGeometry *fgeom,
|
||||||
|
int resize_gravity,
|
||||||
|
const MetaRectangle *orig,
|
||||||
|
MetaRectangle *new);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* META_CONSTRAINTS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -469,7 +469,8 @@ meta_display_open (const char *name)
|
|||||||
XA_CARDINAL,
|
XA_CARDINAL,
|
||||||
32, PropModeReplace, (guchar*) data, 1);
|
32, PropModeReplace, (guchar*) data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta_display_grab (display);
|
||||||
/* Now manage all existing windows */
|
/* Now manage all existing windows */
|
||||||
tmp = display->screens;
|
tmp = display->screens;
|
||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
@ -477,6 +478,25 @@ meta_display_open (const char *name)
|
|||||||
meta_screen_manage_all_windows (tmp->data);
|
meta_screen_manage_all_windows (tmp->data);
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Window focus;
|
||||||
|
int ret_to;
|
||||||
|
|
||||||
|
/* kinda bogus because GetInputFocus has no possible errors */
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
|
||||||
|
focus = None;
|
||||||
|
ret_to = RevertToNone;
|
||||||
|
XGetInputFocus (display->xdisplay, &focus, &ret_to);
|
||||||
|
|
||||||
|
/* Force a new FocusIn (does this work?) */
|
||||||
|
XSetInputFocus (display->xdisplay, focus, ret_to, CurrentTime);
|
||||||
|
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_display_ungrab (display);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
45
src/window.c
45
src/window.c
@ -2944,6 +2944,37 @@ meta_window_configure_request (MetaWindow *window,
|
|||||||
int x, y, width, height;
|
int x, y, width, height;
|
||||||
gboolean only_resize;
|
gboolean only_resize;
|
||||||
gboolean allow_position_change;
|
gboolean allow_position_change;
|
||||||
|
gboolean in_grab_op;
|
||||||
|
|
||||||
|
/* We ignore configure requests while the user is moving/resizing
|
||||||
|
* the window, since these represent the app sucking and fighting
|
||||||
|
* the user, most likely due to a bug in the app (e.g. pfaedit
|
||||||
|
* seemed to do this)
|
||||||
|
*
|
||||||
|
* Still have to do the ConfigureNotify and all, but pretend the
|
||||||
|
* app asked for the current size/position instead of the new one.
|
||||||
|
*/
|
||||||
|
in_grab_op = FALSE;
|
||||||
|
if (window->display->grab_op != META_GRAB_OP_NONE &&
|
||||||
|
window == window->display->grab_window)
|
||||||
|
{
|
||||||
|
switch (window->display->grab_op)
|
||||||
|
{
|
||||||
|
case META_GRAB_OP_MOVING:
|
||||||
|
case META_GRAB_OP_RESIZING_SE:
|
||||||
|
case META_GRAB_OP_RESIZING_S:
|
||||||
|
case META_GRAB_OP_RESIZING_SW:
|
||||||
|
case META_GRAB_OP_RESIZING_N:
|
||||||
|
case META_GRAB_OP_RESIZING_NE:
|
||||||
|
case META_GRAB_OP_RESIZING_NW:
|
||||||
|
case META_GRAB_OP_RESIZING_W:
|
||||||
|
case META_GRAB_OP_RESIZING_E:
|
||||||
|
in_grab_op = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* it's essential to use only the explicitly-set fields,
|
/* it's essential to use only the explicitly-set fields,
|
||||||
* and otherwise use our current up-to-date position.
|
* and otherwise use our current up-to-date position.
|
||||||
@ -2978,6 +3009,9 @@ meta_window_configure_request (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
allow_position_change = TRUE;
|
allow_position_change = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_grab_op)
|
||||||
|
allow_position_change = FALSE;
|
||||||
|
|
||||||
if (allow_position_change)
|
if (allow_position_change)
|
||||||
{
|
{
|
||||||
@ -3009,11 +3043,14 @@ meta_window_configure_request (MetaWindow *window,
|
|||||||
width = window->rect.width;
|
width = window->rect.width;
|
||||||
height = window->rect.height;
|
height = window->rect.height;
|
||||||
|
|
||||||
if (event->xconfigurerequest.value_mask & CWWidth)
|
if (!in_grab_op)
|
||||||
width = event->xconfigurerequest.width;
|
{
|
||||||
|
if (event->xconfigurerequest.value_mask & CWWidth)
|
||||||
|
width = event->xconfigurerequest.width;
|
||||||
|
|
||||||
if (event->xconfigurerequest.value_mask & CWHeight)
|
if (event->xconfigurerequest.value_mask & CWHeight)
|
||||||
height = event->xconfigurerequest.height;
|
height = event->xconfigurerequest.height;
|
||||||
|
}
|
||||||
|
|
||||||
/* ICCCM 4.1.5 */
|
/* ICCCM 4.1.5 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user