mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
...
This commit is contained in:
parent
b6e4c8bc41
commit
c18a8137ce
@ -647,8 +647,7 @@ event_callback (XEvent *event,
|
||||
{
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
if (window)
|
||||
meta_display_process_key_event (display, window, event);
|
||||
meta_display_process_key_event (display, window, event);
|
||||
break;
|
||||
case ButtonPress:
|
||||
if ((grab_op_is_mouse (display->grab_op) &&
|
||||
@ -662,17 +661,22 @@ event_callback (XEvent *event,
|
||||
meta_display_end_grab_op (display,
|
||||
event->xbutton.time);
|
||||
}
|
||||
else if (window)
|
||||
else if (window && display->grab_op == META_GRAB_OP_NONE)
|
||||
{
|
||||
gboolean begin_move = FALSE;
|
||||
|
||||
if (event->xbutton.button == 1)
|
||||
{
|
||||
meta_window_raise (window);
|
||||
meta_window_focus (window, event->xbutton.time);
|
||||
|
||||
/* frames.c handles it if frame was receiver */
|
||||
if (!frame_was_receiver)
|
||||
begin_move = TRUE;
|
||||
}
|
||||
else if (event->xbutton.button == 2)
|
||||
{
|
||||
/* FIXME begin move */
|
||||
|
||||
begin_move = TRUE;
|
||||
}
|
||||
else if (event->xbutton.button == 3)
|
||||
{
|
||||
@ -682,6 +686,19 @@ event_callback (XEvent *event,
|
||||
event->xbutton.button,
|
||||
event->xbutton.time);
|
||||
}
|
||||
|
||||
if (begin_move && window->has_move_func)
|
||||
{
|
||||
meta_display_begin_grab_op (display,
|
||||
window,
|
||||
META_GRAB_OP_MOVING,
|
||||
TRUE,
|
||||
event->xbutton.button,
|
||||
0,
|
||||
event->xbutton.time,
|
||||
event->xbutton.x_root,
|
||||
event->xbutton.y_root);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
@ -1012,6 +1029,18 @@ focus_mode (int m)
|
||||
return mode;
|
||||
}
|
||||
|
||||
static char*
|
||||
key_event_description (Display *xdisplay,
|
||||
XEvent *event)
|
||||
{
|
||||
KeySym keysym;
|
||||
|
||||
keysym = XKeycodeToKeysym (xdisplay, event->xkey.keycode, 0);
|
||||
|
||||
return g_strdup_printf ("Key '%s' state 0x%x",
|
||||
XKeysymToString (keysym), event->xkey.state);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_spew_event (MetaDisplay *display,
|
||||
XEvent *event)
|
||||
@ -1030,9 +1059,11 @@ meta_spew_event (MetaDisplay *display,
|
||||
{
|
||||
case KeyPress:
|
||||
name = "KeyPress";
|
||||
extra = key_event_description (display->xdisplay, event);
|
||||
break;
|
||||
case KeyRelease:
|
||||
name = "KeyRelease";
|
||||
extra = key_event_description (display->xdisplay, event);
|
||||
break;
|
||||
case ButtonPress:
|
||||
name = "ButtonPress";
|
||||
@ -1502,6 +1533,8 @@ meta_display_grab_window_buttons (MetaDisplay *display,
|
||||
/* Grab Alt + button1 and Alt + button2 for moving window,
|
||||
* and Alt + button3 for popping up window menu.
|
||||
*/
|
||||
meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow);
|
||||
|
||||
{
|
||||
int i = 1;
|
||||
while (i < 4)
|
||||
|
@ -1149,10 +1149,9 @@ meta_frames_button_press_event (GtkWidget *widget,
|
||||
event->x_root,
|
||||
event->y_root);
|
||||
}
|
||||
else if (((control == META_FRAME_CONTROL_TITLE ||
|
||||
control == META_FRAME_CONTROL_NONE) &&
|
||||
event->button == 1) ||
|
||||
event->button == 2)
|
||||
else if ((control == META_FRAME_CONTROL_TITLE ||
|
||||
control == META_FRAME_CONTROL_NONE) &&
|
||||
event->button == 1)
|
||||
{
|
||||
MetaFrameFlags flags;
|
||||
|
||||
|
@ -365,20 +365,22 @@ meta_display_process_key_event (MetaDisplay *display,
|
||||
KeySym keysym;
|
||||
gboolean handled;
|
||||
|
||||
g_return_if_fail (window != NULL);
|
||||
/* window may be NULL */
|
||||
|
||||
keysym = XKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0);
|
||||
|
||||
meta_verbose ("Processing key %s event, keysym: %s state: 0x%x window: %s\n",
|
||||
event->type == KeyPress ? "press" : "release",
|
||||
XKeysymToString (keysym), event->xkey.state,
|
||||
window->desc);
|
||||
window ? window->desc : "(no window)");
|
||||
|
||||
if (!window->all_keys_grabbed)
|
||||
if (window == NULL || !window->all_keys_grabbed)
|
||||
{
|
||||
/* Do the normal keybindings */
|
||||
process_event (screen_bindings, display, window, event, keysym);
|
||||
process_event (window_bindings, display, window, event, keysym);
|
||||
process_event (screen_bindings, display, NULL, event, keysym);
|
||||
|
||||
if (window)
|
||||
process_event (window_bindings, display, window, event, keysym);
|
||||
return;
|
||||
}
|
||||
|
||||
|
281
src/place.c
281
src/place.c
@ -422,18 +422,17 @@ rects_overlap_horizontally (const MetaRectangle *a,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
meta_window_find_next_vertical_edge (MetaWindow *window,
|
||||
gboolean right)
|
||||
static void
|
||||
get_vertical_edges (MetaWindow *window,
|
||||
int **edges_p,
|
||||
int *n_edges_p)
|
||||
{
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
int left_edge, right_edge;
|
||||
int n_windows;
|
||||
int *edges;
|
||||
int i;
|
||||
int n_edges;
|
||||
int retval;
|
||||
MetaRectangle rect;
|
||||
|
||||
windows = get_windows_on_same_workspace (window, &n_windows);
|
||||
@ -482,6 +481,85 @@ meta_window_find_next_vertical_edge (MetaWindow *window,
|
||||
/* Sort */
|
||||
qsort (edges, n_edges, sizeof (int), intcmp);
|
||||
|
||||
*edges_p = edges;
|
||||
*n_edges_p = n_edges;
|
||||
}
|
||||
|
||||
static void
|
||||
get_horizontal_edges (MetaWindow *window,
|
||||
int **edges_p,
|
||||
int *n_edges_p)
|
||||
{
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
int n_windows;
|
||||
int *edges;
|
||||
int i;
|
||||
int n_edges;
|
||||
MetaRectangle rect;
|
||||
|
||||
windows = get_windows_on_same_workspace (window, &n_windows);
|
||||
|
||||
i = 0;
|
||||
n_edges = n_windows * 2 + 4; /* 4 = workspace/screen edges */
|
||||
edges = g_new (int, n_edges);
|
||||
|
||||
/* workspace/screen edges */
|
||||
edges[i] = window->screen->active_workspace->workarea.y;
|
||||
++i;
|
||||
edges[i] =
|
||||
window->screen->active_workspace->workarea.y +
|
||||
window->screen->active_workspace->workarea.height;
|
||||
++i;
|
||||
edges[i] = 0;
|
||||
++i;
|
||||
edges[i] = window->screen->height;
|
||||
++i;
|
||||
|
||||
g_assert (i == 4);
|
||||
|
||||
meta_window_get_outer_rect (window, &rect);
|
||||
|
||||
/* get window edges */
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle w_rect;
|
||||
|
||||
meta_window_get_outer_rect (w, &w_rect);
|
||||
|
||||
if (rects_overlap_horizontally (&rect, &w_rect))
|
||||
{
|
||||
window_get_edges (w, NULL, NULL, &edges[i], &edges[i+1]);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
n_edges = i;
|
||||
|
||||
g_slist_free (windows);
|
||||
|
||||
/* Sort */
|
||||
qsort (edges, n_edges, sizeof (int), intcmp);
|
||||
|
||||
*edges_p = edges;
|
||||
*n_edges_p = n_edges;
|
||||
}
|
||||
|
||||
int
|
||||
meta_window_find_next_vertical_edge (MetaWindow *window,
|
||||
gboolean right)
|
||||
{
|
||||
int left_edge, right_edge;
|
||||
int *edges;
|
||||
int i;
|
||||
int n_edges;
|
||||
int retval;
|
||||
|
||||
get_vertical_edges (window, &edges, &n_edges);
|
||||
|
||||
/* Find next */
|
||||
meta_window_get_position (window, &retval, NULL);
|
||||
|
||||
@ -542,61 +620,13 @@ int
|
||||
meta_window_find_next_horizontal_edge (MetaWindow *window,
|
||||
gboolean down)
|
||||
{
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
int top_edge, bottom_edge;
|
||||
int n_windows;
|
||||
int *edges;
|
||||
int i;
|
||||
int n_edges;
|
||||
int retval;
|
||||
MetaRectangle rect;
|
||||
|
||||
windows = get_windows_on_same_workspace (window, &n_windows);
|
||||
|
||||
i = 0;
|
||||
n_edges = n_windows * 2 + 4; /* 4 = workspace/screen edges */
|
||||
edges = g_new (int, n_edges);
|
||||
|
||||
/* workspace/screen edges */
|
||||
edges[i] = window->screen->active_workspace->workarea.y;
|
||||
++i;
|
||||
edges[i] =
|
||||
window->screen->active_workspace->workarea.y +
|
||||
window->screen->active_workspace->workarea.height;
|
||||
++i;
|
||||
edges[i] = 0;
|
||||
++i;
|
||||
edges[i] = window->screen->height;
|
||||
++i;
|
||||
|
||||
g_assert (i == 4);
|
||||
|
||||
meta_window_get_outer_rect (window, &rect);
|
||||
|
||||
/* get window edges */
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle w_rect;
|
||||
|
||||
meta_window_get_outer_rect (w, &w_rect);
|
||||
|
||||
if (rects_overlap_horizontally (&rect, &w_rect))
|
||||
{
|
||||
window_get_edges (w, NULL, NULL, &edges[i], &edges[i+1]);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
n_edges = i;
|
||||
|
||||
g_slist_free (windows);
|
||||
|
||||
/* Sort */
|
||||
qsort (edges, n_edges, sizeof (int), intcmp);
|
||||
get_horizontal_edges (window, &edges, &n_edges);
|
||||
|
||||
/* Find next */
|
||||
meta_window_get_position (window, NULL, &retval);
|
||||
@ -653,3 +683,146 @@ meta_window_find_next_horizontal_edge (MetaWindow *window,
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
meta_window_find_nearest_vertical_edge (MetaWindow *window,
|
||||
int x_pos)
|
||||
{
|
||||
int *edges;
|
||||
int i;
|
||||
int n_edges;
|
||||
int *positions;
|
||||
int n_positions;
|
||||
int retval;
|
||||
|
||||
get_vertical_edges (window, &edges, &n_edges);
|
||||
|
||||
/* Create an array of all snapped positions our window could have */
|
||||
n_positions = n_edges * 2;
|
||||
positions = g_new (int, n_positions);
|
||||
|
||||
i = 0;
|
||||
while (i < n_edges)
|
||||
{
|
||||
int left_pos, right_pos;
|
||||
|
||||
left_pos = edges[i];
|
||||
if (window->frame)
|
||||
left_pos += window->frame->child_x;
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
right_pos = edges[i] - window->frame->rect.width;
|
||||
right_pos += window->frame->child_x;
|
||||
}
|
||||
else
|
||||
{
|
||||
right_pos = edges[i] - window->rect.width;
|
||||
}
|
||||
|
||||
positions[i * 2] = left_pos;
|
||||
positions[i * 2 + 1] = right_pos;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
g_free (edges);
|
||||
|
||||
/* Sort */
|
||||
qsort (positions, n_positions, sizeof (int), intcmp);
|
||||
|
||||
/* Find nearest */
|
||||
|
||||
retval = positions[0];
|
||||
|
||||
i = 1;
|
||||
while (i < n_positions)
|
||||
{
|
||||
int delta;
|
||||
int best_delta;
|
||||
|
||||
delta = ABS (x_pos - positions[i]);
|
||||
best_delta = ABS (x_pos - retval);
|
||||
|
||||
if (delta < best_delta)
|
||||
retval = positions[i];
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
g_free (positions);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
meta_window_find_nearest_horizontal_edge (MetaWindow *window,
|
||||
int y_pos)
|
||||
{
|
||||
int *edges;
|
||||
int i;
|
||||
int n_edges;
|
||||
int *positions;
|
||||
int n_positions;
|
||||
int retval;
|
||||
|
||||
get_horizontal_edges (window, &edges, &n_edges);
|
||||
|
||||
/* Create an array of all snapped positions our window could have */
|
||||
n_positions = n_edges * 2;
|
||||
positions = g_new (int, n_positions);
|
||||
|
||||
i = 0;
|
||||
while (i < n_edges)
|
||||
{
|
||||
int top_pos, bottom_pos;
|
||||
|
||||
top_pos = edges[i];
|
||||
if (window->frame)
|
||||
top_pos += window->frame->child_y;
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
bottom_pos = edges[i] - window->frame->rect.height;
|
||||
bottom_pos += window->frame->child_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
bottom_pos = edges[i] - window->rect.height;
|
||||
}
|
||||
|
||||
positions[i * 2] = top_pos;
|
||||
positions[i * 2 + 1] = bottom_pos;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
g_free (edges);
|
||||
|
||||
/* Sort */
|
||||
qsort (positions, n_positions, sizeof (int), intcmp);
|
||||
|
||||
/* Find nearest */
|
||||
|
||||
retval = positions[0];
|
||||
|
||||
i = 1;
|
||||
while (i < n_positions)
|
||||
{
|
||||
int delta;
|
||||
int best_delta;
|
||||
|
||||
delta = ABS (y_pos - positions[i]);
|
||||
best_delta = ABS (y_pos - retval);
|
||||
|
||||
if (delta < best_delta)
|
||||
retval = positions[i];
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
g_free (positions);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
17
src/place.h
17
src/place.h
@ -32,11 +32,28 @@ void meta_window_place (MetaWindow *window,
|
||||
int *new_x,
|
||||
int *new_y);
|
||||
|
||||
/* Returns the position to move the window to in order
|
||||
* to snap it to the next edge in the given direction,
|
||||
* while moving.
|
||||
*/
|
||||
int meta_window_find_next_vertical_edge (MetaWindow *window,
|
||||
gboolean right);
|
||||
int meta_window_find_next_horizontal_edge (MetaWindow *window,
|
||||
gboolean down);
|
||||
|
||||
/* Returns the position to move the window to in order
|
||||
* to snap it to the nearest edge, while moving.
|
||||
*/
|
||||
int meta_window_find_nearest_vertical_edge (MetaWindow *window,
|
||||
int x_pos);
|
||||
|
||||
int meta_window_find_nearest_horizontal_edge (MetaWindow *window,
|
||||
int y_pos);
|
||||
|
||||
/* FIXME need edge-snap functions for resizing as well, those
|
||||
* behave somewhat differently.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
23
src/window.c
23
src/window.c
@ -3717,18 +3717,28 @@ window_query_root_pointer (MetaWindow *window,
|
||||
|
||||
static void
|
||||
update_move (MetaWindow *window,
|
||||
unsigned int mask,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
int dx, dy;
|
||||
int new_x, new_y;
|
||||
|
||||
dx = x - window->display->grab_root_x;
|
||||
dy = y - window->display->grab_root_y;
|
||||
|
||||
window->user_has_moved = TRUE;
|
||||
meta_window_move (window,
|
||||
window->display->grab_initial_window_pos.x + dx,
|
||||
window->display->grab_initial_window_pos.y + dy);
|
||||
new_x = window->display->grab_initial_window_pos.x + dx;
|
||||
new_y = window->display->grab_initial_window_pos.y + dy;
|
||||
|
||||
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, new_x, new_y);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3829,7 +3839,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
switch (window->display->grab_op)
|
||||
{
|
||||
case META_GRAB_OP_MOVING:
|
||||
update_move (window, event->xbutton.x_root, event->xbutton.y_root);
|
||||
update_move (window, event->xbutton.state,
|
||||
event->xbutton.x_root, event->xbutton.y_root);
|
||||
break;
|
||||
|
||||
case META_GRAB_OP_RESIZING_E:
|
||||
@ -3855,7 +3866,9 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
{
|
||||
int x, y;
|
||||
window_query_root_pointer (window, &x, &y);
|
||||
update_move (window, x, y);
|
||||
update_move (window,
|
||||
event->xbutton.state,
|
||||
x, y);
|
||||
}
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user