From c18a8137ce063918615d5a74474011b09c349b95 Mon Sep 17 00:00:00 2001 From: rhp Date: Thu, 26 Jul 2001 03:58:24 +0000 Subject: [PATCH] ... --- src/display.c | 43 ++++++- src/frames.c | 7 +- src/keybindings.c | 12 +- src/place.c | 283 +++++++++++++++++++++++++++++++++++++--------- src/place.h | 17 +++ src/window.c | 23 +++- 6 files changed, 311 insertions(+), 74 deletions(-) diff --git a/src/display.c b/src/display.c index 0622701f7..0c62bd269 100644 --- a/src/display.c +++ b/src/display.c @@ -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) diff --git a/src/frames.c b/src/frames.c index 5af3a1a6d..e09d41c2b 100644 --- a/src/frames.c +++ b/src/frames.c @@ -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; diff --git a/src/keybindings.c b/src/keybindings.c index 177b6d649..a717a8b37 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -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; } diff --git a/src/place.c b/src/place.c index f2c70adbe..8952d117f 100644 --- a/src/place.c +++ b/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,62 +620,14 @@ 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; + + get_horizontal_edges (window, &edges, &n_edges); - 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); - /* 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; +} diff --git a/src/place.h b/src/place.h index 1d3274ba8..a628c5631 100644 --- a/src/place.h +++ b/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 diff --git a/src/window.c b/src/window.c index 9e0dc7190..37cfda0b4 100644 --- a/src/window.c +++ b/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;