summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog53
-rw-r--r--README7
-rw-r--r--src/display.c69
-rw-r--r--src/display.h11
-rw-r--r--src/effects.c103
-rw-r--r--src/effects.h8
-rw-r--r--src/frames.c7
-rw-r--r--src/keybindings.c261
-rw-r--r--src/metacity.schemas.in19
-rw-r--r--src/prefs.c47
-rw-r--r--src/prefs.h4
-rwxr-xr-xsrc/run-metacity.sh4
-rw-r--r--src/screen.c18
-rw-r--r--src/screen.h5
-rw-r--r--src/window.c289
-rw-r--r--src/window.h8
16 files changed, 748 insertions, 165 deletions
diff --git a/ChangeLog b/ChangeLog
index ab710bf..012b098 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+2003-10-12 Havoc Pennington <hp@redhat.com>
+
+ Merge reduced_resources mode patch from the branch. Offers
+ wireframe and no-animations.
+
+ * src/window.c (implement_showing): no animation if we are
+ in reduced resources mode
+
+ * src/prefs.c: add REDUCED_RESOURCES pref
+
+ * src/window.c (meta_window_update_keyboard_resize): fix to
+ modify grab_anchor_window_pos to grab_wireframe_rect if
+ appropriate instead of window->rect
+
+ * src/display.h (struct _MetaDisplay): add grab_start_serial used
+ to avoid responding to events that occurred prior to the grab
+ initialization.
+
+ Still broken in various ways, specifically EnterNotify that
+ occurred prior to XGrabPointer is processed as if it occurred
+ after.
+
+ * src/window.c (meta_window_update_keyboard_move): add this
+ instead of meta_window_warp_pointer() crack
+
+ * src/effects.c (meta_effects_update_wireframe): draw a kind of
+ grid for the wireframe, instead of just a rectangle, like twm
+
+ * src/screen.c (meta_screen_new): line width of 3 for the XOR gc
+
+ "Reduced resources" mode based on wireframe patch from
+ Erwann Chenede. Still pretty buggy.
+
+ * src/keybindings.c (process_keyboard_move_grab)
+ (process_keyboard_resize_grab): add gruesome wireframe hacks
+
+ * src/display.c (meta_display_end_grab_op): end wireframe
+ (meta_display_begin_grab_op): begin wireframe
+
+ * src/effects.c (meta_effects_end_wireframe)
+ (meta_effects_update_wireframe, meta_effects_begin_wireframe):
+ routines to draw the wireframe stuff
+
+ * src/window.c (window_should_be_showing): hide window when
+ doing wireframe, commented out as it breaks grab
+ * src/window.c (meta_window_refresh_resize_popup): handle wireframe
+
+ * src/screen.c (meta_screen_new): create a screen->root_xor_gc
+ for use in drawing wireframes
+
+ * src/frames.c (meta_frames_push_delay_exposes): repaint
+ everything before we delay
+
2003-10-11 Havoc Pennington <hp@pobox.com>
* src/display.c (meta_display_begin_grab_op): initialize
diff --git a/README b/README
index 7d57166..aacb0fb 100644
--- a/README
+++ b/README
@@ -370,12 +370,11 @@ A: This one is also in rationales.txt. Because "ouija board" UI, where
http://pobox.com/~hp/free-software-ui.html
http://pobox.com/~hp/features.html
-Q: Why no wireframe move/resize?
+Q: Why does wireframe move/resize suck?
-A: It's implemented in a patch that will be merged for GNOME 2.6
- and is already in some vendor packages.
+A: You can turn it on with the reduced_resources setting.
- But: Because it has low usability, and is a pain
+ But: it has low usability, and is a pain
to implement, and there's no reason opaque move/resize should be a
problem on any setup that can run a modern desktop worth a darn to
begin with.
diff --git a/src/display.c b/src/display.c
index c098676..719789c 100644
--- a/src/display.c
+++ b/src/display.c
@@ -35,6 +35,7 @@
#include "resizepopup.h"
#include "workspace.h"
#include "bell.h"
+#include "effects.h"
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#ifdef HAVE_SOLARIS_XINERAMA
@@ -1219,7 +1220,8 @@ event_callback (XEvent *event,
* goes to the frame.
*/
frame_was_receiver = TRUE;
- meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event\n");
+ meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event for %s\n",
+ window->desc);
}
#ifdef HAVE_XSYNC
@@ -1231,6 +1233,7 @@ event_callback (XEvent *event,
if (display->grab_op != META_GRAB_OP_NONE &&
display->grab_window != NULL &&
+ event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (display->grab_window, event);
}
@@ -1296,7 +1299,8 @@ event_callback (XEvent *event,
case ButtonPress:
if ((window &&
grab_op_is_mouse (display->grab_op) &&
- display->grab_button != (int) event->xbutton.button &&
+ display->grab_button != (int) event->xbutton.button &&
+ event->xany.serial > display->grab_start_serial &&
display->grab_window == window) ||
grab_op_is_keyboard (display->grab_op))
{
@@ -1446,16 +1450,19 @@ event_callback (XEvent *event,
break;
case ButtonRelease:
if (display->grab_window == window &&
+ event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
break;
case MotionNotify:
if (display->grab_window == window &&
+ event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
break;
case EnterNotify:
if (display->grab_window == window &&
+ event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
/* do this even if window->has_focus to avoid races */
@@ -1519,6 +1526,7 @@ event_callback (XEvent *event,
break;
case LeaveNotify:
if (display->grab_window == window &&
+ event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
else if (window != NULL)
@@ -2797,8 +2805,9 @@ meta_display_begin_grab_op (MetaDisplay *display,
Window grab_xwindow;
meta_topic (META_DEBUG_WINDOW_OPS,
- "Doing grab op %d on window %s button %d pointer already grabbed: %d\n",
- op, window ? window->desc : "none", button, pointer_already_grabbed);
+ "Doing grab op %d on window %s button %d pointer already grabbed: %d pointer pos %d,%d\n",
+ op, window ? window->desc : "none", button, pointer_already_grabbed,
+ root_x, root_y);
if (display->grab_op != META_GRAB_OP_NONE)
{
@@ -2808,6 +2817,9 @@ meta_display_begin_grab_op (MetaDisplay *display,
return FALSE;
}
+ /* We'll ignore any events < this serial. */
+ display->grab_start_serial = XNextRequest (display->xdisplay);
+
/* FIXME:
* If we have no MetaWindow we do our best
* and try to do the grab on the RootWindow.
@@ -2823,7 +2835,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
if (pointer_already_grabbed)
display->grab_have_pointer = TRUE;
-
+
meta_display_set_grab_op_cursor (display, screen, op, FALSE, grab_xwindow,
timestamp);
@@ -2860,8 +2872,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_xwindow = grab_xwindow;
display->grab_button = button;
display->grab_mask = modmask;
- display->grab_initial_root_x = root_x;
- display->grab_initial_root_y = root_y;
+ display->grab_anchor_root_x = root_x;
+ display->grab_anchor_root_y = root_y;
display->grab_latest_motion_x = root_x;
display->grab_latest_motion_y = root_y;
display->grab_last_moveresize_time.tv_sec = 0;
@@ -2870,6 +2882,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
#ifdef HAVE_XSYNC
display->grab_update_alarm = None;
#endif
+ display->grab_was_cancelled = FALSE;
if (display->grab_window)
{
@@ -2877,9 +2890,34 @@ meta_display_begin_grab_op (MetaDisplay *display,
meta_window_get_position (display->grab_window,
&display->grab_initial_window_pos.x,
&display->grab_initial_window_pos.y);
+ display->grab_anchor_window_pos = display->grab_initial_window_pos;
+ display->grab_wireframe_active =
+ meta_prefs_get_reduced_resources () &&
+ (meta_grab_op_is_resizing (display->grab_op) ||
+ meta_grab_op_is_moving (display->grab_op));
+
+ if (display->grab_wireframe_active)
+ {
+ /* FIXME we should really display the outer frame rect,
+ * but that complicates all the move/resize code since
+ * it works in terms of window rect.
+ */
+ display->grab_wireframe_rect = window->rect;
+ if (window->frame)
+ {
+ display->grab_wireframe_rect.x += window->frame->rect.x;
+ display->grab_wireframe_rect.y += window->frame->rect.y;
+ }
+
+ meta_window_calc_showing (display->grab_window);
+ meta_effects_begin_wireframe (display->grab_window->screen,
+ &display->grab_wireframe_rect);
+ }
+
#ifdef HAVE_XSYNC
- if (meta_grab_op_is_resizing (display->grab_op) &&
+ if (!display->grab_wireframe_active &&
+ meta_grab_op_is_resizing (display->grab_op) &&
display->grab_window->update_counter != None)
{
XSyncAlarmAttributes values;
@@ -3009,6 +3047,21 @@ meta_display_end_grab_op (MetaDisplay *display,
display->grab_update_alarm);
}
#endif /* HAVE_XSYNC */
+
+ if (display->grab_wireframe_active)
+ {
+ display->grab_wireframe_active = FALSE;
+ meta_effects_end_wireframe (display->grab_window->screen,
+ &display->grab_wireframe_rect);
+ if (!display->grab_was_cancelled)
+ meta_window_move_resize (display->grab_window,
+ TRUE,
+ display->grab_wireframe_rect.x,
+ display->grab_wireframe_rect.y,
+ display->grab_wireframe_rect.width,
+ display->grab_wireframe_rect.height);
+ meta_window_calc_showing (display->grab_window);
+ }
display->grab_window = NULL;
display->grab_screen = NULL;
diff --git a/src/display.h b/src/display.h
index f96253d..d6d3495 100644
--- a/src/display.h
+++ b/src/display.h
@@ -225,19 +225,24 @@ struct _MetaDisplay
MetaScreen *grab_screen;
MetaWindow *grab_window;
Window grab_xwindow;
+ gulong grab_start_serial;
int grab_button;
- int grab_initial_root_x;
- int grab_initial_root_y;
+ int grab_anchor_root_x;
+ int grab_anchor_root_y;
+ MetaRectangle grab_anchor_window_pos;
int grab_latest_motion_x;
int grab_latest_motion_y;
gulong grab_mask;
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
+ guint grab_wireframe_active : 1;
+ guint grab_was_cancelled : 1;
+ MetaRectangle grab_wireframe_rect;
MetaRectangle grab_initial_window_pos;
MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time;
Time grab_motion_notify_time;
-
+
/* we use property updates as sentinels for certain window focus events
* to avoid some race conditions on EnterNotify events
*/
diff --git a/src/effects.c b/src/effects.c
index 18fa594..dee1529 100644
--- a/src/effects.c
+++ b/src/effects.c
@@ -409,5 +409,108 @@ meta_effects_draw_box_animation (MetaScreen *screen,
XFlush (context->screen->display->xdisplay);
}
+void
+meta_effects_begin_wireframe (MetaScreen *screen,
+ const MetaRectangle *rect)
+{
+ /* Grab the X server to avoid screen dirt */
+ meta_display_grab (screen->display);
+ meta_ui_push_delay_exposes (screen->ui);
+
+ meta_effects_update_wireframe (screen, NULL, rect);
+}
+
+static void
+draw_xor_rect (MetaScreen *screen,
+ const MetaRectangle *rect)
+{
+ /* The lines in the center can't overlap the rectangle or each
+ * other, or the XOR gets reversed. So we have to draw things
+ * a bit oddly.
+ */
+ XSegment segments[8];
+ int i;
+
+#define LINE_WIDTH META_WIREFRAME_XOR_LINE_WIDTH
+
+ XDrawRectangle (screen->display->xdisplay,
+ screen->xroot,
+ screen->root_xor_gc,
+ rect->x, rect->y,
+ rect->width, rect->height);
+
+ /* Don't put lines inside small rectangles where they won't fit */
+ if (rect->width < (LINE_WIDTH * 4) ||
+ rect->height < (LINE_WIDTH * 4))
+ return;
+
+ /* Two vertical lines at 1/3 and 2/3 */
+ segments[0].x1 = rect->x + rect->width / 3;
+ segments[0].y1 = rect->y + LINE_WIDTH / 2 + LINE_WIDTH % 2;
+ segments[0].x2 = segments[0].x1;
+ segments[0].y2 = rect->y + rect->height - LINE_WIDTH / 2;
+
+ segments[1] = segments[0];
+ segments[1].x1 = rect->x + (rect->width / 3) * 2;
+ segments[1].x2 = segments[1].x1;
+
+ /* Now make two horizontal lines at 1/3 and 2/3, but not
+ * overlapping the verticals
+ */
+
+ segments[2].x1 = rect->x + LINE_WIDTH / 2 + LINE_WIDTH % 2;
+ segments[2].x2 = segments[0].x1 - LINE_WIDTH / 2;
+ segments[2].y1 = rect->y + rect->height / 3;
+ segments[2].y2 = segments[2].y1;
+
+ segments[3] = segments[2];
+ segments[3].x1 = segments[2].x2 + LINE_WIDTH;
+ segments[3].x2 = segments[1].x1 - LINE_WIDTH / 2;
+
+ segments[4] = segments[3];
+ segments[4].x1 = segments[3].x2 + LINE_WIDTH;
+ segments[4].x2 = rect->x + rect->width - LINE_WIDTH / 2;
+ /* Second horizontal line is just like the first, but
+ * shifted down
+ */
+ i = 5;
+ while (i < 8)
+ {
+ segments[i] = segments[i - 3];
+ segments[i].y1 = rect->y + (rect->height / 3) * 2;
+ segments[i].y2 = segments[i].y1;
+ ++i;
+ }
+
+ XDrawSegments (screen->display->xdisplay,
+ screen->xroot,
+ screen->root_xor_gc,
+ segments,
+ G_N_ELEMENTS (segments));
+}
+
+void
+meta_effects_update_wireframe (MetaScreen *screen,
+ const MetaRectangle *old_rect,
+ const MetaRectangle *new_rect)
+{
+ if (old_rect)
+ draw_xor_rect (screen, old_rect);
+
+ if (new_rect)
+ draw_xor_rect (screen, new_rect);
+
+ XFlush (screen->display->xdisplay);
+}
+
+void
+meta_effects_end_wireframe (MetaScreen *screen,
+ const MetaRectangle *old_rect)
+{
+ meta_effects_update_wireframe (screen, old_rect, NULL);
+
+ meta_display_ungrab (screen->display);
+ meta_ui_pop_delay_exposes (screen->ui);
+}
diff --git a/src/effects.h b/src/effects.h
index 744ffc1..82dc0c5 100644
--- a/src/effects.h
+++ b/src/effects.h
@@ -41,4 +41,12 @@ void meta_effects_draw_box_animation (MetaScreen *screen,
double seconds_duration,
MetaBoxAnimType anim_type);
+void meta_effects_begin_wireframe (MetaScreen *screen,
+ const MetaRectangle *rect);
+void meta_effects_update_wireframe (MetaScreen *screen,
+ const MetaRectangle *old_rect,
+ const MetaRectangle *new_rect);
+void meta_effects_end_wireframe (MetaScreen *screen,
+ const MetaRectangle *old_rect);
+
#endif /* META_EFFECTS_H */
diff --git a/src/frames.c b/src/frames.c
index a99c13a..3086837 100644
--- a/src/frames.c
+++ b/src/frames.c
@@ -2110,6 +2110,13 @@ get_control (MetaFrames *frames,
void
meta_frames_push_delay_exposes (MetaFrames *frames)
{
+ if (frames->expose_delay_count == 0)
+ {
+ /* Make sure we've repainted things */
+ gdk_window_process_all_updates ();
+ XFlush (gdk_display);
+ }
+
frames->expose_delay_count += 1;
}
diff --git a/src/keybindings.c b/src/keybindings.c
index 2d91fe2..3c50d39 100644
--- a/src/keybindings.c
+++ b/src/keybindings.c
@@ -27,6 +27,7 @@
#include "frame.h"
#include "place.h"
#include "prefs.h"
+#include "effects.h"
#include <X11/keysym.h>
#include <string.h>
@@ -1693,10 +1694,24 @@ process_keyboard_move_grab (MetaDisplay *display,
if (is_modifier (display, event->xkey.keycode))
return TRUE;
- meta_window_get_position (window, &x, &y);
+ if (display->grab_wireframe_active)
+ {
+ x = display->grab_wireframe_rect.x;
+ y = display->grab_wireframe_rect.y;
+ }
+ else
+ {
+ meta_window_get_position (window, &x, &y);
+ }
+ /* FIXME in wireframe mode the edge snapping is all fucked up
+ * since the edge-find routines use window->rect. Window
+ * constraints are also broken with wireframe.
+ */
smart_snap = (event->xkey.state & ShiftMask) != 0;
-
+ if (display->grab_wireframe_active)
+ smart_snap = FALSE;
+
#define SMALL_INCREMENT 1
#define NORMAL_INCREMENT 10
@@ -1709,13 +1724,18 @@ process_keyboard_move_grab (MetaDisplay *display,
if (keysym == XK_Escape)
{
- /* End move and restore to original position */
+ /* End resize and restore to original state.
+ * The move_resize is only needed when !wireframe
+ * since in wireframe we always moveresize at the end
+ * of the grab only.
+ */
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_initial_window_pos.x,
display->grab_initial_window_pos.y,
display->grab_initial_window_pos.width,
display->grab_initial_window_pos.height);
+ display->grab_was_cancelled = TRUE;
}
/* When moving by increments, we still snap to edges if the move
@@ -1729,11 +1749,14 @@ process_keyboard_move_grab (MetaDisplay *display,
case XK_KP_Prior:
case XK_Up:
case XK_KP_Up:
- edge = meta_window_find_next_horizontal_edge (window, FALSE);
y -= incr;
-
- if (smart_snap || ((edge > y) && ABS (edge - y) < incr))
- y = edge;
+
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_horizontal_edge (window, FALSE);
+ if (smart_snap || ((edge > y) && ABS (edge - y) < incr))
+ y = edge;
+ }
handled = TRUE;
break;
@@ -1741,11 +1764,14 @@ process_keyboard_move_grab (MetaDisplay *display,
case XK_KP_Next:
case XK_Down:
case XK_KP_Down:
- edge = meta_window_find_next_horizontal_edge (window, TRUE);
y += incr;
- if (smart_snap || ((edge < y) && ABS (edge - y) < incr))
- y = edge;
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_horizontal_edge (window, TRUE);
+ if (smart_snap || ((edge < y) && ABS (edge - y) < incr))
+ y = edge;
+ }
handled = TRUE;
break;
@@ -1757,11 +1783,14 @@ process_keyboard_move_grab (MetaDisplay *display,
case XK_KP_End:
case XK_Left:
case XK_KP_Left:
- edge = meta_window_find_next_vertical_edge (window, FALSE);
x -= incr;
-
- if (smart_snap || ((edge > x) && ABS (edge - x) < incr))
- x = edge;
+
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_vertical_edge (window, FALSE);
+ if (smart_snap || ((edge > x) && ABS (edge - x) < incr))
+ x = edge;
+ }
handled = TRUE;
break;
@@ -1769,18 +1798,43 @@ process_keyboard_move_grab (MetaDisplay *display,
case XK_KP_Next:
case XK_Right:
case XK_KP_Right:
- edge = meta_window_find_next_vertical_edge (window, TRUE);
x += incr;
- if (smart_snap || ((edge < x) && ABS (edge - x) < incr))
- x = edge;
+
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_vertical_edge (window, TRUE);
+ if (smart_snap || ((edge < x) && ABS (edge - x) < incr))
+ x = edge;
+ }
+
handled = TRUE;
break;
}
if (handled)
{
- meta_window_move (window, TRUE, x, y);
- meta_window_warp_pointer (window, display->grab_op);
+ meta_topic (META_DEBUG_KEYBINDINGS,
+ "Computed new window location %d,%d due to keypress\n",
+ x, y);
+ if (display->grab_wireframe_active)
+ {
+ MetaRectangle new_xor;
+
+ new_xor = display->grab_wireframe_rect;
+ new_xor.x = x;
+ new_xor.y = y;
+
+ meta_effects_update_wireframe (window->screen,
+ &display->grab_wireframe_rect,
+ &new_xor);
+ display->grab_wireframe_rect = new_xor;
+ }
+ else
+ {
+ meta_window_move (window, TRUE, x, y);
+ }
+
+ meta_window_update_keyboard_move (window);
}
return handled;
@@ -1815,13 +1869,18 @@ process_keyboard_resize_grab (MetaDisplay *display,
if (keysym == XK_Escape)
{
- /* End resize and restore to original state */
+ /* End resize and restore to original state.
+ * The move_resize is only needed when !wireframe
+ * since in wireframe we always moveresize at the end
+ * of the grab only.
+ */
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_initial_window_pos.x,
display->grab_initial_window_pos.y,
display->grab_initial_window_pos.width,
display->grab_initial_window_pos.height);
+ display->grab_was_cancelled = TRUE;
return FALSE;
}
@@ -1931,20 +1990,38 @@ process_keyboard_resize_grab (MetaDisplay *display,
if (handled)
{
- meta_window_update_resize_grab_op (window, TRUE);
+ meta_window_update_keyboard_resize (window, TRUE);
return TRUE;
- }
+ }
- meta_window_get_position (window, &orig_x, &orig_y);
- x = orig_x;
- y = orig_y;
- width = window->rect.width;
- height = window->rect.height;
+ if (display->grab_wireframe_active)
+ {
+ x = display->grab_wireframe_rect.x;
+ y = display->grab_wireframe_rect.y;
+ orig_x = x;
+ orig_y = y;
+ width = display->grab_wireframe_rect.width;
+ height = display->grab_wireframe_rect.height;
+ }
+ else
+ {
+ meta_window_get_position (window, &orig_x, &orig_y);
+ x = orig_x;
+ y = orig_y;
+ width = window->rect.width;
+ height = window->rect.height;
+ }
gravity = meta_resize_gravity_from_grab_op (display->grab_op);
-
- smart_snap = (event->xkey.state & ShiftMask) != 0;
+ /* FIXME in wireframe mode the edge snapping is all fucked up
+ * since the edge-find routines use window->rect. Window
+ * constraints are also broken with wireframe.
+ */
+ smart_snap = (event->xkey.state & ShiftMask) != 0;
+ if (display->grab_wireframe_active)
+ smart_snap = FALSE;
+
#define SMALL_INCREMENT 1
#define NORMAL_INCREMENT 10
@@ -1994,12 +2071,16 @@ process_keyboard_resize_grab (MetaDisplay *display,
case NorthWestGravity:
case NorthEastGravity:
/* Move bottom edge up */
- edge = meta_window_find_next_horizontal_edge (window, TRUE);
height -= height_inc;
- if (smart_snap || ((edge > (y+height)) &&
- ABS (edge - (y+height)) < height_inc))
- height = edge - y;
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_horizontal_edge (window, TRUE);
+
+ if (smart_snap || ((edge > (y+height)) &&
+ ABS (edge - (y+height)) < height_inc))
+ height = edge - y;
+ }
handled = TRUE;
break;
@@ -2008,11 +2089,15 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthWestGravity:
case SouthEastGravity:
/* Move top edge up */
- edge = meta_window_find_next_horizontal_edge (window, FALSE);
y -= height_inc;
-
- if (smart_snap || ((edge > y) && ABS (edge - y) < height_inc))
- y = edge;
+
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_horizontal_edge (window, FALSE);
+
+ if (smart_snap || ((edge > y) && ABS (edge - y) < height_inc))
+ y = edge;
+ }
height += (orig_y - y);
break;
@@ -2035,12 +2120,16 @@ process_keyboard_resize_grab (MetaDisplay *display,
case NorthWestGravity:
case NorthEastGravity:
/* Move bottom edge down */
- edge = meta_window_find_next_horizontal_edge (window, TRUE);
height += height_inc;
-
- if (smart_snap || ((edge < (y+height)) &&
- ABS (edge - (y+height)) < height_inc))
- height = edge - y;
+
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_horizontal_edge (window, TRUE);
+
+ if (smart_snap || ((edge < (y+height)) &&
+ ABS (edge - (y+height)) < height_inc))
+ height = edge - y;
+ }
handled = TRUE;
break;
@@ -2049,11 +2138,15 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthWestGravity:
case SouthEastGravity:
/* Move top edge down */
- edge = meta_window_find_next_horizontal_edge (window, FALSE);
y += height_inc;
-
- if (smart_snap || ((edge < y) && ABS (edge - y) < height_inc))
- y = edge;
+
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_horizontal_edge (window, FALSE);
+
+ if (smart_snap || ((edge < y) && ABS (edge - y) < height_inc))
+ y = edge;
+ }
height -= (y - orig_y);
break;
@@ -2076,11 +2169,15 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthEastGravity:
case NorthEastGravity:
/* Move left edge left */
- edge = meta_window_find_next_vertical_edge (window, TRUE);
x -= width_inc;
- if (smart_snap || ((edge > x) && ABS (edge - x) < width_inc))
- x = edge;
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_vertical_edge (window, TRUE);
+
+ if (smart_snap || ((edge > x) && ABS (edge - x) < width_inc))
+ x = edge;
+ }
width += (orig_x - x);
break;
@@ -2089,12 +2186,16 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthWestGravity:
case NorthWestGravity:
/* Move right edge left */
- edge = meta_window_find_next_vertical_edge (window, FALSE);
width -= width_inc;
- if (smart_snap || ((edge > (x+width)) &&
- ABS (edge - (x+width)) < width_inc))
- width = edge - x;
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_vertical_edge (window, FALSE);
+
+ if (smart_snap || ((edge > (x+width)) &&
+ ABS (edge - (x+width)) < width_inc))
+ width = edge - x;
+ }
handled = TRUE;
break;
@@ -2117,11 +2218,15 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthEastGravity:
case NorthEastGravity:
/* Move left edge right */
- edge = meta_window_find_next_vertical_edge (window, FALSE);
x += width_inc;
-
- if (smart_snap || ((edge < x) && ABS (edge - x) < width_inc))
- x = edge;
+
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_vertical_edge (window, FALSE);
+
+ if (smart_snap || ((edge < x) && ABS (edge - x) < width_inc))
+ x = edge;
+ }
width -= (x - orig_x);
break;
@@ -2130,12 +2235,16 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthWestGravity:
case NorthWestGravity:
/* Move right edge right */
- edge = meta_window_find_next_vertical_edge (window, TRUE);
width += width_inc;
-
- if (smart_snap || ((edge > (x+width)) &&
- ABS (edge - (x+width)) < width_inc))
- width = edge - x;
+
+ if (!display->grab_wireframe_active)
+ {
+ edge = meta_window_find_next_vertical_edge (window, TRUE);
+
+ if (smart_snap || ((edge > (x+width)) &&
+ ABS (edge - (x+width)) < width_inc))
+ width = edge - x;
+ }
handled = TRUE;
break;
@@ -2162,8 +2271,32 @@ process_keyboard_resize_grab (MetaDisplay *display,
if (handled)
{
- meta_window_move_resize (window, TRUE, x, y, width, height);
- meta_window_update_resize_grab_op (window, FALSE);
+ meta_topic (META_DEBUG_KEYBINDINGS,
+ "Computed new window location %d,%d %dx%d due to keypress\n",
+ x, y, width, height);
+
+ if (display->grab_wireframe_active)
+ {
+ MetaRectangle new_xor;
+
+ new_xor.x = x;
+ new_xor.y = y;
+ new_xor.width = width;
+ new_xor.height = height;
+
+ meta_effects_update_wireframe (window->screen,
+ &window->display->grab_wireframe_rect,
+ &new_xor);
+ window->display->grab_wireframe_rect = new_xor;
+
+ /* do this after drawing the wires, so we don't draw over it */
+ meta_window_refresh_resize_popup (window);
+ }
+ else
+ {
+ meta_window_move_resize (window, TRUE, x, y, width, height);
+ }
+ meta_window_update_keyboard_resize (window, FALSE);
}
return handled;
diff --git a/src/metacity.schemas.in b/src/metacity.schemas.in
index 4350b67..5cf9f10 100644
--- a/src/metacity.schemas.in
+++ b/src/metacity.schemas.in
@@ -257,6 +257,25 @@
</locale>
</schema>
+ <schema>
+ <key>/schemas/apps/metacity/general/reduced_resources</key>
+ <applyto>/apps/metacity/general/reduced_resources</applyto>
+ <owner>metacity</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>If true, trade off usability for less resource usage</short>
+ <long>
+ If true, metacity will give the user less feedback and
+ less sense of "direct manipulation", by using wireframes,
+ avoiding animations, or other means. This is a significant
+ reduction in usability for many users, but may allow
+ legacy applications and terminal servers to function
+ when they would otherwise be impractical.
+ </long>
+ </locale>
+ </schema>
+
<!-- Window Keybindings -->
<schema>
diff --git a/src/prefs.c b/src/prefs.c
index 9ed41bc..81af51e 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -51,6 +51,7 @@
#define KEY_APPLICATION_BASED "/apps/metacity/general/application_based"
#define KEY_DISABLE_WORKAROUNDS "/apps/metacity/general/disable_workarounds"
#define KEY_BUTTON_LAYOUT "/apps/metacity/general/button_layout"
+#define KEY_REDUCED_RESOURCES "/apps/metacity/general/reduced_resources"
#define KEY_COMMAND_PREFIX "/apps/metacity/keybinding_commands/command_"
#define KEY_SCREEN_BINDINGS_PREFIX "/apps/metacity/global_keybindings"
@@ -83,6 +84,8 @@ static gboolean auto_raise = FALSE;
static gboolean auto_raise_delay = 500;
static gboolean provide_visual_bell = TRUE;
static gboolean bell_is_audible = TRUE;
+static gboolean reduced_resources = FALSE;
+
static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_INVALID;
static MetaButtonLayout button_layout = {
{
@@ -129,6 +132,7 @@ static gboolean update_command (const char *name,
const char *value);
static gboolean update_workspace_name (const char *name,
const char *value);
+static gboolean update_reduced_resources (gboolean value);
static void change_notify (GConfClient *client,
guint cnxn_id,
@@ -372,7 +376,6 @@ meta_prefs_init (void)
cleanup_error (&err);
update_button_layout (str_val);
g_free (str_val);
-#endif /* HAVE_GCONF */
bool_val = gconf_client_get_bool (default_client, KEY_VISUAL_BELL,
&err);
@@ -388,6 +391,12 @@ meta_prefs_init (void)
update_visual_bell_type (str_val);
g_free (str_val);
+ bool_val = gconf_client_get_bool (default_client, KEY_REDUCED_RESOURCES,
+ &err);
+ cleanup_error (&err);
+ update_reduced_resources (bool_val);
+#endif /* HAVE_GCONF */
+
/* Load keybindings prefs */
init_bindings ();
@@ -733,6 +742,22 @@ change_notify (GConfClient *client,
if (update_visual_bell_type (str))
queue_changed (META_PREF_VISUAL_BELL_TYPE);
}
+ else if (strcmp (key, KEY_REDUCED_RESOURCES) == 0)
+ {
+ gboolean b;
+
+ if (value && value->type != GCONF_VALUE_BOOL)
+ {
+ meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
+ KEY_REDUCED_RESOURCES);
+ goto out;
+ }
+
+ b = value ? gconf_value_get_bool (value) : reduced_resources;
+
+ if (update_reduced_resources (b))
+ queue_changed (META_PREF_REDUCED_RESOURCES);
+ }
else
{
meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
@@ -1239,6 +1264,16 @@ update_auto_raise_delay (int value)
return old != auto_raise_delay;
}
+
+static gboolean
+update_reduced_resources (gboolean value)
+{
+ gboolean old = reduced_resources;
+
+ reduced_resources = value;
+
+ return old != reduced_resources;
+}
#endif /* HAVE_GCONF */
#ifdef WITH_VERBOSE_MODE
@@ -1305,6 +1340,10 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_VISUAL_BELL_TYPE:
return "VISUAL_BELL_TYPE";
break;
+
+ case META_PREF_REDUCED_RESOURCES:
+ return "REDUCED_RESOURCES";
+ break;
}
return "(unknown)";
@@ -1974,6 +2013,12 @@ meta_prefs_get_auto_raise_delay ()
return auto_raise_delay;
}
+gboolean
+meta_prefs_get_reduced_resources ()
+{
+ return reduced_resources;
+}
+
MetaKeyBindingAction
meta_prefs_get_keybinding_action (const char *name)
{
diff --git a/src/prefs.h b/src/prefs.h
index 18a20df..c0a0bc6 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -45,7 +45,8 @@ typedef enum
META_PREF_WORKSPACE_NAMES,
META_PREF_VISUAL_BELL,
META_PREF_AUDIBLE_BELL,
- META_PREF_VISUAL_BELL_TYPE
+ META_PREF_VISUAL_BELL_TYPE,
+ META_PREF_REDUCED_RESOURCES
} MetaPreference;
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@@ -69,6 +70,7 @@ gboolean meta_prefs_get_application_based (void);
gboolean meta_prefs_get_disable_workarounds (void);
gboolean meta_prefs_get_auto_raise (void);
int meta_prefs_get_auto_raise_delay (void);
+gboolean meta_prefs_get_reduced_resources (void);
const char* meta_prefs_get_command (int i);
diff --git a/src/run-metacity.sh b/src/run-metacity.sh
index 98ccbf7..e0d9265 100755
--- a/src/run-metacity.sh
+++ b/src/run-metacity.sh
@@ -1,11 +1,11 @@
#! /bin/bash
if test -z "$XNEST_DISPLAY"; then
- XNEST_DISPLAY=:1
+ XNEST_DISPLAY=:8
fi
if test -z "$CLIENT_DISPLAY"; then
- CLIENT_DISPLAY=:1
+ CLIENT_DISPLAY=:8
fi
if test -z "$METACITY_DISPLAY"; then
diff --git a/src/screen.c b/src/screen.c
index 348d467..18647d3 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -538,10 +538,23 @@ meta_screen_new (MetaDisplay *display,
screen->starting_corner = META_SCREEN_TOPLEFT;
screen->showing_desktop = FALSE;
+
+ {
+ XGCValues gc_values;
+
+ gc_values.subwindow_mode = IncludeInferiors;
+ gc_values.function = GXinvert;
+ gc_values.line_width = META_WIREFRAME_XOR_LINE_WIDTH;
+
+ screen->root_xor_gc = XCreateGC (screen->display->xdisplay,
+ screen->xroot,
+ GCSubwindowMode | GCFunction | GCLineWidth,
+ &gc_values);
+ }
screen->xinerama_infos = NULL;
screen->n_xinerama_infos = 0;
- screen->last_xinerama_index = 0;
+ screen->last_xinerama_index = 0;
reload_xinerama_infos (screen);
@@ -679,6 +692,9 @@ meta_screen_free (MetaScreen *screen)
if (screen->work_area_idle != 0)
g_source_remove (screen->work_area_idle);
+
+ XFreeGC (screen->display->xdisplay,
+ screen->root_xor_gc);
g_free (screen->screen_name);
g_free (screen);
diff --git a/src/screen.h b/src/screen.h
index 64fa494..24b29ab 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -56,6 +56,8 @@ typedef enum
META_SCREEN_RIGHT
} MetaScreenDirection;
+#define META_WIREFRAME_XOR_LINE_WIDTH 5
+
struct _MetaScreen
{
MetaDisplay *display;
@@ -108,6 +110,9 @@ struct _MetaScreen
guint showing_desktop : 1;
int closing;
+
+ /* gc for XOR on root window */
+ GC root_xor_gc;
};
MetaScreen* meta_screen_new (MetaDisplay *display,
diff --git a/src/window.c b/src/window.c
index 9bb5b3e..edddc27 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1206,6 +1206,14 @@ window_should_be_showing (MetaWindow *window)
showing = FALSE;
}
+#if 0
+ /* 5. See if we're drawing wireframe
+ */
+ if (window->display->grab_window == window &&
+ window->display->grab_wireframe_active)
+ showing = FALSE;
+#endif
+
return showing;
}
@@ -1230,7 +1238,8 @@ implement_showing (MetaWindow *window,
* if we are mapped now, we are supposed to
* be minimized, and we are on the current workspace.
*/
- if (on_workspace && window->minimized && window->mapped)
+ if (on_workspace && window->minimized && window->mapped &&
+ !meta_prefs_get_reduced_resources ())
{
MetaRectangle icon_rect, window_rect;
gboolean result;
@@ -1856,7 +1865,7 @@ meta_window_unmaximize (MetaWindow *window)
if (meta_grab_op_is_moving (window->display->grab_op) &&
window->display->grab_window == window)
{
- window->display->grab_initial_window_pos = window->saved_rect;
+ window->display->grab_anchor_window_pos = window->saved_rect;
}
meta_window_move_resize (window,
@@ -5620,7 +5629,7 @@ check_moveresize_frequency (MetaWindow *window)
window->display->grab_last_moveresize_time = current_time;
meta_topic (META_DEBUG_RESIZING,
- " Doing move/resize now (%g of %g seconds elapsed)\n",
+ " Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
elapsed / 1000.0, 1.0 / max_resizes_per_second);
return TRUE;
@@ -5639,12 +5648,20 @@ update_move (MetaWindow *window,
window->display->grab_latest_motion_x = x;
window->display->grab_latest_motion_y = y;
- dx = x - window->display->grab_initial_root_x;
- dy = y - window->display->grab_initial_root_y;
+ dx = x - window->display->grab_anchor_root_x;
+ dy = y - window->display->grab_anchor_root_y;
- new_x = window->display->grab_initial_window_pos.x + dx;
- new_y = window->display->grab_initial_window_pos.y + dy;
+ new_x = window->display->grab_anchor_window_pos.x + dx;
+ new_y = window->display->grab_anchor_window_pos.y + dy;
+ meta_verbose ("x,y = %d,%d anchor ptr %d,%d anchor pos %d,%d dx,dy %d,%d\n",
+ x, y,
+ window->display->grab_anchor_root_x,
+ window->display->grab_anchor_root_y,
+ window->display->grab_anchor_window_pos.x,
+ window->display->grab_anchor_window_pos.y,
+ dx, dy);
+
/* shake loose (unmaximize) maximized window if dragged beyond the threshold
* in the Y direction. You can't pull a window loose via X motion.
*/
@@ -5733,14 +5750,33 @@ update_move (MetaWindow *window,
if (window->maximized)
return;
- if (mask & ShiftMask)
+ if (window->display->grab_wireframe_active)
{
- /* snap to edges */
- new_x = meta_window_find_nearest_vertical_edge (window, new_x);
- new_y = meta_window_find_nearest_horizontal_edge (window, new_y);
- }
+ /* FIXME Horribly broken, does not honor position
+ * constraints
+ */
+ MetaRectangle new_xor;
+ new_xor = window->display->grab_wireframe_rect;
+ new_xor.x = new_x;
+ new_xor.y = new_y;
- meta_window_move (window, TRUE, new_x, new_y);
+ meta_effects_update_wireframe (window->screen,
+ &window->display->grab_wireframe_rect,
+ &new_xor);
+ window->display->grab_wireframe_rect = new_xor;
+ }
+ else
+ {
+ /* FIXME, edge snapping broken in wireframe mode */
+ if (mask & ShiftMask)
+ {
+ /* snap to edges */
+ new_x = meta_window_find_nearest_vertical_edge (window, new_x);
+ new_y = meta_window_find_nearest_horizontal_edge (window, new_y);
+ }
+
+ meta_window_move (window, TRUE, new_x, new_y);
+ }
}
static void
@@ -5751,16 +5787,21 @@ update_resize (MetaWindow *window,
int new_w, new_h;
int gravity;
MetaRectangle old;
+ int new_x, new_y;
window->display->grab_latest_motion_x = x;
window->display->grab_latest_motion_y = y;
- dx = x - window->display->grab_initial_root_x;
- dy = y - window->display->grab_initial_root_y;
+ dx = x - window->display->grab_anchor_root_x;
+ dy = y - window->display->grab_anchor_root_y;
- new_w = window->display->grab_initial_window_pos.width;
- new_h = window->display->grab_initial_window_pos.height;
+ new_w = window->display->grab_anchor_window_pos.width;
+ new_h = window->display->grab_anchor_window_pos.height;
+ /* FIXME this is only used in wireframe mode */
+ new_x = window->display->grab_anchor_window_pos.x;
+ new_y = window->display->grab_anchor_window_pos.y;
+
switch (window->display->grab_op)
{
case META_GRAB_OP_RESIZING_SE:
@@ -5779,6 +5820,7 @@ update_resize (MetaWindow *window,
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
case META_GRAB_OP_KEYBOARD_RESIZING_W:
new_w -= dx;
+ new_x += dx;
break;
default:
@@ -5803,6 +5845,7 @@ update_resize (MetaWindow *window,
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
new_h -= dy;
+ new_y += dy;
break;
default:
break;
@@ -5812,12 +5855,42 @@ update_resize (MetaWindow *window,
return;
old = window->rect;
-
+
/* compute gravity of client during operation */
gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
g_assert (gravity >= 0);
- meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
+ if (window->display->grab_wireframe_active)
+ {
+ /* FIXME This is crap. For example, the wireframe isn't
+ * constrained in the way that a real resize would be. An
+ * obvious elegant solution is to unmap the window during
+ * wireframe, but still resize it; however, that probably
+ * confuses broken clients that have problems with opaque
+ * resize, they probably don't track their visibility.
+ */
+ MetaRectangle new_xor;
+
+ if ((new_x + new_w <= new_x) || (new_y + new_h <= new_y))
+ return;
+
+ new_xor.x = new_x;
+ new_xor.y = new_y;
+ new_xor.width = new_w;
+ new_xor.height = new_h;
+
+ meta_effects_update_wireframe (window->screen,
+ &window->display->grab_wireframe_rect,
+ &new_xor);
+ window->display->grab_wireframe_rect = new_xor;
+
+ /* do this after drawing the wires, so we don't draw over it */
+ meta_window_refresh_resize_popup (window);
+ }
+ else
+ {
+ meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
+ }
/* If we don't actually resize the window, we clear the timestamp,
* so we'll quickly try again. Otherwise you get "stuck" because
@@ -6219,6 +6292,13 @@ meta_window_refresh_resize_popup (MetaWindow *window)
if (window->display->grab_window != window)
return;
+ /* FIXME for now we bail out when doing wireframe, because our
+ * server grab keeps us from being able to redraw the stuff
+ * underneath the resize popup.
+ */
+ if (window->display->grab_wireframe_active)
+ return;
+
switch (window->display->grab_op)
{
case META_GRAB_OP_RESIZING_SE:
@@ -6257,7 +6337,7 @@ meta_window_refresh_resize_popup (MetaWindow *window)
if (window->display->grab_resize_popup != NULL)
{
int gravity;
- int x, y;
+ int x, y, width, height;
MetaFrameGeometry fgeom;
if (window->frame)
@@ -6273,13 +6353,24 @@ meta_window_refresh_resize_popup (MetaWindow *window)
gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
g_assert (gravity >= 0);
- meta_window_get_position (window, &x, &y);
+ if (window->display->grab_wireframe_active)
+ {
+ x = window->display->grab_wireframe_rect.x;
+ y = window->display->grab_wireframe_rect.y;
+ width = window->display->grab_wireframe_rect.width;
+ height = window->display->grab_wireframe_rect.height;
+ }
+ else
+ {
+ meta_window_get_position (window, &x, &y);
+ width = window->rect.width;
+ height = window->rect.height;
+ }
meta_ui_resize_popup_set (window->display->grab_resize_popup,
gravity,
x, y,
- window->rect.width,
- window->rect.height,
+ width, height,
window->size_hints.base_width,
window->size_hints.base_height,
window->size_hints.min_width,
@@ -6406,53 +6497,70 @@ meta_window_is_ancestor_of_transient (MetaWindow *window,
return d.found;
}
+/* Warp pointer to location appropriate for grab,
+ * return root coordinates where pointer ended up.
+ */
static gboolean
-warp_pointer (MetaWindow *window,
- MetaGrabOp grab_op,
- int *x,
- int *y)
+warp_grab_pointer (MetaWindow *window,
+ MetaGrabOp grab_op,
+ int *x,
+ int *y)
{
+ MetaRectangle rect;
+
+ /* We may not have done begin_grab_op yet, i.e. may not be in a grab
+ */
+
+ if (window == window->display->grab_window &&
+ window->display->grab_wireframe_active)
+ rect = window->display->grab_wireframe_rect;
+ else
+ {
+ rect = window->rect;
+ meta_window_get_position (window, &rect.x, &rect.y);
+ }
+
switch (grab_op)
{
case META_GRAB_OP_KEYBOARD_MOVING:
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- *x = window->rect.width / 2;
- *y = window->rect.height / 2;
+ *x = rect.width / 2;
+ *y = rect.height / 2;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_S:
- *x = window->rect.width / 2;
- *y = window->rect.height;
+ *x = rect.width / 2;
+ *y = rect.height;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_N:
- *x = window->rect.width / 2;
+ *x = rect.width / 2;
*y = 0;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_W:
*x = 0;
- *y = window->rect.height / 2;
+ *y = rect.height / 2;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_E:
- *x = window->rect.width;
- *y = window->rect.height / 2;
+ *x = rect.width;
+ *y = rect.height / 2;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
- *x = window->rect.width;
- *y = window->rect.height;
+ *x = rect.width;
+ *y = rect.height;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- *x = window->rect.width;
+ *x = rect.width;
*y = 0;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
*x = 0;
- *y = window->rect.height;
+ *y = rect.height;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
@@ -6464,45 +6572,45 @@ warp_pointer (MetaWindow *window,
return FALSE;
}
+ *x += rect.x;
+ *y += rect.y;
+
meta_error_trap_push_with_return (window->display);
+
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Warping pointer to %d,%d with window at %d,%d\n",
+ *x, *y, rect.x, rect.y);
XWarpPointer (window->display->xdisplay,
None,
- window->xwindow,
+ window->screen->xroot,
0, 0, 0, 0,
- *x,
- *y);
+ *x, *y);
if (meta_error_trap_pop_with_return (window->display, FALSE) != Success)
{
- meta_verbose ("Failed to warp pointer for window %s\n", window->desc);
+ meta_verbose ("Failed to warp pointer for window %s\n",
+ window->desc);
return FALSE;
}
-
+
return TRUE;
}
-gboolean
-meta_window_warp_pointer (MetaWindow *window,
- MetaGrabOp grab_op)
-{
- int x, y;
-
- return warp_pointer (window, grab_op, &x, &y);
-}
-
void
meta_window_begin_grab_op (MetaWindow *window,
MetaGrabOp op,
Time timestamp)
{
- int x, y, x_offset, y_offset;
-
- meta_window_get_position (window, &x, &y);
+ int x, y;
+ gulong grab_start_serial;
+ grab_start_serial = XNextRequest (window->display->xdisplay);
+
meta_window_raise (window);
- warp_pointer (window, op, &x_offset, &y_offset);
+ warp_grab_pointer (window,
+ op, &x, &y);
meta_display_begin_grab_op (window->display,
window->screen,
@@ -6510,31 +6618,50 @@ meta_window_begin_grab_op (MetaWindow *window,
op,
FALSE, 0, 0,
timestamp,
- x + x_offset,
- y + y_offset);
+ x, y);
+
+ /* We override the one set in display_begin_grab_op since we
+ * did additional stuff as part of the grabbing process
+ */
+ window->display->grab_start_serial = grab_start_serial;
}
void
-meta_window_update_resize_grab_op (MetaWindow *window,
- gboolean update_cursor)
+meta_window_update_keyboard_resize (MetaWindow *window,
+ gboolean update_cursor)
{
- int x, y, x_offset, y_offset;
-
- meta_window_get_position (window, &x, &y);
+ int x, y;
- warp_pointer (window, window->display->grab_op, &x_offset, &y_offset);
+ warp_grab_pointer (window,
+ window->display->grab_op,
+ &x, &y);
- /* As we warped the pointer, we have to reset the apparent
- * initial window state, since if the mouse moves we want
- * to use those events to do the right thing.
- */
- if (window->display->grab_window == window)
- {
- window->display->grab_initial_root_x = x + x_offset;
- window->display->grab_initial_root_y = y + y_offset;
-
- window->display->grab_initial_window_pos = window->rect;
- }
+ {
+ /* As we warped the pointer, we have to reset the anchor state,
+ * since if the mouse moves we want to use those events to do the
+ * right thing. Also, this means that the motion notify
+ * from the pointer warp comes back as a no-op.
+ */
+ int dx, dy;
+
+ dx = x - window->display->grab_anchor_root_x;
+ dy = y - window->display->grab_anchor_root_y;
+
+ window->display->grab_anchor_root_x += dx;
+ window->display->grab_anchor_root_y += dy;
+ if (window->display->grab_wireframe_active)
+ {
+ window->display->grab_anchor_window_pos =
+ window->display->grab_wireframe_rect;
+ }
+ else
+ {
+ window->display->grab_anchor_window_pos = window->rect;
+ meta_window_get_position (window,
+ &window->display->grab_anchor_window_pos.x,
+ &window->display->grab_anchor_window_pos.y);
+ }
+ }
if (update_cursor)
{
@@ -6548,6 +6675,16 @@ meta_window_update_resize_grab_op (MetaWindow *window,
}
void
+meta_window_update_keyboard_move (MetaWindow *window)
+{
+ int x, y;
+
+ warp_grab_pointer (window,
+ window->display->grab_op,
+ &x, &y);
+}
+
+void
meta_window_update_layer (MetaWindow *window)
{
MetaGroup *group;
diff --git a/src/window.h b/src/window.h
index 3b36872..91f3711 100644
--- a/src/window.h
+++ b/src/window.h
@@ -469,15 +469,13 @@ void meta_window_foreach_ancestor (MetaWindow *window,
MetaWindowForeachFunc func,
void *data);
-gboolean meta_window_warp_pointer (MetaWindow *window,
- MetaGrabOp grab_op);
-
void meta_window_begin_grab_op (MetaWindow *window,
MetaGrabOp op,
Time timestamp);
-void meta_window_update_resize_grab_op (MetaWindow *window,
- gboolean update_cursor);
+void meta_window_update_keyboard_resize (MetaWindow *window,
+ gboolean update_cursor);
+void meta_window_update_keyboard_move (MetaWindow *window);
void meta_window_update_layer (MetaWindow *window);