Patch to provide extra cues to the user when using window menu move and

2002-08-08  Craig Black  <blackc@speakeasy.net>

  Patch to provide extra cues to the user when using
  window menu move and resize, #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
This commit is contained in:
Craig Black 2002-08-09 04:27:23 +00:00 committed by Craig Black
parent 8c5369d522
commit 4fcc9f052e
7 changed files with 352 additions and 88 deletions

View File

@ -1,3 +1,36 @@
2002-08-08 Craig Black <blackc@speakeasy.net>
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 <blackc@speakeasy.net>
* src/display.h: update comment

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -1472,7 +1472,10 @@ process_keyboard_move_grab (MetaDisplay *display,
}
if (handled)
{
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)
{
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_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_window_begin_grab_op (window,
META_GRAB_OP_KEYBOARD_MOVING,
FALSE, 0, 0,
event->xkey.time,
0, 0);
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_window_begin_grab_op (window,
META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
FALSE, 0, 0,
event->xkey.time,
0, 0);
event->xkey.time);
}
}

View File

@ -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,
meta_window_begin_grab_op (window,
op,
FALSE, 0, 0,
meta_display_get_current_time (window->display),
0, 0);
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_window_begin_grab_op (window,
META_GRAB_OP_KEYBOARD_MOVING,
FALSE, 0, 0,
meta_display_get_current_time (window->display),
0, 0);
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_window_begin_grab_op (window,
META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
FALSE, 0, 0,
meta_display_get_current_time (window->display),
0, 0);
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);
@ -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));
}
}

View File

@ -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