Resize floating windows with the mouse

This commit is contained in:
Bastien Dejean 2012-09-22 16:32:35 +02:00
parent e81bb851be
commit cfa333e214
6 changed files with 96 additions and 31 deletions

View file

@ -38,9 +38,9 @@ void register_events(void)
die("another WM is already running\n");
}
xcb_grab_button(dpy, false, screen->root, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_1, MOUSE_MODIFIER);
xcb_grab_button(dpy, false, screen->root, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_2, MOUSE_MODIFIER);
xcb_grab_button(dpy, false, screen->root, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_3, MOUSE_MODIFIER);
xcb_grab_button(dpy, false, screen->root, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_1, BUTTON_MODIFIER);
xcb_grab_button(dpy, false, screen->root, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_2, BUTTON_MODIFIER);
xcb_grab_button(dpy, false, screen->root, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_3, BUTTON_MODIFIER);
}
void setup(void)

View file

@ -5,7 +5,7 @@
#define ROOT_EVENT_MASK (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY)
#define CLIENT_EVENT_MASK (XCB_EVENT_MASK_PROPERTY_CHANGE)
#define MOUSE_MODIFIER XCB_MOD_MASK_4
#define BUTTON_MODIFIER XCB_MOD_MASK_4
xcb_connection_t *dpy;
int default_screen, screen_width, screen_height;

View file

@ -261,6 +261,7 @@ void button_press(xcb_generic_event_t *evt)
window_location_t loc;
if (locate_window(win, &loc)) {
client_t *c = loc.node->client;
switch (e->detail) {
case XCB_BUTTON_INDEX_2:
focus_node(loc.desktop, loc.node, true);
@ -270,10 +271,27 @@ void button_press(xcb_generic_event_t *evt)
if (!is_floating(loc.node->client))
return;
PUTS("grab pointer from button press");
frozen_pointer->window = loc.node->client->window;
frozen_pointer->rectangle = loc.node->client->floating_rectangle;
frozen_pointer->desktop = loc.desktop;
frozen_pointer->node = loc.node;
frozen_pointer->rectangle = c->floating_rectangle;
frozen_pointer->position = (xcb_point_t) {e->root_x, e->root_y};
frozen_pointer->button = e->detail;
if (e->detail == XCB_BUTTON_INDEX_3) {
int16_t mid_x, mid_y;
mid_x = c->floating_rectangle.x + (c->floating_rectangle.width / 2);
mid_y = c->floating_rectangle.y + (c->floating_rectangle.height / 2);
if (e->root_x > mid_x) {
if (e->root_y > mid_y)
frozen_pointer->corner = BOTTOM_RIGHT;
else
frozen_pointer->corner = TOP_RIGHT;
} else {
if (e->root_y > mid_y)
frozen_pointer->corner = BOTTOM_LEFT;
else
frozen_pointer->corner = TOP_LEFT;
}
}
xcb_grab_pointer(dpy, false, screen->root, XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_CURRENT_TIME);
break;
}
@ -283,20 +301,58 @@ void button_press(xcb_generic_event_t *evt)
void motion_notify(xcb_generic_event_t *evt)
{
xcb_motion_notify_event_t *e = (xcb_motion_notify_event_t *) evt;
xcb_window_t win = e->child;
PRINTF("motion notify %X %u %u\n", win, e->detail, e->state);
int16_t delta_x, delta_y, x, y;
uint16_t w, h;
desktop_t *d = frozen_pointer->desktop;
node_t *n = frozen_pointer->node;
client_t *c = n->client;
xcb_rectangle_t rect = frozen_pointer->rectangle;
xcb_window_t win = c->window;
PRINTF("motion notify %X %u\n", win, frozen_pointer->button);
delta_x = e->root_x - frozen_pointer->position.x;
delta_y = e->root_y - frozen_pointer->position.y;
switch (frozen_pointer->button) {
case XCB_BUTTON_INDEX_1:
delta_x = e->root_x - frozen_pointer->position.x;
delta_y = e->root_y - frozen_pointer->position.y;
x = frozen_pointer->rectangle.x + delta_x;
y = frozen_pointer->rectangle.y + delta_y;
window_move(frozen_pointer->window, x, y);
x = rect.x + delta_x;
y = rect.y + delta_y;
window_move(win, x, y);
break;
case XCB_BUTTON_INDEX_3:
switch (frozen_pointer->corner) {
case TOP_LEFT:
x = rect.x + delta_x;
y = rect.y + delta_y;
w = rect.width - delta_x;
h = rect.height - delta_y;
break;
case TOP_RIGHT:
x = rect.x;
y = rect.y + delta_y;
w = rect.width + delta_x;
h = rect.height - delta_y;
break;
case BOTTOM_LEFT:
x = rect.x + delta_x;
y = rect.y;
w = rect.width - delta_x;
h = rect.height + delta_y;
break;
case BOTTOM_RIGHT:
x = rect.x;
y = rect.y;
w = rect.width + delta_x;
h = rect.height + delta_y;
break;
}
window_move_resize(win, x, y, w, h);
c->floating_rectangle = (xcb_rectangle_t) {x, y, w, h};
window_draw_border(n, (d->focus == n));
}
}

View file

@ -359,10 +359,10 @@ bool parse_direction(char *s, direction_t *d)
bool parse_cycle_direction(char *s, cycle_dir_t *d)
{
if (strcmp(s, "prev") == 0) {
*d = DIR_PREV;
*d = CYCLE_PREV;
return true;
} else if (strcmp(s, "next") == 0) {
*d = DIR_NEXT;
*d = CYCLE_NEXT;
return true;
}
return false;

12
tree.c
View file

@ -564,9 +564,9 @@ void select_desktop(desktop_t *d)
void cycle_desktop(cycle_dir_t dir)
{
if (dir == DIR_NEXT)
if (dir == CYCLE_NEXT)
select_desktop((desk->next == NULL ? desk_head : desk->next));
else if (dir == DIR_PREV)
else if (dir == CYCLE_PREV)
select_desktop((desk->prev == NULL ? desk_tail : desk->prev));
}
@ -577,9 +577,9 @@ void cycle_leaf(desktop_t *d, node_t *n, cycle_dir_t dir, skip_client_t skip)
PUTS("cycle leaf");
node_t *f = (dir == DIR_PREV ? prev_leaf(n) : next_leaf(n));
node_t *f = (dir == CYCLE_PREV ? prev_leaf(n) : next_leaf(n));
if (f == NULL)
f = (dir == DIR_PREV ? second_extrema(d->root) : first_extrema(d->root));
f = (dir == CYCLE_PREV ? second_extrema(d->root) : first_extrema(d->root));
while (f != n) {
bool tiled = is_tiled(f->client);
@ -587,9 +587,9 @@ void cycle_leaf(desktop_t *d, node_t *n, cycle_dir_t dir, skip_client_t skip)
focus_node(d, f, true);
return;
}
f = (dir == DIR_PREV ? prev_leaf(f) : next_leaf(f));
f = (dir == CYCLE_PREV ? prev_leaf(f) : next_leaf(f));
if (f == NULL)
f = (dir == DIR_PREV ? second_extrema(d->root) : first_extrema(d->root));
f = (dir == CYCLE_PREV ? second_extrema(d->root) : first_extrema(d->root));
}
}

27
types.h
View file

@ -40,8 +40,8 @@ typedef enum {
} skip_client_t;
typedef enum {
DIR_NEXT,
DIR_PREV
CYCLE_NEXT,
CYCLE_PREV
} cycle_dir_t;
typedef enum {
@ -57,6 +57,13 @@ typedef enum {
DIR_DOWN
} direction_t;
typedef enum {
TOP_LEFT,
TOP_RIGHT,
BOTTOM_LEFT,
BOTTOM_RIGHT
} corner_t;
typedef struct {
xcb_window_t window;
bool floating;
@ -108,18 +115,20 @@ struct rule_t {
rule_t *next;
};
typedef struct {
xcb_button_t button;
xcb_point_t position;
xcb_rectangle_t rectangle;
xcb_window_t window;
} pointer_state_t;
typedef struct {
node_t *node;
desktop_t *desktop;
} window_location_t;
typedef struct {
xcb_point_t position;
xcb_button_t button;
xcb_rectangle_t rectangle;
desktop_t *desktop;
node_t *node;
corner_t corner;
} pointer_state_t;
node_t *make_node(void);
desktop_t *make_desktop(const char *);
client_t *make_client(xcb_window_t);