]> git.sur5r.net Git - i3/i3/commitdiff
Implement scrolling on stack windows and on the bar. This implements ticket #18
authorMichael Stapelberg <michael+x200@stapelberg.de>
Wed, 1 Apr 2009 10:31:13 +0000 (12:31 +0200)
committerMichael Stapelberg <michael+x200@stapelberg.de>
Wed, 1 Apr 2009 10:31:13 +0000 (12:31 +0200)
include/commands.h
src/commands.c
src/handlers.c

index ce55f93589b49fec626b72d3e54887936ab8c6ec..a2701924b87d06cc5a48b8ef7be23b9d58667f55 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef _COMMANDS_H
 #define _COMMANDS_H
 
 #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);
 
 void show_workspace(xcb_connection_t *conn, int workspace);
 void parse_command(xcb_connection_t *conn, const char *command);
 
index 36589b10fd7459e37e575ff9e6e9f4fcad42f2b7..50e52f9d09660db8ca58f46cb3604532621228b6 100644 (file)
@@ -24,8 +24,7 @@
 #include "i3.h"
 #include "xinerama.h"
 
 #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;
         /* If this container is empty, we’re done */
         if (container->currently_focused == NULL)
                 return false;
index e912350cb6f11d4cb58e33c6fe088d13b6ef59e8..17f4462d51cd97cfc3268ac5656a12bc1e3e75d3 100644 (file)
@@ -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;
  */
 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;
                 }
 
                         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;
 }
 
         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;
  */
 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;
                 }
                         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;
 }
 
         return false;
 }