From 25ffe6b566379f25dd3cf7e74aeefd084b7e1b19 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 17 Apr 2003 06:17:06 +0000 Subject: [PATCH] add support for interactive/keyboard move/resize --- openbox/focus.c | 6 +- openbox/moveresize.c | 168 +++++++++++++++++++++++++++++++------------ openbox/moveresize.h | 2 + openbox/openbox.c | 11 +++ openbox/openbox.h | 3 + 5 files changed, 141 insertions(+), 49 deletions(-) diff --git a/openbox/focus.c b/openbox/focus.c index e5d3942f..cd08ab68 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -106,12 +106,10 @@ void focus_set_client(Client *client) static gboolean focus_under_pointer() { - Window w; - int i, x, y; - guint u; + int x, y; GList *it; - if (XQueryPointer(ob_display, ob_root, &w, &w, &x, &y, &i, &i, &u)) { + if (ob_pointer_pos(&x, &y)) { for (it = stacking_list; it != NULL; it = it->next) { Client *c = it->data; if (c->desktop == screen_desktop && diff --git a/openbox/moveresize.c b/openbox/moveresize.c index c8263179..2bee161e 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -19,9 +19,22 @@ static guint button; static guint32 corner; static Corner lockcorner; +static guint button_return, button_escape, button_left, button_right, + button_up, button_down; + #define POPUP_X (10) #define POPUP_Y (10) +void moveresize_startup() +{ + button_return = XKeysymToKeycode(ob_display, XStringToKeysym("Return")); + button_escape = XKeysymToKeycode(ob_display, XStringToKeysym("Escape")); + button_left = XKeysymToKeycode(ob_display, XStringToKeysym("Left")); + button_right = XKeysymToKeycode(ob_display, XStringToKeysym("Right")); + button_up = XKeysymToKeycode(ob_display, XStringToKeysym("Up")); + button_down = XKeysymToKeycode(ob_display, XStringToKeysym("Down")); +} + static void popup_coords(char *format, int a, int b) { XSetWindowAttributes attrib; @@ -57,14 +70,25 @@ void moveresize_start(Client *c, int x, int y, guint b, guint32 cnr) start_cy = c->frame->area.y; start_cw = c->area.width; start_ch = c->area.height; - start_x = x; - start_y = y; - button = b; + if (corner == prop_atoms.net_wm_moveresize_move_keyboard || + corner == prop_atoms.net_wm_moveresize_size_keyboard) + button = 0; /* mouse can't end it without being pressed first */ + else + button = b; corner = cnr; + if (corner == prop_atoms.net_wm_moveresize_move || + corner == prop_atoms.net_wm_moveresize_move_keyboard) { + cur_x = start_cx; + cur_y = start_cy; + moving = TRUE; + } else { + cur_x = start_cw; + cur_y = start_ch; + moving = FALSE; + } + moveresize_in_progress = TRUE; - moving = (corner == prop_atoms.net_wm_moveresize_move || - corner == prop_atoms.net_wm_moveresize_move_keyboard); if (corner == prop_atoms.net_wm_moveresize_size_topleft) cur = ob_cursors.tl; @@ -95,23 +119,77 @@ void moveresize_start(Client *c, int x, int y, guint b, guint32 cnr) grab_pointer(TRUE, cur); } +static void end_moveresize(gboolean cancel) +{ + grab_keyboard(FALSE); + grab_pointer(FALSE, None); + + XDestroyWindow(ob_display, coords); + coords = None; + + moveresize_in_progress = FALSE; + + if (moving) { + client_configure(client, Corner_TopLeft, (cancel ? start_cx : cur_x), + (cancel ? start_cy : cur_y), + start_cw, start_ch, TRUE, TRUE); + } else { + client_configure(client, lockcorner, client->area.x, + client->area.y, (cancel ? start_cw : cur_x), + (cancel ? start_ch : cur_y), TRUE, TRUE); + } +} + +static void do_move() +{ + dispatch_move(client, &cur_x, &cur_y); + + popup_coords("X: %d Y: %d", cur_x, cur_y); + + /* get where the client should be */ + frame_frame_gravity(client->frame, &cur_x, &cur_y); + client_configure(client, Corner_TopLeft, cur_x, cur_y, + start_cw, start_ch, TRUE, FALSE); +} + +static void do_resize() +{ + /* dispatch_resize needs the frame size */ + cur_x += client->frame->size.left + client->frame->size.right; + cur_y += client->frame->size.top + client->frame->size.bottom; + + dispatch_resize(client, &cur_x, &cur_y, lockcorner); + + cur_x -= client->frame->size.left + client->frame->size.right; + cur_y -= client->frame->size.top + client->frame->size.bottom; + + client_configure(client, lockcorner, client->area.x, + client->area.y, cur_x, cur_y, TRUE, FALSE); + + popup_coords("W: %d H: %d", client->logical_size.width, + client->logical_size.height); +} + void moveresize_event(XEvent *e) { g_assert(moveresize_in_progress); - if (e->type == MotionNotify) { + if (e->type == ButtonPress) { + if (!button) { + start_x = e->xbutton.x_root; + start_y = e->xbutton.y_root; + button = e->xbutton.button; /* this will end it now */ + } + } else if (e->type == ButtonRelease) { + if (e->xbutton.button == button) { + end_moveresize(FALSE); + } + } else if (e->type == MotionNotify) { if (moving) { cur_x = start_cx + e->xmotion.x_root - start_x; cur_y = start_cy + e->xmotion.y_root - start_y; - dispatch_move(client, &cur_x, &cur_y); - - popup_coords("X: %d Y: %d", cur_x, cur_y); - - /* get where the client should be */ - frame_frame_gravity(client->frame, &cur_x, &cur_y); - client_configure(client, Corner_TopLeft, cur_x, cur_y, - start_cw, start_ch, TRUE, FALSE); + do_move(); } else { if (corner == prop_atoms.net_wm_moveresize_size_topleft) { cur_x = start_cw - (e->xmotion.x_root - start_x); @@ -154,39 +232,39 @@ void moveresize_event(XEvent *e) } else g_assert_not_reached(); - /* dispatch_resize needs the frame size */ - cur_x += client->frame->size.left + client->frame->size.right; - cur_y += client->frame->size.top + client->frame->size.bottom; - - dispatch_resize(client, &cur_x, &cur_y, lockcorner); - - cur_x -= client->frame->size.left + client->frame->size.right; - cur_y -= client->frame->size.top + client->frame->size.bottom; - - client_configure(client, lockcorner, client->area.x, - client->area.y, cur_x, cur_y, TRUE, FALSE); - - popup_coords("W: %d H: %d", client->logical_size.width, - client->logical_size.height); + do_resize(); } - } else if (e->type == ButtonRelease) { - if (e->xbutton.button == button) { - grab_keyboard(FALSE); - grab_pointer(FALSE, None); - - XDestroyWindow(ob_display, coords); - coords = None; - - moveresize_in_progress = FALSE; - - if (moving) { - client_configure(client, Corner_TopLeft, cur_x, cur_y, - start_cw, start_ch, TRUE, TRUE); - } else { - client_configure(client, lockcorner, client->area.x, - client->area.y, cur_x, cur_y, TRUE, TRUE); + } else if (e->type == KeyPress) { + if (e->xkey.keycode == button_escape) + end_moveresize(TRUE); + else if (e->xkey.keycode == button_return) + end_moveresize(FALSE); + else { + if (corner == prop_atoms.net_wm_moveresize_size_keyboard) { + if (e->xkey.keycode == button_right) + cur_x += MAX(4, client->size_inc.width); + else if (e->xkey.keycode == button_left) + cur_x -= MAX(4, client->size_inc.width); + else if (e->xkey.keycode == button_down) + cur_y += MAX(4, client->size_inc.height); + else if (e->xkey.keycode == button_up) + cur_y -= MAX(4, client->size_inc.height); + else + return; + do_resize(); + } else if (corner == prop_atoms.net_wm_moveresize_move_keyboard) { + if (e->xkey.keycode == button_right) + cur_x += 4; + else if (e->xkey.keycode == button_left) + cur_x -= 4; + else if (e->xkey.keycode == button_down) + cur_y += 4; + else if (e->xkey.keycode == button_up) + cur_y -= 4; + else + return; + do_move(); } } - } else if (e->type == KeyPress) { } } diff --git a/openbox/moveresize.h b/openbox/moveresize.h index 971ad359..3b8b3c6a 100644 --- a/openbox/moveresize.h +++ b/openbox/moveresize.h @@ -7,6 +7,8 @@ extern gboolean moveresize_in_progress; +void moveresize_startup(); + void moveresize_start(Client *c, int x, int y, guint b, guint32 corner); void moveresize_event(XEvent *e); diff --git a/openbox/openbox.c b/openbox/openbox.c index 980aceb4..3c2dfc28 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -7,6 +7,7 @@ #include "prop.h" #include "screen.h" #include "focus.h" +#include "moveresize.h" #include "frame.h" #include "extensions.h" #include "parse.h" @@ -165,6 +166,7 @@ int main(int argc, char **argv) font_startup(); theme_startup(); event_startup(); + moveresize_startup(); grab_startup(); plugin_startup(); /* load the plugins specified in the pluginrc */ @@ -322,3 +324,12 @@ void parse_args(int argc, char **argv) } } } + +gboolean ob_pointer_pos(int *x, int *y) +{ + Window w; + int i, x, y; + guint u; + + return !!XQueryPointer(ob_display, ob_root, &w, &w, x, y, &i, &i, &u); +} diff --git a/openbox/openbox.h b/openbox/openbox.h index 70e51136..932c3e3e 100644 --- a/openbox/openbox.h +++ b/openbox/openbox.h @@ -47,4 +47,7 @@ extern Cursors ob_cursors; /*! The path of the rc file. If NULL the default paths are searched for one. */ extern char *ob_rc_path; +/* cuz i have nowhere better to put it right now... */ +gboolean ob_pointer_pos(int *x, int *y); + #endif -- 2.45.2