Implement clicking on the bar to switch workspaces

This commit is contained in:
Michael Stapelberg 2009-03-15 17:49:25 +01:00
parent 76effaf29a
commit 3a994e4bf7
4 changed files with 70 additions and 22 deletions

View File

@ -13,6 +13,7 @@
#ifndef _COMMANDS_H #ifndef _COMMANDS_H
#define _COMMANDS_H #define _COMMANDS_H
void show_workspace(xcb_connection_t *conn, int workspace);
void parse_command(xcb_connection_t *conn, const char *command); void parse_command(xcb_connection_t *conn, const char *command);
#endif #endif

View File

@ -447,7 +447,11 @@ static void move_current_window_to_workspace(xcb_connection_t *conn, int workspa
render_layout(conn); render_layout(conn);
} }
static void show_workspace(xcb_connection_t *conn, int workspace) { /*
* Switches to the given workspace
*
*/
void show_workspace(xcb_connection_t *conn, int workspace) {
Client *client; Client *client;
xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root; xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
/* t_ws (to workspace) is just a convenience pointer to the workspace were switching to */ /* t_ws (to workspace) is just a convenience pointer to the workspace were switching to */

View File

@ -180,17 +180,12 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_
return 1; return 1;
} }
int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_event_t *event) { /*
LOG("button press!\n"); * Checks if the button press was on a stack window, handles focus setting and returns true
/* This was either a focus for a clients parent (= titlebar)… */ * if so, or false otherwise.
Client *client = table_get(byChild, event->event); *
bool border_click = false; */
if (client == NULL) { static bool button_press_stackwin(xcb_connection_t *conn, xcb_button_press_event_t *event) {
client = table_get(byParent, event->event);
border_click = true;
}
if (client == NULL) {
/* The client was neither on a clients titlebar nor on a client itself, maybe on a stack_window? */
struct Stack_Window *stack_win; struct Stack_Window *stack_win;
SLIST_FOREACH(stack_win, &stack_wins, stack_windows) SLIST_FOREACH(stack_win, &stack_wins, stack_windows)
if (stack_win->window == event->event) { if (stack_win->window == event->event) {
@ -207,12 +202,60 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
CIRCLEQ_FOREACH(client, &(stack_win->container->clients), clients) CIRCLEQ_FOREACH(client, &(stack_win->container->clients), clients)
if (c++ == destination) { if (c++ == destination) {
set_focus(conn, client); set_focus(conn, client);
return 1; return true;
} }
return 1; return true;
} }
return false;
}
/*
* Checks if the button press was on a bar, switches to the workspace and returns true
* if so, or false otherwise.
*
*/
static bool button_press_bar(xcb_connection_t *conn, xcb_button_press_event_t *event) {
i3Screen *screen;
TAILQ_FOREACH(screen, virtual_screens, screens)
if (screen->bar == event->event) {
LOG("Click on a bar\n");
i3Font *font = load_font(conn, config.font);
int workspace = event->event_x / (font->height + 6),
c = 0;
/* Because workspaces can be on different screens, we need to loop
through all of them and decide to count it based on its ->screen */
for (int i = 0; i < 10; i++)
if ((workspaces[i].screen == screen) && (c++ == workspace)) {
show_workspace(conn, i+1);
return true;
}
return true;
}
return false;
}
int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_event_t *event) {
LOG("button press!\n");
/* This was either a focus for a clients parent (= titlebar)… */
Client *client = table_get(byChild, event->event);
bool border_click = false;
if (client == NULL) {
client = table_get(byParent, event->event);
border_click = true;
}
if (client == NULL) {
/* The client was neither on a clients titlebar nor on a client itself, maybe on a stack_window? */
if (button_press_stackwin(conn, event))
return 1;
/* Or on a bar? */
if (button_press_bar(conn, event))
return 1;
LOG("Could not handle this button press\n");
return 1; return 1;
} }

View File

@ -177,7 +177,7 @@ static void initialize_screen(xcb_connection_t *conn, i3Screen *screen, Workspac
screen->rect.x + screen->rect.width, screen->rect.x + screen->rect.width,
font->height + 6}; font->height + 6};
uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK; uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
uint32_t values[] = {1, XCB_EVENT_MASK_EXPOSURE}; uint32_t values[] = {1, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS};
screen->bar = create_window(conn, bar_rect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, mask, values); screen->bar = create_window(conn, bar_rect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, mask, values);
screen->bargc = xcb_generate_id(conn); screen->bargc = xcb_generate_id(conn);
xcb_create_gc(conn, screen->bargc, screen->bar, 0, 0); xcb_create_gc(conn, screen->bargc, screen->bar, 0, 0);