]> git.sur5r.net Git - i3/i3/commitdiff
Use drag_pointer from floating.c for the resize handler
authorMichael Stapelberg <michael@stapelberg.de>
Wed, 24 Jun 2009 15:40:34 +0000 (17:40 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 24 Jun 2009 15:40:34 +0000 (17:40 +0200)
include/floating.h
src/floating.c
src/resize.c

index a4f8619ac4e1b38abd52bb4424fdf76aae9491cc..b0c0b7cc17c78966e5b6a82a1ca74c92dff0e802 100644 (file)
 #ifndef _FLOATING_H
 #define _FLOATING_H
 
+/** Callback for dragging */
+typedef void(*callback_t)(Rect*, uint32_t, uint32_t);
+
+/** On which border was the dragging initiated? */
+typedef enum { BORDER_LEFT, BORDER_RIGHT, BORDER_TOP, BORDER_BOTTOM} border_t;
+
 /**
  * Enters floating mode for the given client.
  * Correctly takes care of the position/size (separately stored for tiling/floating mode)
@@ -67,4 +73,15 @@ void floating_move(xcb_connection_t *conn, Client *currently_focused, direction_
  */
 void floating_toggle_hide(xcb_connection_t *conn, Workspace *workspace);
 
+/**
+ * This function grabs your pointer and lets you drag stuff around (borders).
+ * Every time you move your mouse, an XCB_MOTION_NOTIFY event will be received
+ * and the given callback will be called with the parameters specified (client,
+ * border on which the click originally was), the original rect of the client,
+ * the event and the new coordinates (x, y).
+ *
+ */
+void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_press_event_t *event,
+                  xcb_window_t confine_to, border_t border, callback_t callback);
+
 #endif
index 6e5bec52b65dbe3cb8fc0bc79809e6dd71db779b..5deda47a7c6a536065c7092fc94e8aa2725bf091 100644 (file)
 #include "debug.h"
 #include "layout.h"
 #include "client.h"
-
-/* On which border was the dragging initiated? */
-typedef enum { BORDER_LEFT, BORDER_RIGHT, BORDER_TOP, BORDER_BOTTOM} border_t;
-/* Callback for dragging */
-typedef void(*callback_t)(Rect*, uint32_t, uint32_t);
-
-/* Forward definitions */
-static void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_press_event_t *event,
-                         border_t border, callback_t callback);
+#include "floating.h"
 
 /*
  * Toggles floating mode for the given client.
@@ -238,7 +230,7 @@ int floating_border_click(xcb_connection_t *conn, Client *client, xcb_button_pre
 
         LOG("border = %d\n", border);
 
-        drag_pointer(conn, client, event, border, resize_callback);
+        drag_pointer(conn, client, event, XCB_NONE, border, resize_callback);
 
         return 1;
 }
@@ -264,7 +256,7 @@ void floating_drag_window(xcb_connection_t *conn, Client *client, xcb_button_pre
         }
 
 
-        drag_pointer(conn, client, event, BORDER_TOP /* irrelevant */, drag_window_callback);
+        drag_pointer(conn, client, event, XCB_NONE, BORDER_TOP /* irrelevant */, drag_window_callback);
 }
 
 /*
@@ -275,12 +267,13 @@ void floating_drag_window(xcb_connection_t *conn, Client *client, xcb_button_pre
  * the event and the new coordinates (x, y).
  *
  */
-static void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_press_event_t *event,
-                         border_t border, callback_t callback) {
+void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_press_event_t *event,
+                  xcb_window_t confine_to, border_t border, callback_t callback) {
         xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
         uint32_t new_x, new_y;
         Rect old_rect;
-        memcpy(&old_rect, &(client->rect), sizeof(Rect));
+        if (client != NULL)
+                memcpy(&old_rect, &(client->rect), sizeof(Rect));
 
         /* Grab the pointer */
         /* TODO: returncode */
@@ -290,7 +283,7 @@ static void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_pres
                         XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION, /* which events to let through */
                         XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
                         XCB_GRAB_MODE_ASYNC, /* keyboard mode */
-                        XCB_NONE,            /* confine_to = in which window should the cursor stay */
+                        confine_to,          /* confine_to = in which window should the cursor stay */
                         XCB_NONE,            /* don’t display a special cursor */
                         XCB_CURRENT_TIME);
 
index 7a20061c7d96793e7360c510c43560e7a0c05167..3a639e2ede9587f8fdb4e0c53cd11f3c375c86fc 100644 (file)
@@ -26,6 +26,7 @@
 #include "layout.h"
 #include "xinerama.h"
 #include "config.h"
+#include "floating.h"
 
 /*
  * Renders the resize window between the first/second container and resizes
@@ -35,7 +36,6 @@
 int resize_graphical_handler(xcb_connection_t *conn, Workspace *ws, int first, int second,
                              resize_orientation_t orientation, xcb_button_press_event_t *event) {
         int new_position;
-        xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
         xcb_screen_t *root_screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
         i3Screen *screen = get_screen_containing(event->root_x, event->root_y);
         if (screen == NULL) {
@@ -91,59 +91,32 @@ int resize_graphical_handler(xcb_connection_t *conn, Workspace *ws, int first, i
 
         xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, helpwin);
 
-        xcb_grab_pointer(conn, false, root, XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION,
-                        XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, grabwin, XCB_NONE, XCB_CURRENT_TIME);
-
         xcb_flush(conn);
 
-        xcb_generic_event_t *inside_event;
-        /* I’ve always wanted to have my own eventhandler… */
-        while ((inside_event = xcb_wait_for_event(conn))) {
-                /* Same as get_event_handler in xcb */
-                int nr = inside_event->response_type;
-                if (nr == 0) {
-                        /* An error occured */
-                        handle_event(NULL, conn, inside_event);
-                        free(inside_event);
-                        continue;
-                }
-                assert(nr < 256);
-                nr &= XCB_EVENT_RESPONSE_TYPE_MASK;
-                assert(nr >= 2);
-
-                /* Check if we need to escape this loop */
-                if (nr == XCB_BUTTON_RELEASE)
-                        break;
-
-                switch (nr) {
-                        case XCB_MOTION_NOTIFY: {
-                                xcb_motion_notify_event_t *motion_event = (xcb_motion_notify_event_t*)inside_event;
-                                if (orientation == O_VERTICAL) {
-                                        if (motion_event->root_x < (screen->rect.x + screen->rect.width) &&
-                                            motion_event->root_x > screen->rect.x) {
-                                                values[0] = new_position = ((xcb_motion_notify_event_t*)inside_event)->root_x;
-                                                xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_X, values);
-                                        } else {
-                                                LOG("Ignoring new position\n");
-                                        }
-                                } else {
-                                        values[0] = new_position = ((xcb_motion_notify_event_t*)inside_event)->root_y;
-                                        xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_Y, values);
-                                }
-
-                                xcb_flush(conn);
-                                break;
-                        }
-                        default:
-                                LOG("Passing to original handler\n");
-                                /* Use original handler */
-                                xcb_event_handle(&evenths, inside_event);
-                                break;
+        void resize_callback(Rect *old_rect, uint32_t new_x, uint32_t new_y) {
+                LOG("new x = %d, y = %d\n", new_x, new_y);
+                if (orientation == O_VERTICAL) {
+                        /* Check if the new coordinates are within screen boundaries */
+                        if (new_x > (screen->rect.x + screen->rect.width) ||
+                            new_x < screen->rect.x)
+                                return;
+
+                        values[0] = new_position = new_x;
+                        xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_X, values);
+                } else {
+                        if (new_y > (screen->rect.y + screen->rect.height) ||
+                            new_y < screen->rect.y)
+                                return;
+
+                        values[0] = new_position = new_y;
+                        xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_Y, values);
                 }
-                free(inside_event);
+
+                xcb_flush(conn);
         }
 
-        xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
+        drag_pointer(conn, NULL, event, grabwin, BORDER_TOP, resize_callback);
+
         xcb_destroy_window(conn, helpwin);
         xcb_destroy_window(conn, grabwin);
         xcb_flush(conn);