From 755540817eb8ea8fb76e435e8d5138bd41d0d739 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 1 Apr 2009 12:31:13 +0200 Subject: [PATCH] Implement scrolling on stack windows and on the bar. This implements ticket #18 --- include/commands.h | 1 + src/commands.c | 3 +- src/handlers.c | 82 +++++++++++++++++++++++++++++----------------- 3 files changed, 54 insertions(+), 32 deletions(-) diff --git a/include/commands.h b/include/commands.h index ce55f935..a2701924 100644 --- a/include/commands.h +++ b/include/commands.h @@ -13,6 +13,7 @@ #ifndef _COMMANDS_H #define _COMMANDS_H +bool focus_window_in_container(xcb_connection_t *conn, Container *container, direction_t direction); void show_workspace(xcb_connection_t *conn, int workspace); void parse_command(xcb_connection_t *conn, const char *command); diff --git a/src/commands.c b/src/commands.c index 36589b10..50e52f9d 100644 --- a/src/commands.c +++ b/src/commands.c @@ -24,8 +24,7 @@ #include "i3.h" #include "xinerama.h" -static bool focus_window_in_container(xcb_connection_t *conn, Container *container, - direction_t direction) { +bool focus_window_in_container(xcb_connection_t *conn, Container *container, direction_t direction) { /* If this container is empty, we’re done */ if (container->currently_focused == NULL) return false; diff --git a/src/handlers.c b/src/handlers.c index e912350c..17f4462d 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -199,27 +199,37 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_ */ 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; - } + SLIST_FOREACH(stack_win, &stack_wins, stack_windows) { + if (stack_win->window != event->event) + continue; + /* A stack window was clicked, we check if it was button4 or button5 + which are scroll up / scroll down. */ + if (event->detail == XCB_BUTTON_INDEX_4 || event->detail == XCB_BUTTON_INDEX_5) { + direction_t direction = (event->detail == XCB_BUTTON_INDEX_4 ? D_UP : D_DOWN); + focus_window_in_container(conn, CUR_CELL, direction); return true; } + /* It was no scrolling, so 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; } @@ -230,21 +240,33 @@ static bool button_press_stackwin(xcb_connection_t *conn, xcb_button_press_event */ 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; - } + TAILQ_FOREACH(screen, virtual_screens, screens) { + if (screen->bar != event->event) + continue; + + LOG("Click on a bar\n"); + + /* Check if the button was one of button4 or button5 (scroll up / scroll down) */ + if (event->detail == XCB_BUTTON_INDEX_4 || event->detail == XCB_BUTTON_INDEX_5) { + int dest_workspace = (event->detail == XCB_BUTTON_INDEX_4 ? + c_ws->num - 1 : + c_ws->num + 1); + if ((dest_workspace >= 0) && (dest_workspace < 10)) + show_workspace(conn, dest_workspace+1); return true; } + 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; } -- 2.39.5