summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-10-12 06:25:38 +0000
committerHavoc Pennington <hp@src.gnome.org>2003-10-12 06:25:38 +0000
commite98fad3e62f9aa4d6c899f773b81687eeac40248 (patch)
tree69efe13e78cb669495d4b6ad8d6efe22f87631c7 /src
parent6628acb59c697d6317b87dddd44a26ecea698ba3 (diff)
downloadmetacity-e98fad3e62f9aa4d6c899f773b81687eeac40248.tar.gz
Merge reduced_resources mode patch from the branch. Offers wireframe and
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
Diffstat (limited to 'src')
-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
14 files changed, 692 insertions, 161 deletions
diff --git a/src/display.c b/src/display.c
index c0986769..719789c6 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 f96253d6..d6d34954 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 18fa5947..dee15296 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 744ffc12..82dc0c51 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 a99c13aa..3086837e 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 2d91fe2c..3c50d390 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 4350b67a..5cf9f103 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 9ed41bcd..81af51e3 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 18a20df3..c0a0bc66 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 98ccbf74..e0d9265a 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 348d467b..18647d3a 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 64fa4948..24b29ab7 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 9bb5b3e5..edddc27e 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 3b36872e..91f3711c 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);