Before this fix, you could go upwards and select the screen which
was at the rightmost because it also was the one topmost (if all
screen’s top position is equal).
*/
void client_map(xcb_connection_t *conn, Client *client);
*/
void client_map(xcb_connection_t *conn, Client *client);
+/**
+ * Pretty-prints the client’s information into the logfile.
+ *
+ */
+void client_log(Client *client);
+
* This function always returns a screen.
*
*/
* This function always returns a screen.
*
*/
-i3Screen *get_screen_most(direction_t direction);
+i3Screen *get_screen_most(direction_t direction, i3Screen *current);
xcb_map_window(conn, client->frame);
}
xcb_map_window(conn, client->frame);
}
+
+/*
+ * Pretty-prints the client’s information into the logfile.
+ *
+ */
+void client_log(Client *client) {
+ LOG("Window: frame 0x%08x, child 0x%08x\n", client->frame, client->child);
+}
LOG("Target screen NULL\n");
/* Wrap around if the target screen is out of bounds */
if (direction == D_RIGHT)
LOG("Target screen NULL\n");
/* Wrap around if the target screen is out of bounds */
if (direction == D_RIGHT)
- target = get_screen_most(D_LEFT);
+ target = get_screen_most(D_LEFT, cs);
else if (direction == D_LEFT)
else if (direction == D_LEFT)
- target = get_screen_most(D_RIGHT);
+ target = get_screen_most(D_RIGHT, cs);
else if (direction == D_UP)
else if (direction == D_UP)
- target = get_screen_most(D_DOWN);
- else target = get_screen_most(D_UP);
+ target = get_screen_most(D_DOWN, cs);
+ else target = get_screen_most(D_UP, cs);
}
LOG("Switching to ws %d\n", target->current_workspace + 1);
}
LOG("Switching to ws %d\n", target->current_workspace + 1);
if ((screen = get_screen_containing(container->x, destination_y)) == NULL) {
LOG("Wrapping screen around vertically\n");
/* No screen found? Then wrap */
if ((screen = get_screen_containing(container->x, destination_y)) == NULL) {
LOG("Wrapping screen around vertically\n");
/* No screen found? Then wrap */
- screen = get_screen_most((direction == D_UP ? D_DOWN : D_UP));
+ screen = get_screen_most((direction == D_UP ? D_DOWN : D_UP), container->workspace->screen);
}
t_ws = &(workspaces[screen->current_workspace]);
new_row = (direction == D_UP ? (t_ws->rows - 1) : 0);
}
t_ws = &(workspaces[screen->current_workspace]);
new_row = (direction == D_UP ? (t_ws->rows - 1) : 0);
int destination_x = (direction == D_LEFT ? (container->x - 1) : (container->x + container->width + 1));
if ((screen = get_screen_containing(destination_x, container->y)) == NULL) {
LOG("Wrapping screen around horizontally\n");
int destination_x = (direction == D_LEFT ? (container->x - 1) : (container->x + container->width + 1));
if ((screen = get_screen_containing(destination_x, container->y)) == NULL) {
LOG("Wrapping screen around horizontally\n");
- screen = get_screen_most((direction == D_LEFT ? D_RIGHT : D_LEFT));
+ screen = get_screen_most((direction == D_LEFT ? D_RIGHT : D_LEFT), container->workspace->screen);
}
t_ws = &(workspaces[screen->current_workspace]);
new_col = (direction == D_LEFT ? (t_ws->cols - 1) : 0);
}
t_ws = &(workspaces[screen->current_workspace]);
new_col = (direction == D_LEFT ? (t_ws->cols - 1) : 0);
*
*/
int handle_motion_notify(void *ignored, xcb_connection_t *conn, xcb_motion_notify_event_t *event) {
*
*/
int handle_motion_notify(void *ignored, xcb_connection_t *conn, xcb_motion_notify_event_t *event) {
- LOG("pointer motion notify, getting screen at %d x %d\n", event->root_x, event->root_y);
+ /* Skip events where the pointer was over a child window, we are only
+ * interested in events on the root window. */
+ if (event->child != 0)
+ return 1;
check_crossing_screen_boundary(event->root_x, event->root_y);
check_crossing_screen_boundary(event->root_x, event->root_y);
*
*/
int handle_mapping_notify(void *ignored, xcb_connection_t *conn, xcb_mapping_notify_event_t *event) {
*
*/
int handle_mapping_notify(void *ignored, xcb_connection_t *conn, xcb_mapping_notify_event_t *event) {
- LOG("\n\nmapping notify\n\n");
-
if (event->request != XCB_MAPPING_KEYBOARD &&
event->request != XCB_MAPPING_MODIFIER)
return 0;
if (event->request != XCB_MAPPING_KEYBOARD &&
event->request != XCB_MAPPING_MODIFIER)
return 0;
+ LOG("Received mapping_notify for keyboard or modifier mapping, re-grabbing keys\n");
xcb_refresh_keyboard_mapping(keysyms, event);
xcb_get_numlock_mask(conn);
ungrab_all_keys(conn);
xcb_refresh_keyboard_mapping(keysyms, event);
xcb_get_numlock_mask(conn);
ungrab_all_keys(conn);
- LOG("Re-grabbing...\n");
}
int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_event_t *event) {
}
int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_event_t *event) {
- LOG("button press!\n");
- LOG("state = %d\n", event->state);
+ LOG("Button %d pressed\n", event->state);
/* This was either a focus for a client’s parent (= titlebar)… */
Client *client = table_get(&by_child, event->event);
bool border_click = false;
/* This was either a focus for a client’s parent (= titlebar)… */
Client *client = table_get(&by_child, event->event);
bool border_click = false;
*
*/
int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure_request_event_t *event) {
*
*/
int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure_request_event_t *event) {
- LOG("configure-request, serial %d\n", event->sequence);
- LOG("event->window = %08x\n", event->window);
- LOG("application wants to be at %dx%d with %dx%d\n", event->x, event->y, event->width, event->height);
+ LOG("window 0x%08x wants to be at %dx%d with %dx%d\n",
+ event->window, event->x, event->y, event->width, event->height);
Client *client = table_get(&by_child, event->window);
if (client == NULL) {
Client *client = table_get(&by_child, event->window);
if (client == NULL) {
- LOG("This client is not mapped, so we don't care and just tell the client that he will get its size\n");
uint32_t mask = 0;
uint32_t values[7];
int c = 0;
uint32_t mask = 0;
uint32_t values[7];
int c = 0;
int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_notify_event_t *event) {
xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_notify_event_t *event) {
xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
- LOG("handle_configure_event for window %08x\n", event->window);
- LOG("event->type = %d, \n", event->response_type);
LOG("event->x = %d, ->y = %d, ->width = %d, ->height = %d\n", event->x, event->y, event->width, event->height);
/* We ignore this sequence twice because events for child and frame should be ignored */
LOG("event->x = %d, ->y = %d, ->width = %d, ->height = %d\n", event->x, event->y, event->width, event->height);
/* We ignore this sequence twice because events for child and frame should be ignored */
- if (workspace_empty) {
- LOG("setting ws to NULL for workspace %d (%p)\n", client->workspace->num,
- client->workspace);
client->workspace->screen = NULL;
client->workspace->screen = NULL;
FREE(client->window_class);
FREE(client->name);
FREE(client->window_class);
FREE(client->name);
*/
int handle_windowname_change(void *data, xcb_connection_t *conn, uint8_t state,
xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop) {
*/
int handle_windowname_change(void *data, xcb_connection_t *conn, uint8_t state,
xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop) {
- LOG("window's name changed.\n");
if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
LOG("_NET_WM_NAME not specified, not changing\n");
return 1;
if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
LOG("_NET_WM_NAME not specified, not changing\n");
return 1;
asprintf(&new_name, "%.*s", xcb_get_property_value_length(prop), (char*)xcb_get_property_value(prop));
/* Convert it to UCS-2 here for not having to convert it later every time we want to pass it to X */
char *ucs2_name = convert_utf8_to_ucs2(new_name, &new_len);
asprintf(&new_name, "%.*s", xcb_get_property_value_length(prop), (char*)xcb_get_property_value(prop));
/* Convert it to UCS-2 here for not having to convert it later every time we want to pass it to X */
char *ucs2_name = convert_utf8_to_ucs2(new_name, &new_len);
- LOG("Name should change to \"%s\"\n", new_name);
+ LOG("_NET_WM_NAME changed to \"%s\"\n", new_name);
free(new_name);
/* Check if they are the same and don’t update if so.
free(new_name);
/* Check if they are the same and don’t update if so.
if ((new_len == client->name_len) &&
(client->name != NULL) &&
(memcmp(client->name, ucs2_name, new_len * 2) == 0)) {
if ((new_len == client->name_len) &&
(client->name != NULL) &&
(memcmp(client->name, ucs2_name, new_len * 2) == 0)) {
- LOG("Name did not change, not updating\n");
free(ucs2_name);
return 1;
}
free(ucs2_name);
return 1;
}
*/
int handle_windowname_change_legacy(void *data, xcb_connection_t *conn, uint8_t state,
xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop) {
*/
int handle_windowname_change_legacy(void *data, xcb_connection_t *conn, uint8_t state,
xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop) {
- LOG("window's name changed (legacy).\n");
if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
LOG("prop == NULL\n");
return 1;
if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
LOG("prop == NULL\n");
return 1;
if (client == NULL)
return 1;
if (client == NULL)
return 1;
- if (client->uses_net_wm_name) {
- LOG("This client is capable of _NET_WM_NAME, ignoring legacy name\n");
+ /* Client capable of _NET_WM_NAME, ignore legacy name changes */
+ if (client->uses_net_wm_name)
/* Save the old pointer to make the update atomic */
char *new_name;
/* Save the old pointer to make the update atomic */
char *new_name;
return 1;
}
/* Convert it to UCS-2 here for not having to convert it later every time we want to pass it to X */
return 1;
}
/* Convert it to UCS-2 here for not having to convert it later every time we want to pass it to X */
- LOG("Name should change to \"%s\"\n", new_name);
+ LOG("WM_NAME changed to \"%s\"\n", new_name);
/* Check if they are the same and don’t update if so. */
if (client->name != NULL &&
strlen(new_name) == strlen(client->name) &&
strcmp(client->name, new_name) == 0) {
/* Check if they are the same and don’t update if so. */
if (client->name != NULL &&
strlen(new_name) == strlen(client->name) &&
strcmp(client->name, new_name) == 0) {
- LOG("Name did not change, not updating\n");
free(new_name);
return 1;
}
free(new_name);
return 1;
}
- LOG("Using legacy window title. Note that in order to get Unicode window titles in i3,"
+ LOG("Using legacy window title. Note that in order to get Unicode window titles in i3, "
"the application has to set _NET_WM_NAME which is in UTF-8 encoding.\n");
char *old_name = client->name;
"the application has to set _NET_WM_NAME which is in UTF-8 encoding.\n");
char *old_name = client->name;
*/
int handle_windowclass_change(void *data, xcb_connection_t *conn, uint8_t state,
xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop) {
*/
int handle_windowclass_change(void *data, xcb_connection_t *conn, uint8_t state,
xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop) {
- LOG("window class changed\n");
if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
LOG("prop == NULL\n");
return 1;
if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
LOG("prop == NULL\n");
return 1;
- LOG("changed to %s\n", new_class);
+ LOG("WM_CLASS changed to %s\n", new_class);
char *old_class = client->window_class;
client->window_class = new_class;
FREE(old_class);
char *old_class = client->window_class;
client->window_class = new_class;
FREE(old_class);
- LOG("got client %s\n", client->name);
- if (client->dock) {
- LOG("this is a dock\n");
if (client->container == NULL || client->container->mode != MODE_STACK)
decorate_window(conn, client, client->frame, client->titlegc, 0);
if (client->container == NULL || client->container->mode != MODE_STACK)
decorate_window(conn, client, client->frame, client->titlegc, 0);
*
*/
int handle_client_message(void *data, xcb_connection_t *conn, xcb_client_message_event_t *event) {
*
*/
int handle_client_message(void *data, xcb_connection_t *conn, xcb_client_message_event_t *event) {
- LOG("client_message\n");
-
if (event->type == atoms[_NET_WM_STATE]) {
if (event->format != 32 || event->data.data32[1] != atoms[_NET_WM_STATE_FULLSCREEN])
return 0;
if (event->type == atoms[_NET_WM_STATE]) {
if (event->format != 32 || event->data.data32[1] != atoms[_NET_WM_STATE_FULLSCREEN])
return 0;
Client *client = table_get(&by_child, event->window);
if (client == NULL)
return 0;
Client *client = table_get(&by_child, event->window);
if (client == NULL)
return 0;
return 1;
}
xcb_size_hints_t size_hints;
return 1;
}
xcb_size_hints_t size_hints;
- LOG("client is %08x / child %08x\n", client->frame, client->child);
/* If the hints were already in this event, use them, if not, request them */
if (reply != NULL)
/* If the hints were already in this event, use them, if not, request them */
if (reply != NULL)
- LOG("window is %08x / %s\n", client->child, client->name);
-
int base_width = 0, base_height = 0;
/* base_width/height are the desired size of the window.
int base_width = 0, base_height = 0;
/* base_width/height are the desired size of the window.
*/
int handle_transient_for(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
xcb_atom_t name, xcb_get_property_reply_t *reply) {
*/
int handle_transient_for(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
xcb_atom_t name, xcb_get_property_reply_t *reply) {
- LOG("Transient hint!\n");
Client *client = table_get(&by_child, window);
if (client == NULL) {
LOG("No such client\n");
Client *client = table_get(&by_child, window);
if (client == NULL) {
LOG("No such client\n");
xcb_window_t transient_for;
if (reply != NULL) {
xcb_window_t transient_for;
if (reply != NULL) {
- if (!xcb_get_wm_transient_for_from_reply(&transient_for, reply)) {
- LOG("Not transient for any window\n");
+ if (!xcb_get_wm_transient_for_from_reply(&transient_for, reply))
} else {
if (!xcb_get_wm_transient_for_reply(conn, xcb_get_wm_transient_for_unchecked(conn, window),
} else {
if (!xcb_get_wm_transient_for_reply(conn, xcb_get_wm_transient_for_unchecked(conn, window),
- &transient_for, NULL)) {
- LOG("Not transient for any window\n");
}
if (client->floating == FLOATING_AUTO_OFF) {
}
if (client->floating == FLOATING_AUTO_OFF) {
*/
int handle_clientleader_change(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
xcb_atom_t name, xcb_get_property_reply_t *prop) {
*/
int handle_clientleader_change(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
xcb_atom_t name, xcb_get_property_reply_t *prop) {
- LOG("client leader changed\n");
if (prop == NULL) {
prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn,
false, window, WM_CLIENT_LEADER, WINDOW, 0, 32), NULL);
if (prop == NULL) {
prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn,
false, window, WM_CLIENT_LEADER, WINDOW, 0, 32), NULL);
if (leader == NULL)
return 1;
if (leader == NULL)
return 1;
- LOG("changed to %08x\n", *leader);
+ LOG("Client leader changed to %08x\n", *leader);
client->leader = *leader;
client->leader = *leader;
}
static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int width, int height) {
}
static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int width, int height) {
- LOG("Rendering internal bar\n");
i3Font *font = load_font(conn, config.font);
i3Screen *screen = r_ws->screen;
enum { SET_NORMAL = 0, SET_FOCUSED = 1 };
i3Font *font = load_font(conn, config.font);
i3Screen *screen = r_ws->screen;
enum { SET_NORMAL = 0, SET_FOCUSED = 1 };
(xcb_char2b_t*)ws->name);
drawn += ws->text_width + 12;
}
(xcb_char2b_t*)ws->name);
drawn += ws->text_width + 12;
}
-
- LOG("done rendering internal\n");
Client *client;
uint32_t values[1];
Client *client;
uint32_t values[1];
- LOG("Ignore enter_notify = %d\n", ignore_enter_notify);
-
FOR_TABLE(workspace)
CIRCLEQ_FOREACH(client, &(workspace->table[cols][rows]->clients), clients) {
/* Change event mask for the decorations */
FOR_TABLE(workspace)
CIRCLEQ_FOREACH(client, &(workspace->table[cols][rows]->clients), clients) {
/* Change event mask for the decorations */
* This function always returns a screen.
*
*/
* This function always returns a screen.
*
*/
-i3Screen *get_screen_most(direction_t direction) {
+i3Screen *get_screen_most(direction_t direction, i3Screen *current) {
i3Screen *screen, *candidate = NULL;
int position = 0;
TAILQ_FOREACH(screen, virtual_screens, screens) {
i3Screen *screen, *candidate = NULL;
int position = 0;
TAILQ_FOREACH(screen, virtual_screens, screens) {
+ if (((direction == D_UP) || (direction == D_DOWN)) &&
+ (current->rect.x != screen->rect.x))
+ continue;
+
+ if (((direction == D_LEFT) || (direction == D_RIGHT)) &&
+ (current->rect.y != screen->rect.y))
+ continue;
+
switch (direction) {
case D_UP:
WIN(screen->rect.y, <= position);
switch (direction) {
case D_UP:
WIN(screen->rect.y, <= position);