summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhp <rhp>2001-07-26 03:58:24 +0000
committerrhp <rhp>2001-07-26 03:58:24 +0000
commitc18a8137ce063918615d5a74474011b09c349b95 (patch)
treed9a8dfda2bf0229f288898a3c4cd9691e57e17f2
parentb6e4c8bc414cf8905e5b2d0f2f84c2155acd10cf (diff)
downloadmetacity-c18a8137ce063918615d5a74474011b09c349b95.tar.gz
...
-rw-r--r--src/display.c43
-rw-r--r--src/frames.c7
-rw-r--r--src/keybindings.c12
-rw-r--r--src/place.c281
-rw-r--r--src/place.h17
-rw-r--r--src/window.c23
6 files changed, 310 insertions, 73 deletions
diff --git a/src/display.c b/src/display.c
index 0622701f..0c62bd26 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 5af3a1a6..e09d41c2 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 177b6d64..a717a8b3 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 f2c70adb..8952d117 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;
-
- 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;
+ get_horizontal_edges (window, &edges, &n_edges);
- 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 1d3274ba..a628c563 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 9e0dc719..37cfda0b 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;