Implement clicking on the bar to switch workspaces
This commit is contained in:
parent
76effaf29a
commit
3a994e4bf7
|
@ -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
|
||||||
|
|
|
@ -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 we’re switching to */
|
/* t_ws (to workspace) is just a convenience pointer to the workspace we’re switching to */
|
||||||
|
|
|
@ -180,6 +180,63 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if the button press was on a stack window, handles focus setting and returns true
|
||||||
|
* if so, or false otherwise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static bool button_press_stackwin(xcb_connection_t *conn, xcb_button_press_event_t *event) {
|
||||||
|
struct Stack_Window *stack_win;
|
||||||
|
SLIST_FOREACH(stack_win, &stack_wins, stack_windows)
|
||||||
|
if (stack_win->window == event->event) {
|
||||||
|
/* A stack window was clicked. We calculate the destination client by
|
||||||
|
dividing the Y position of the event through the height of a window
|
||||||
|
decoration and then set the focus to this client. */
|
||||||
|
i3Font *font = load_font(conn, config.font);
|
||||||
|
int decoration_height = (font->height + 2 + 2);
|
||||||
|
int destination = (event->event_y / decoration_height),
|
||||||
|
c = 0;
|
||||||
|
Client *client;
|
||||||
|
|
||||||
|
LOG("Click on stack_win for client %d\n", destination);
|
||||||
|
CIRCLEQ_FOREACH(client, &(stack_win->container->clients), clients)
|
||||||
|
if (c++ == destination) {
|
||||||
|
set_focus(conn, client);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_event_t *event) {
|
||||||
LOG("button press!\n");
|
LOG("button press!\n");
|
||||||
/* This was either a focus for a client’s parent (= titlebar)… */
|
/* This was either a focus for a client’s parent (= titlebar)… */
|
||||||
|
@ -191,28 +248,14 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
|
||||||
}
|
}
|
||||||
if (client == NULL) {
|
if (client == NULL) {
|
||||||
/* The client was neither on a client’s titlebar nor on a client itself, maybe on a stack_window? */
|
/* The client was neither on a client’s titlebar nor on a client itself, maybe on a stack_window? */
|
||||||
struct Stack_Window *stack_win;
|
if (button_press_stackwin(conn, event))
|
||||||
SLIST_FOREACH(stack_win, &stack_wins, stack_windows)
|
return 1;
|
||||||
if (stack_win->window == event->event) {
|
|
||||||
/* A stack window was clicked. We calculate the destination client by
|
|
||||||
dividing the Y position of the event through the height of a window
|
|
||||||
decoration and then set the focus to this client. */
|
|
||||||
i3Font *font = load_font(conn, config.font);
|
|
||||||
int decoration_height = (font->height + 2 + 2);
|
|
||||||
int destination = (event->event_y / decoration_height),
|
|
||||||
c = 0;
|
|
||||||
Client *client;
|
|
||||||
|
|
||||||
LOG("Click on stack_win for client %d\n", destination);
|
/* Or on a bar? */
|
||||||
CIRCLEQ_FOREACH(client, &(stack_win->container->clients), clients)
|
if (button_press_bar(conn, event))
|
||||||
if (c++ == destination) {
|
return 1;
|
||||||
set_focus(conn, client);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
LOG("Could not handle this button press\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue