diff --git a/ChangeLog b/ChangeLog index 313c10233..aaf8d4f36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2002-07-20 Havoc Pennington + + * src/display.c (meta_display_open): grab display across managing + each screen; XGetInputFocus() on startup. + +2002-07-19 Havoc Pennington + + * 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 * configure.in: fix x11 header checks when x11 is not in the diff --git a/src/constraints.c b/src/constraints.c new file mode 100644 index 000000000..0ed0d0b58 --- /dev/null +++ b/src/constraints.c @@ -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 + +/* 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) +{ + + + +} + + + + + + + + + diff --git a/src/constraints.h b/src/constraints.h new file mode 100644 index 000000000..e901cf251 --- /dev/null +++ b/src/constraints.h @@ -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 */ + + + + + + + + + diff --git a/src/display.c b/src/display.c index 74d124254..e26eaa7e0 100644 --- a/src/display.c +++ b/src/display.c @@ -469,7 +469,8 @@ meta_display_open (const char *name) XA_CARDINAL, 32, PropModeReplace, (guchar*) data, 1); } - + + meta_display_grab (display); /* Now manage all existing windows */ tmp = display->screens; while (tmp != NULL) @@ -477,6 +478,25 @@ meta_display_open (const char *name) meta_screen_manage_all_windows (tmp->data); 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; } diff --git a/src/window.c b/src/window.c index 882f9770c..54e989f55 100644 --- a/src/window.c +++ b/src/window.c @@ -2944,6 +2944,37 @@ meta_window_configure_request (MetaWindow *window, int x, y, width, height; gboolean only_resize; 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, * and otherwise use our current up-to-date position. @@ -2978,6 +3009,9 @@ meta_window_configure_request (MetaWindow *window, { allow_position_change = TRUE; } + + if (in_grab_op) + allow_position_change = FALSE; if (allow_position_change) { @@ -3009,11 +3043,14 @@ meta_window_configure_request (MetaWindow *window, width = window->rect.width; height = window->rect.height; - if (event->xconfigurerequest.value_mask & CWWidth) - width = event->xconfigurerequest.width; + if (!in_grab_op) + { + if (event->xconfigurerequest.value_mask & CWWidth) + width = event->xconfigurerequest.width; - if (event->xconfigurerequest.value_mask & CWHeight) - height = event->xconfigurerequest.height; + if (event->xconfigurerequest.value_mask & CWHeight) + height = event->xconfigurerequest.height; + } /* ICCCM 4.1.5 */