re-add focus follows mouse handling

This commit is contained in:
Michael Stapelberg 2010-04-13 18:43:37 +02:00
parent eec762ea8f
commit 8e5a831e27
7 changed files with 113 additions and 77 deletions

View File

@ -21,7 +21,6 @@
int handle_key_press(void *ignored, xcb_connection_t *conn, int handle_key_press(void *ignored, xcb_connection_t *conn,
xcb_key_press_event_t *event); xcb_key_press_event_t *event);
#if 0
/** /**
* When the user moves the mouse pointer onto a window, this callback gets * When the user moves the mouse pointer onto a window, this callback gets
* called. * called.
@ -30,6 +29,7 @@ int handle_key_press(void *ignored, xcb_connection_t *conn,
int handle_enter_notify(void *ignored, xcb_connection_t *conn, int handle_enter_notify(void *ignored, xcb_connection_t *conn,
xcb_enter_notify_event_t *event); xcb_enter_notify_event_t *event);
#if 0
/** /**
* When the user moves the mouse but does not change the active window * When the user moves the mouse but does not change the active window
* (e.g. when having no windows opened but moving mouse on the root screen * (e.g. when having no windows opened but moving mouse on the root screen

View File

@ -36,6 +36,7 @@ while (0)
int min(int a, int b); int min(int a, int b);
int max(int a, int b); int max(int a, int b);
bool rect_contains(Rect rect, uint32_t x, uint32_t y);
/** /**
* Updates *destination with new_value and returns true if it was changed or false * Updates *destination with new_value and returns true if it was changed or false

View File

@ -486,6 +486,7 @@ workspace_name:
assign: assign:
TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow assign_target TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow assign_target
{ {
#if 0
printf("assignment of %s\n", $<string>3); printf("assignment of %s\n", $<string>3);
struct Assignment *new = $<assignment>6; struct Assignment *new = $<assignment>6;
@ -493,29 +494,36 @@ assign:
printf(" floating = %d\n", new->floating); printf(" floating = %d\n", new->floating);
new->windowclass_title = $<string>3; new->windowclass_title = $<string>3;
TAILQ_INSERT_TAIL(&assignments, new, assignments); TAILQ_INSERT_TAIL(&assignments, new, assignments);
#endif
} }
; ;
assign_target: assign_target:
NUMBER NUMBER
{ {
#if 0
struct Assignment *new = scalloc(sizeof(struct Assignment)); struct Assignment *new = scalloc(sizeof(struct Assignment));
new->workspace = $<number>1; new->workspace = $<number>1;
new->floating = ASSIGN_FLOATING_NO; new->floating = ASSIGN_FLOATING_NO;
$<assignment>$ = new; $<assignment>$ = new;
#endif
} }
| '~' | '~'
{ {
#if 0
struct Assignment *new = scalloc(sizeof(struct Assignment)); struct Assignment *new = scalloc(sizeof(struct Assignment));
new->floating = ASSIGN_FLOATING_ONLY; new->floating = ASSIGN_FLOATING_ONLY;
$<assignment>$ = new; $<assignment>$ = new;
#endif
} }
| '~' NUMBER | '~' NUMBER
{ {
#if 0
struct Assignment *new = scalloc(sizeof(struct Assignment)); struct Assignment *new = scalloc(sizeof(struct Assignment));
new->workspace = $<number>2; new->workspace = $<number>2;
new->floating = ASSIGN_FLOATING; new->floating = ASSIGN_FLOATING;
$<assignment>$ = new; $<assignment>$ = new;
#endif
} }
; ;

View File

@ -305,6 +305,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
SLIST_REMOVE(&modes, mode, Mode, modes); SLIST_REMOVE(&modes, mode, Mode, modes);
} }
#if 0
struct Assignment *assign; struct Assignment *assign;
while (!TAILQ_EMPTY(&assignments)) { while (!TAILQ_EMPTY(&assignments)) {
assign = TAILQ_FIRST(&assignments); assign = TAILQ_FIRST(&assignments);
@ -312,6 +313,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
TAILQ_REMOVE(&assignments, assign, assignments); TAILQ_REMOVE(&assignments, assign, assignments);
FREE(assign); FREE(assign);
} }
#endif
/* Clear workspace names */ /* Clear workspace names */
#if 0 #if 0

View File

@ -45,12 +45,13 @@ static bool event_is_ignored(const int sequence) {
} }
SLIST_FOREACH(event, &ignore_events, ignore_events) { SLIST_FOREACH(event, &ignore_events, ignore_events) {
if (event->sequence == sequence) { if (event->sequence != sequence)
continue;
SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events); SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events);
free(event); free(event);
return true; return true;
} }
}
return false; return false;
} }
@ -140,55 +141,57 @@ static void check_crossing_screen_boundary(uint32_t x, uint32_t y) {
if (first_client != NULL) if (first_client != NULL)
set_focus(global_conn, first_client, true); set_focus(global_conn, first_client, true);
} }
#endif
/* /*
* When the user moves the mouse pointer onto a window, this callback gets called. * When the user moves the mouse pointer onto a window, this callback gets called.
* *
*/ */
int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_event_t *event) { int handle_enter_notify(void *ignored, xcb_connection_t *conn,
DLOG("enter_notify for %08x, mode = %d, detail %d, serial %d\n", event->event, event->mode, event->detail, event->sequence); xcb_enter_notify_event_t *event) {
Con *con;
DLOG("enter_notify for %08x, mode = %d, detail %d, serial %d\n",
event->event, event->mode, event->detail, event->sequence);
DLOG("coordinates %x, %x\n", event->event_x, event->event_y);
if (event->mode != XCB_NOTIFY_MODE_NORMAL) { if (event->mode != XCB_NOTIFY_MODE_NORMAL) {
DLOG("This was not a normal notify, ignoring\n"); DLOG("This was not a normal notify, ignoring\n");
return 1; return 1;
} }
/* Some events are not interesting, because they were not generated actively by the /* Some events are not interesting, because they were not generated
user, but by reconfiguration of windows */ * actively by the user, but by reconfiguration of windows */
if (event_is_ignored(event->sequence)) if (event_is_ignored(event->sequence))
return 1; return 1;
/* This was either a focus for a clients parent (= titlebar)… */ /* Get container by frame or by child window */
Client *client = table_get(&by_parent, event->event); if ((con = con_by_frame_id(event->event)) == NULL)
/* …or the client itself */ con = con_by_window_id(event->event);
if (client == NULL)
client = table_get(&by_child, event->event);
/* Check for stack windows */
if (client == NULL) {
struct Stack_Window *stack_win;
SLIST_FOREACH(stack_win, &stack_wins, stack_windows)
if (stack_win->window == event->event) {
client = stack_win->container->currently_focused;
break;
}
}
/* If not, then the user moved his cursor to the root window. In that case, we adjust c_ws */ /* If not, then the user moved his cursor to the root window. In that case, we adjust c_ws */
if (client == NULL) { if (con == NULL) {
DLOG("Getting screen at %d x %d\n", event->root_x, event->root_y); DLOG("Getting screen at %d x %d\n", event->root_x, event->root_y);
check_crossing_screen_boundary(event->root_x, event->root_y); //check_crossing_screen_boundary(event->root_x, event->root_y);
return 1; return 1;
} }
/* Do plausibility checks: This event may be useless for us if it occurs on a window /* see if the user entered the window on a certain window decoration */
which is in a stacked container but not the focused one */ int layout = con->layout;
if (client->container != NULL && Con *child;
client->container->mode == MODE_STACK && TAILQ_FOREACH(child, &(con->nodes_head), nodes)
client->container->currently_focused != client) { if (rect_contains(child->deco_rect, event->event_x, event->event_y)) {
DLOG("Plausibility check says: no\n"); LOG("using child %p / %s instead!\n", child, child->name);
return 1; con = child;
break;
} }
/* for stacked/tabbed layout we do not want to change focus when the user
* enters the window at the decoration of any child window. */
if (layout == L_STACKED || layout == L_TABBED) {
con = TAILQ_FIRST(&(con->parent->focus_head));
LOG("using focused %p / %s instead\n", con, con->name);
}
#if 0
if (client->workspace != c_ws && client->workspace->output == c_ws->output) { if (client->workspace != c_ws && client->workspace->output == c_ws->output) {
/* This can happen when a client gets assigned to a different workspace than /* This can happen when a client gets assigned to a different workspace than
* the current one (see src/mainx.c:reparent_window). Shortly after it was created, * the current one (see src/mainx.c:reparent_window). Shortly after it was created,
@ -196,12 +199,20 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_
DLOG("enter_notify for a client on a different workspace but the same screen, ignoring\n"); DLOG("enter_notify for a client on a different workspace but the same screen, ignoring\n");
return 1; return 1;
} }
#endif
if (!config.disable_focus_follows_mouse) if (config.disable_focus_follows_mouse)
set_focus(conn, client, false); return 1;
Con *next = con;
while (!TAILQ_EMPTY(&(next->focus_head)))
next = TAILQ_FIRST(&(next->focus_head));
con_focus(next);
x_push_changes(croot);
return 1; return 1;
} }
#if 0
/* /*
* When the user moves the mouse but does not change the active window * When the user moves the mouse but does not change the active window

View File

@ -139,7 +139,11 @@ void parse_command(const char *command) {
tree_next('n', VERT); tree_next('n', VERT);
else if (strncasecmp(command, "workspace ", strlen("workspace ")) == 0) else if (strncasecmp(command, "workspace ", strlen("workspace ")) == 0)
workspace_show(command + strlen("workspace ")); workspace_show(command + strlen("workspace "));
else if (strcasecmp(command, "stack") == 0) {
focused->layout = L_STACKED;
x_push_changes(croot);
}
else if (strcasecmp(command, "move before h") == 0) else if (strcasecmp(command, "move before h") == 0)
tree_move('p', HORIZ); tree_move('p', HORIZ);
else if (strcasecmp(command, "move before v") == 0) else if (strcasecmp(command, "move before v") == 0)
@ -312,6 +316,9 @@ int main(int argc, char *argv[]) {
xcb_event_set_expose_handler(&evenths, handle_expose_event, NULL); xcb_event_set_expose_handler(&evenths, handle_expose_event, NULL);
/* Enter window = user moved his mouse over the window */
xcb_event_set_enter_notify_handler(&evenths, handle_enter_notify, NULL);
/* Setup NetWM atoms */ /* Setup NetWM atoms */
#define GET_ATOM(name) \ #define GET_ATOM(name) \

View File

@ -31,6 +31,13 @@ int max(int a, int b) {
return (a > b ? a : b); return (a > b ? a : b);
} }
bool rect_contains(Rect rect, uint32_t x, uint32_t y) {
return (x >= rect.x &&
x <= (rect.x + rect.width) &&
y >= rect.y &&
y <= (rect.y + rect.height));
}
/* /*
* Updates *destination with new_value and returns true if it was changed or false * Updates *destination with new_value and returns true if it was changed or false
* if it was the same * if it was the same