Focus follows pointer rewrite

This commit is contained in:
Bastien Dejean 2013-03-02 19:39:16 +01:00
parent 336ec4c96c
commit 6bfebaaf6b
8 changed files with 46 additions and 28 deletions

View file

@ -1,4 +1,3 @@
- Rewrite `focus_follows_pointer` by using a root sized input only window mapped and unmapped via enter notify events.
- Rewrite `find_neighbor` based on the distances between the windows sides (more intuitive).
- Focus history.
- Command line completion for *bspc*.

View file

@ -62,6 +62,11 @@ void setup(void)
screen_height = screen->height_in_pixels;
root_depth = screen->root_depth;
uint32_t mask = XCB_CW_EVENT_MASK;
uint32_t values[] = {XCB_EVENT_MASK_POINTER_MOTION};
motion_recorder = xcb_generate_id(dpy);
xcb_create_window(dpy, XCB_COPY_FROM_PARENT, motion_recorder, root, 0, 0, screen_width, screen_height, 0, XCB_WINDOW_CLASS_INPUT_ONLY, XCB_COPY_FROM_PARENT, mask, values);
xcb_atom_t net_atoms[] = {ewmh->_NET_SUPPORTED,
ewmh->_NET_DESKTOP_NAMES,
ewmh->_NET_NUMBER_OF_DESKTOPS,
@ -124,8 +129,6 @@ void setup(void)
ewmh_update_current_desktop();
rule_head = rule_tail = NULL;
frozen_pointer = make_pointer_state();
last_focused_window = XCB_NONE;
save_pointer_position(&last_pointer_position);
split_mode = MODE_AUTOMATIC;
visible = true;
exit_status = 0;
@ -240,6 +243,7 @@ int main(int argc, char *argv[])
if (status_fifo != NULL)
fclose(status_fifo);
xcb_ewmh_connection_wipe(ewmh);
xcb_destroy_window(dpy, motion_recorder);
free(ewmh);
xcb_flush(dpy);
xcb_disconnect(dpy);

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 CLIENT_EVENT_MASK_FFP (XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_POINTER_MOTION)
#define CLIENT_EVENT_MASK_FFP (XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_ENTER_WINDOW)
xcb_connection_t *dpy;
int default_screen, screen_width, screen_height;
@ -31,8 +31,7 @@ rule_t *rule_head;
rule_t *rule_tail;
pointer_state_t *frozen_pointer;
xcb_window_t last_focused_window;
xcb_point_t last_pointer_position;
xcb_window_t motion_recorder;
xcb_atom_t compton_shadow;
int exit_status;

View file

@ -39,7 +39,7 @@ void handle_event(xcb_generic_event_t *evt)
enter_notify(evt);
break;
case XCB_MOTION_NOTIFY:
motion_notify(evt);
motion_notify();
break;
default:
break;
@ -234,20 +234,22 @@ void enter_notify(xcb_generic_event_t *evt)
PRINTF("enter notify %X %d %d\n", win, e->mode, e->detail);
if (e->mode != XCB_NOTIFY_MODE_NORMAL
|| (last_pointer_position.x = e->root_x && last_pointer_position.y == e->root_y))
|| (mon->desk->focus != NULL && mon->desk->focus->client->window == win))
return;
window_focus(win);
enable_motion_recorder();
}
void motion_notify(xcb_generic_event_t *evt)
void motion_notify(void)
{
xcb_motion_notify_event_t *e = (xcb_motion_notify_event_t *) evt;
xcb_window_t win = e->event;
PUTS("motion notify");
PRINTF("motion notify %X\n", win);
disable_motion_recorder();
window_focus(win);
xcb_window_t win = XCB_NONE;
get_pointed_window(&win);
if (win != XCB_NONE)
window_focus(win);
}
void handle_state(monitor_t *m, desktop_t *d, node_t *n, xcb_atom_t state, unsigned int action)

View file

@ -12,7 +12,7 @@ void configure_request(xcb_generic_event_t *);
void client_message(xcb_generic_event_t *);
void property_notify(xcb_generic_event_t *);
void enter_notify(xcb_generic_event_t *);
void motion_notify(xcb_generic_event_t *);
void motion_notify(void);
void handle_state(monitor_t *, desktop_t *, node_t *, xcb_atom_t, unsigned int);
void grab_pointer(pointer_action_t);
void track_pointer(int, int);

16
tree.c
View file

@ -196,8 +196,6 @@ void arrange(monitor_t *m, desktop_t *d)
rect.y += m->top_padding + wg;
rect.width -= m->left_padding + m->right_padding + wg;
rect.height -= m->top_padding + m->bottom_padding + wg;
if (focus_follows_pointer)
save_pointer_position(&last_pointer_position);
apply_layout(m, d, d->root, rect, rect);
}
@ -389,16 +387,10 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n, bool is_mapped)
}
if (focus_follows_pointer) {
save_pointer_position(&last_pointer_position);
if (n != mon->desk->focus) {
if (last_focused_window != XCB_NONE) {
uint32_t values[] = {CLIENT_EVENT_MASK_FFP};
xcb_change_window_attributes(dpy, last_focused_window, XCB_CW_EVENT_MASK, values);
}
uint32_t values[] = {CLIENT_EVENT_MASK};
xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
last_focused_window = n->client->window;
}
xcb_window_t win = XCB_NONE;
get_pointed_window(&win);
if (win != n->client->window)
enable_motion_recorder();
}
if (!is_tiled(n->client)) {

View file

@ -421,6 +421,15 @@ void save_pointer_position(xcb_point_t *pos)
}
}
void get_pointed_window(xcb_window_t *win)
{
xcb_query_pointer_reply_t *qpr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), NULL);
if (qpr != NULL) {
*win = qpr->child;
free(qpr);
}
}
void window_focus(xcb_window_t win)
{
window_location_t loc;
@ -500,3 +509,14 @@ void toggle_visibility(void)
if (visible)
update_current();
}
void enable_motion_recorder(void)
{
window_raise(motion_recorder);
window_show(motion_recorder);
}
void disable_motion_recorder(void)
{
window_hide(motion_recorder);
}

View file

@ -34,10 +34,12 @@ void window_lower(xcb_window_t);
void window_set_visibility(xcb_window_t, bool);
void window_hide(xcb_window_t);
void window_show(xcb_window_t);
void enable_motion_recorder(void);
void disable_motion_recorder(void);
void toggle_visibility(void);
uint32_t get_border_color(client_t *, bool, bool);
void update_floating_rectangle(client_t *);
void save_pointer_position(xcb_point_t *);
void get_pointed_window(xcb_window_t *);
void list_windows(char *);
#endif