This commit is contained in:
rhp 2001-07-26 03:58:24 +00:00
parent b6e4c8bc41
commit c18a8137ce
6 changed files with 311 additions and 74 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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