diff --git a/ChangeLog b/ChangeLog index 98d8a24f1..2a70e5674 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2002-08-08 Craig Black + + Patch to provide extra cues when using the window menu + move and resize items, #85724. + + * src/common.h: add new cursors + + * src/display.c: (grab_op_is_mouse) + (meta_display_create_x_cursor), (xcursor_for_op), + (meta_display_set_grab_op_cursor), + (meta_display_begin_grab_op): + The keyboard move and resize grab ops now also use the mouse. + Allow the grab cursor to be changed during the grab op. + Hold onto the initial grab position in case of reset. + + * src/display.h: save the initial grab position + + * src/keybindings.c: (process_keyboard_move_grab), + (process_keyboard_resize_grab), (handle_begin_move), + (handle_begin_resize): + The keyboard move and resize grab ops now also use the mouse. + + * src/window.c: (meta_window_client_message), (menu_callback), + (update_move), (update_resize), + (meta_window_handle_mouse_grab_op_event), (warp_pointer), + (meta_window_warp_pointer), (meta_window_begin_grab_op), + (meta_window_update_resize_grab_op): + When moving or resizing a window use the last grab position + in computing change increment. + Provide support for warping the mouse pointer. + + * src/window.h: new warp pointer and grab op helper functions + 2002-08-08 Craig Black * src/display.h: update comment diff --git a/src/common.h b/src/common.h index dc54bbe04..9e59fa8cf 100644 --- a/src/common.h +++ b/src/common.h @@ -128,7 +128,9 @@ typedef enum META_CURSOR_SE_RESIZE, META_CURSOR_SW_RESIZE, META_CURSOR_NE_RESIZE, - META_CURSOR_NW_RESIZE + META_CURSOR_NW_RESIZE, + META_CURSOR_MOVE_WINDOW, + META_CURSOR_RESIZE_WINDOW } MetaCursor; diff --git a/src/display.c b/src/display.c index 00ba3fed7..a47b2a484 100644 --- a/src/display.c +++ b/src/display.c @@ -803,6 +803,16 @@ grab_op_is_mouse (MetaGrabOp op) case META_GRAB_OP_RESIZING_NW: case META_GRAB_OP_RESIZING_W: case META_GRAB_OP_RESIZING_E: + case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: + case META_GRAB_OP_KEYBOARD_RESIZING_S: + case META_GRAB_OP_KEYBOARD_RESIZING_N: + case META_GRAB_OP_KEYBOARD_RESIZING_W: + case META_GRAB_OP_KEYBOARD_RESIZING_E: + case META_GRAB_OP_KEYBOARD_RESIZING_SE: + case META_GRAB_OP_KEYBOARD_RESIZING_NE: + case META_GRAB_OP_KEYBOARD_RESIZING_SW: + case META_GRAB_OP_KEYBOARD_RESIZING_NW: + case META_GRAB_OP_KEYBOARD_MOVING: return TRUE; break; @@ -2180,6 +2190,12 @@ meta_display_create_x_cursor (MetaDisplay *display, case META_CURSOR_NW_RESIZE: glyph = XC_top_left_corner; break; + case META_CURSOR_MOVE_WINDOW: + glyph = XC_plus; + break; + case META_CURSOR_RESIZE_WINDOW: + glyph = XC_fleur; + break; default: g_assert_not_reached (); @@ -2201,29 +2217,43 @@ xcursor_for_op (MetaDisplay *display, switch (op) { case META_GRAB_OP_RESIZING_SE: + case META_GRAB_OP_KEYBOARD_RESIZING_SE: cursor = META_CURSOR_SE_RESIZE; break; case META_GRAB_OP_RESIZING_S: + case META_GRAB_OP_KEYBOARD_RESIZING_S: cursor = META_CURSOR_SOUTH_RESIZE; break; case META_GRAB_OP_RESIZING_SW: + case META_GRAB_OP_KEYBOARD_RESIZING_SW: cursor = META_CURSOR_SW_RESIZE; break; case META_GRAB_OP_RESIZING_N: + case META_GRAB_OP_KEYBOARD_RESIZING_N: cursor = META_CURSOR_NORTH_RESIZE; break; case META_GRAB_OP_RESIZING_NE: + case META_GRAB_OP_KEYBOARD_RESIZING_NE: cursor = META_CURSOR_NE_RESIZE; break; case META_GRAB_OP_RESIZING_NW: + case META_GRAB_OP_KEYBOARD_RESIZING_NW: cursor = META_CURSOR_NW_RESIZE; break; case META_GRAB_OP_RESIZING_W: + case META_GRAB_OP_KEYBOARD_RESIZING_W: cursor = META_CURSOR_WEST_RESIZE; break; case META_GRAB_OP_RESIZING_E: + case META_GRAB_OP_KEYBOARD_RESIZING_E: cursor = META_CURSOR_EAST_RESIZE; break; + case META_GRAB_OP_KEYBOARD_MOVING: + cursor = META_CURSOR_MOVE_WINDOW; + break; + case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: + cursor = META_CURSOR_RESIZE_WINDOW; + break; default: break; @@ -2232,6 +2262,61 @@ xcursor_for_op (MetaDisplay *display, return meta_display_create_x_cursor (display, cursor); } +void +meta_display_set_grab_op_cursor (MetaDisplay *display, + MetaGrabOp op, + gboolean change_pointer, + Window grab_xwindow, + Time timestamp) +{ + Cursor cursor; + + cursor = xcursor_for_op (display, op); + +#define GRAB_MASK (PointerMotionMask | PointerMotionHintMask | \ + ButtonPressMask | ButtonReleaseMask) + + meta_error_trap_push (display); + + if (change_pointer) + { + XChangeActivePointerGrab (display->xdisplay, + GRAB_MASK, + cursor, + timestamp); + + meta_topic (META_DEBUG_WINDOW_OPS, + "Changed pointer with XChangeActivePointerGrab()\n"); + } + else + { + if (XGrabPointer (display->xdisplay, + grab_xwindow, + False, + GRAB_MASK, + GrabModeAsync, GrabModeAsync, + None, + cursor, + timestamp) == GrabSuccess) + { + display->grab_have_pointer = TRUE; + meta_topic (META_DEBUG_WINDOW_OPS, + "XGrabPointer() returned GrabSuccess\n"); + } + } + + if (meta_error_trap_pop (display) != Success) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Error trapped from XGrabPointer()\n"); + if (display->grab_have_pointer) + display->grab_have_pointer = FALSE; + } +#undef GRAB_MASK + + XFreeCursor (display->xdisplay, cursor); +} + gboolean meta_display_begin_grab_op (MetaDisplay *display, MetaScreen *screen, @@ -2245,7 +2330,6 @@ meta_display_begin_grab_op (MetaDisplay *display, int root_y) { Window grab_xwindow; - Cursor cursor; meta_topic (META_DEBUG_WINDOW_OPS, "Doing grab op %d on window %s button %d pointer already grabbed: %d\n", @@ -2273,35 +2357,7 @@ meta_display_begin_grab_op (MetaDisplay *display, if (pointer_already_grabbed) display->grab_have_pointer = TRUE; - cursor = xcursor_for_op (display, op); - -#define GRAB_MASK (PointerMotionMask | PointerMotionHintMask | \ - ButtonPressMask | ButtonReleaseMask) - - meta_error_trap_push (display); - if (XGrabPointer (display->xdisplay, - grab_xwindow, - False, - GRAB_MASK, - GrabModeAsync, GrabModeAsync, - None, - cursor, - timestamp) == GrabSuccess) - { - display->grab_have_pointer = TRUE; - meta_topic (META_DEBUG_WINDOW_OPS, - "XGrabPointer() returned GrabSuccess\n"); - } - if (meta_error_trap_pop (display) != Success) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Error trapped from XGrabPointer()\n"); - if (display->grab_have_pointer) - display->grab_have_pointer = FALSE; - } -#undef GRAB_MASK - - XFreeCursor (display->xdisplay, cursor); + meta_display_set_grab_op_cursor (display, op, FALSE, grab_xwindow, timestamp); if (!display->grab_have_pointer) { @@ -2336,14 +2392,17 @@ meta_display_begin_grab_op (MetaDisplay *display, display->grab_xwindow = grab_xwindow; display->grab_button = button; display->grab_mask = modmask; - display->grab_root_x = root_x; - display->grab_root_y = root_y; + display->grab_initial_root_x = root_x; + display->grab_initial_root_y = root_y; + display->grab_current_root_x = root_x; + display->grab_current_root_y = root_y; if (display->grab_window) { display->grab_initial_window_pos = display->grab_window->rect; meta_window_get_position (display->grab_window, &display->grab_initial_window_pos.x, &display->grab_initial_window_pos.y); + display->grab_current_window_pos = display->grab_initial_window_pos; } meta_topic (META_DEBUG_WINDOW_OPS, diff --git a/src/display.h b/src/display.h index 95acc6bc5..552a9473c 100644 --- a/src/display.h +++ b/src/display.h @@ -209,12 +209,15 @@ struct _MetaDisplay MetaWindow *grab_window; Window grab_xwindow; int grab_button; - int grab_root_x; - int grab_root_y; + int grab_initial_root_x; + int grab_initial_root_y; + int grab_current_root_x; + int grab_current_root_y; gulong grab_mask; guint grab_have_pointer : 1; guint grab_have_keyboard : 1; MetaRectangle grab_initial_window_pos; + MetaRectangle grab_current_window_pos; MetaResizePopup *grab_resize_popup; @@ -285,6 +288,12 @@ MetaWorkspace* meta_display_get_workspace_by_screen_index (MetaDisplay *displa Cursor meta_display_create_x_cursor (MetaDisplay *display, MetaCursor cursor); +void meta_display_set_grab_op_cursor (MetaDisplay *display, + MetaGrabOp op, + gboolean change_pointer, + Window grab_xwindow, + Time timestamp); + gboolean meta_display_begin_grab_op (MetaDisplay *display, MetaScreen *screen, MetaWindow *window, diff --git a/src/keybindings.c b/src/keybindings.c index bb8b44c15..ab838cca5 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -1472,7 +1472,10 @@ process_keyboard_move_grab (MetaDisplay *display, } if (handled) - meta_window_move (window, TRUE, x, y); + { + meta_window_move (window, TRUE, x, y); + meta_window_warp_pointer (window, display->grab_op); + } return handled; } @@ -1513,7 +1516,7 @@ process_keyboard_resize_grab (MetaDisplay *display, display->grab_initial_window_pos.width, display->grab_initial_window_pos.height); - return TRUE; + return FALSE; } switch (display->grab_op) @@ -1620,7 +1623,10 @@ process_keyboard_resize_grab (MetaDisplay *display, } if (handled) - return TRUE; + { + meta_window_update_resize_grab_op (window, TRUE); + return TRUE; + } meta_window_get_position (window, &orig_x, &orig_y); x = orig_x; @@ -1848,7 +1854,10 @@ process_keyboard_resize_grab (MetaDisplay *display, width = 1; if (handled) - meta_window_move_resize (window, TRUE, x, y, width, height); + { + meta_window_move_resize (window, TRUE, x, y, width, height); + meta_window_update_resize_grab_op (window, FALSE); + } return handled; } @@ -2465,14 +2474,9 @@ handle_begin_move (MetaDisplay *display, { if (window) { - meta_window_raise (window); - meta_display_begin_grab_op (window->display, - window->screen, - window, - META_GRAB_OP_KEYBOARD_MOVING, - FALSE, 0, 0, - event->xkey.time, - 0, 0); + meta_window_begin_grab_op (window, + META_GRAB_OP_KEYBOARD_MOVING, + event->xkey.time); } } @@ -2484,14 +2488,9 @@ handle_begin_resize (MetaDisplay *display, { if (window) { - meta_window_raise (window); - meta_display_begin_grab_op (window->display, - window->screen, - window, - META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN, - FALSE, 0, 0, - event->xkey.time, - 0, 0); + meta_window_begin_grab_op (window, + META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN, + event->xkey.time); } } diff --git a/src/window.c b/src/window.c index 66d08d259..aedcfcb13 100644 --- a/src/window.c +++ b/src/window.c @@ -3418,14 +3418,10 @@ meta_window_client_message (MetaWindow *window, ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) || (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN))) { - meta_window_raise (window); - meta_display_begin_grab_op (window->display, - window->screen, - window, - op, - FALSE, 0, 0, - meta_display_get_current_time (window->display), - 0, 0); + + meta_window_begin_grab_op (window, + op, + meta_display_get_current_time (window->display)); } else if (op != META_GRAB_OP_NONE && ((window->has_move_func && op == META_GRAB_OP_MOVING) || @@ -5679,25 +5675,15 @@ menu_callback (MetaWindowMenu *menu, break; case META_MENU_OP_MOVE: - meta_window_raise (window); - meta_display_begin_grab_op (window->display, - window->screen, - window, - META_GRAB_OP_KEYBOARD_MOVING, - FALSE, 0, 0, - meta_display_get_current_time (window->display), - 0, 0); + meta_window_begin_grab_op (window, + META_GRAB_OP_KEYBOARD_MOVING, + meta_display_get_current_time (window->display)); break; case META_MENU_OP_RESIZE: - meta_window_raise (window); - meta_display_begin_grab_op (window->display, - window->screen, - window, - META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN, - FALSE, 0, 0, - meta_display_get_current_time (window->display), - 0, 0); + meta_window_begin_grab_op (window, + META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN, + meta_display_get_current_time (window->display)); break; case 0: @@ -5821,11 +5807,11 @@ update_move (MetaWindow *window, int dx, dy; int new_x, new_y; - dx = x - window->display->grab_root_x; - dy = y - window->display->grab_root_y; + dx = x - window->display->grab_current_root_x; + dy = y - window->display->grab_current_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_current_window_pos.x + dx; + new_y = window->display->grab_current_window_pos.y + dy; if (mask & ShiftMask) { @@ -5845,23 +5831,29 @@ update_resize (MetaWindow *window, int new_w, new_h; int gravity; - dx = x - window->display->grab_root_x; - dy = y - window->display->grab_root_y; + dx = x - window->display->grab_current_root_x; + dy = y - window->display->grab_current_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_current_window_pos.width; + new_h = window->display->grab_current_window_pos.height; switch (window->display->grab_op) { case META_GRAB_OP_RESIZING_SE: case META_GRAB_OP_RESIZING_NE: case META_GRAB_OP_RESIZING_E: + case META_GRAB_OP_KEYBOARD_RESIZING_SE: + case META_GRAB_OP_KEYBOARD_RESIZING_NE: + case META_GRAB_OP_KEYBOARD_RESIZING_E: new_w += dx; break; case META_GRAB_OP_RESIZING_NW: case META_GRAB_OP_RESIZING_SW: case META_GRAB_OP_RESIZING_W: + case META_GRAB_OP_KEYBOARD_RESIZING_NW: + case META_GRAB_OP_KEYBOARD_RESIZING_SW: + case META_GRAB_OP_KEYBOARD_RESIZING_W: new_w -= dx; break; @@ -5874,12 +5866,18 @@ update_resize (MetaWindow *window, case META_GRAB_OP_RESIZING_SE: case META_GRAB_OP_RESIZING_S: case META_GRAB_OP_RESIZING_SW: + case META_GRAB_OP_KEYBOARD_RESIZING_SE: + case META_GRAB_OP_KEYBOARD_RESIZING_S: + case META_GRAB_OP_KEYBOARD_RESIZING_SW: new_h += dy; break; case META_GRAB_OP_RESIZING_N: case META_GRAB_OP_RESIZING_NE: case META_GRAB_OP_RESIZING_NW: + case META_GRAB_OP_KEYBOARD_RESIZING_N: + case META_GRAB_OP_KEYBOARD_RESIZING_NE: + case META_GRAB_OP_KEYBOARD_RESIZING_NW: new_h -= dy; break; default: @@ -5903,6 +5901,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, switch (window->display->grab_op) { case META_GRAB_OP_MOVING: + case META_GRAB_OP_KEYBOARD_MOVING: update_move (window, event->xbutton.state, event->xbutton.x_root, event->xbutton.y_root); break; @@ -5915,6 +5914,14 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, case META_GRAB_OP_RESIZING_SW: case META_GRAB_OP_RESIZING_NE: case META_GRAB_OP_RESIZING_NW: + case META_GRAB_OP_KEYBOARD_RESIZING_S: + case META_GRAB_OP_KEYBOARD_RESIZING_N: + case META_GRAB_OP_KEYBOARD_RESIZING_W: + case META_GRAB_OP_KEYBOARD_RESIZING_E: + case META_GRAB_OP_KEYBOARD_RESIZING_SE: + case META_GRAB_OP_KEYBOARD_RESIZING_NE: + case META_GRAB_OP_KEYBOARD_RESIZING_SW: + case META_GRAB_OP_KEYBOARD_RESIZING_NW: update_resize (window, event->xbutton.x_root, event->xbutton.y_root); break; @@ -5929,6 +5936,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, switch (window->display->grab_op) { case META_GRAB_OP_MOVING: + case META_GRAB_OP_KEYBOARD_MOVING: { int x, y; window_query_root_pointer (window, &x, &y); @@ -5937,7 +5945,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, x, y); } break; - + case META_GRAB_OP_RESIZING_E: case META_GRAB_OP_RESIZING_W: case META_GRAB_OP_RESIZING_S: @@ -5946,6 +5954,14 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, case META_GRAB_OP_RESIZING_SW: case META_GRAB_OP_RESIZING_NE: case META_GRAB_OP_RESIZING_NW: + case META_GRAB_OP_KEYBOARD_RESIZING_S: + case META_GRAB_OP_KEYBOARD_RESIZING_N: + case META_GRAB_OP_KEYBOARD_RESIZING_W: + case META_GRAB_OP_KEYBOARD_RESIZING_E: + case META_GRAB_OP_KEYBOARD_RESIZING_SE: + case META_GRAB_OP_KEYBOARD_RESIZING_NE: + case META_GRAB_OP_KEYBOARD_RESIZING_SW: + case META_GRAB_OP_KEYBOARD_RESIZING_NW: { int x, y; window_query_root_pointer (window, &x, &y); @@ -6208,3 +6224,139 @@ meta_window_is_ancestor_of_transient (MetaWindow *window, return FALSE; } + +static gboolean +warp_pointer (MetaWindow *window, + MetaGrabOp grab_op, + int *x, + int *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; + break; + + case META_GRAB_OP_KEYBOARD_RESIZING_S: + *x = window->rect.width / 2; + *y = window->rect.height; + break; + + case META_GRAB_OP_KEYBOARD_RESIZING_N: + *x = window->rect.width / 2; + *y = 0; + break; + + case META_GRAB_OP_KEYBOARD_RESIZING_W: + *x = 0; + *y = window->rect.height / 2; + break; + + case META_GRAB_OP_KEYBOARD_RESIZING_E: + *x = window->rect.width; + *y = window->rect.height / 2; + break; + + case META_GRAB_OP_KEYBOARD_RESIZING_SE: + *x = window->rect.width; + *y = window->rect.height; + break; + + case META_GRAB_OP_KEYBOARD_RESIZING_NE: + *x = window->rect.width; + *y = 0; + break; + + case META_GRAB_OP_KEYBOARD_RESIZING_SW: + *x = 0; + *y = window->rect.height; + break; + + case META_GRAB_OP_KEYBOARD_RESIZING_NW: + *x = 0; + *y = 0; + break; + + default: + return FALSE; + } + + meta_error_trap_push (window->display); + + XWarpPointer (window->display->xdisplay, + None, + window->xwindow, + 0, 0, 0, 0, + *x, + *y); + + if (meta_error_trap_pop (window->display)) + { + 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); + + meta_window_raise (window); + + warp_pointer (window, op, &x_offset, &y_offset); + + meta_display_begin_grab_op (window->display, + window->screen, + window, + op, + FALSE, 0, 0, + timestamp, + x + x_offset, + y + y_offset); +} + +void meta_window_update_resize_grab_op (MetaWindow *window, + gboolean update_cursor) +{ + int x, y, x_offset, y_offset; + + meta_window_get_position (window, &x, &y); + + warp_pointer (window, window->display->grab_op, &x_offset, &y_offset); + + window->display->grab_current_root_x = x + x_offset; + window->display->grab_current_root_y = y + y_offset; + + if (window->display->grab_window) + { + window->display->grab_current_window_pos = window->rect; + } + + if (update_cursor) + { + meta_display_set_grab_op_cursor (window->display, + window->display->grab_op, + TRUE, + window->display->grab_xwindow, + meta_display_get_current_time (window->display)); + } +} + diff --git a/src/window.h b/src/window.h index c7e187f8b..f10e632f1 100644 --- a/src/window.h +++ b/src/window.h @@ -406,4 +406,14 @@ void meta_window_foreach_transient (MetaWindow *window, gboolean meta_window_is_ancestor_of_transient (MetaWindow *window, MetaWindow *transient); +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); + #endif