]> git.lizzy.rs Git - bspwm.git/commitdiff
Unify tiled and floating pointer actions
authorBastien Dejean <nihilhill@gmail.com>
Thu, 28 Feb 2013 14:04:14 +0000 (15:04 +0100)
committerBastien Dejean <nihilhill@gmail.com>
Thu, 28 Feb 2013 14:04:14 +0000 (15:04 +0100)
The following 'grab_pointer' arguments are removed: 'move_tiled',
'resize_tiled'. The regular 'move' and 'resize_*' arguments shall be
used instead. The 'fence_grip' parameter is no longer meaningful and
has been removed. Moving and resizing now behaves the same for tiled and
floating windows.

README.md
bspwm.1
events.c
messages.c
settings.c
settings.h
tree.c
types.c
types.h

index fcc6b60e566d72b8587b79ec58571ed954c01bda..5564bf3bcb4c70d575bf4d7c1e209878634a37d3 100644 (file)
--- a/README.md
+++ b/README.md
@@ -115,7 +115,7 @@ The following messages are handled:
 
 - `circulate forward|backward` — Circulate the leaves in the given direction.
 
-- `grab_pointer move|resize_corner|resize_side|focus|move_tiled|resize_tiled` — Begin the specified pointer action.
+- `grab_pointer focus|move|resize_side|resize_corner` — Begin the specified pointer action.
 
 - `track_pointer ROOT_X ROOT_Y` — Pass the pointer root coordinates for the current pointer action.
 
@@ -223,8 +223,6 @@ Colors are either [X color names](http://en.wikipedia.org/wiki/X11_color_names)
 
 - `apply_shadow_property` — Enable shadows for floating windows via the `_COMPTON_SHADOW` property.
 
-- `fence_grip` — If the distance to the nearest fence is greater than `fence_grip`, the `resize_tiled` action will not be engaged.
-
 ## Key Features
 
 - Configured and controlled through messages
diff --git a/bspwm.1 b/bspwm.1
index 811a44337e29c800f7775261be5bb9a66bd11214..f3aa4a666c93a821c6dba19876bc4d5a253fd533 100644 (file)
--- a/bspwm.1
+++ b/bspwm.1
@@ -159,7 +159,7 @@ Focus the nearest window matching the given constraints.
 .BI circulate " forward|backward"
 Circulate the leaves in the given direction.
 .TP
-.BI grab_pointer " move|resize_corner|resize_side|focus|move_tiled|resize_tiled"
+.BI grab_pointer " focus|move|resize_side|resize_corner"
 Begin the specified pointer action.
 .TP
 .BI track_pointer " ROOT_X ROOT_Y"
@@ -339,13 +339,6 @@ Prevent floating windows from being raised when they might cover other floating
 Enable shadows for floating windows via the
 .B _COMPTON_SHADOW
 property.
-.TP
-.I fence_grip
-If the distance to the nearest fence is greater than
-.IR fence_grip ,
-the
-.B resize_tiled
-action will not be engaged.
 .SH AUTHOR
 .EX
 Bastien Dejean <baskerville at lavabit.com>
index 370ab79b511337b2a03416c80ab8a774b201ef00..bd29a1944dd24066e5721b33f17e951bc1ccaee1 100644 (file)
--- a/events.c
+++ b/events.c
@@ -280,20 +280,19 @@ void grab_pointer(pointer_action_t pac)
     }
 
     window_location_t loc;
-    bool found_win = locate_window(win, &loc);
-    if (found_win || pac == ACTION_RESIZE_TILED) {
-        fence_distance_t fd;
+    if (locate_window(win, &loc)) {
         client_t *c = NULL;
         frozen_pointer->position = pos;
         frozen_pointer->action = pac;
-        if (found_win) {
-            c = loc.node->client;
-            frozen_pointer->monitor = loc.monitor;
-            frozen_pointer->desktop = loc.desktop;
-            frozen_pointer->node = loc.node;
-            frozen_pointer->client = c;
-            frozen_pointer->window = c->window;
-        }
+        c = loc.node->client;
+        frozen_pointer->monitor = loc.monitor;
+        frozen_pointer->desktop = loc.desktop;
+        frozen_pointer->node = loc.node;
+        frozen_pointer->client = c;
+        frozen_pointer->window = c->window;
+        frozen_pointer->horizontal_fence = NULL;
+        frozen_pointer->vertical_fence = NULL;
+
         switch (pac)  {
             case ACTION_FOCUS:
                 focus_node(loc.monitor, loc.desktop, loc.node, true);
@@ -302,24 +301,23 @@ void grab_pointer(pointer_action_t pac)
             case ACTION_RESIZE_SIDE:
             case ACTION_RESIZE_CORNER:
                 if (is_tiled(c)) {
-                    loc.node->client->floating_rectangle = c->tiled_rectangle;
-                    toggle_floating(loc.node);
-                    arrange(loc.monitor, loc.desktop);
-                } else if (c->fullscreen) {
+                    frozen_pointer->rectangle = c->tiled_rectangle;
+                    frozen_pointer->is_tiled = true;
+                } else if (is_floating(c)) {
+                    frozen_pointer->rectangle = c->floating_rectangle;
+                    frozen_pointer->is_tiled = false;
+                } else {
                     frozen_pointer->action = ACTION_NONE;
                     return;
                 }
-                frozen_pointer->rectangle = c->floating_rectangle;
-
                 if (pac == ACTION_RESIZE_SIDE) {
-                    float W = c->floating_rectangle.width;
-                    float H = c->floating_rectangle.height;
+                    float W = frozen_pointer->rectangle.width;
+                    float H = frozen_pointer->rectangle.height;
                     float ratio = W / H;
-                    float x = pos.x - c->floating_rectangle.x;
-                    float y = pos.y - c->floating_rectangle.y;
+                    float x = pos.x - frozen_pointer->rectangle.x;
+                    float y = pos.y - frozen_pointer->rectangle.y;
                     float diag_a = ratio * y;
                     float diag_b = W - diag_a;
-
                     if (x < diag_a) {
                         if (x < diag_b)
                             frozen_pointer->side = SIDE_LEFT;
@@ -332,9 +330,8 @@ void grab_pointer(pointer_action_t pac)
                             frozen_pointer->side = SIDE_RIGHT;
                     }
                 } else if (pac == ACTION_RESIZE_CORNER) {
-                    int16_t mid_x, mid_y;
-                    mid_x = c->floating_rectangle.x + (c->floating_rectangle.width / 2);
-                    mid_y = c->floating_rectangle.y + (c->floating_rectangle.height / 2);
+                    int16_t mid_x = frozen_pointer->rectangle.x + (frozen_pointer->rectangle.width / 2);
+                    int16_t mid_y = frozen_pointer->rectangle.y + (frozen_pointer->rectangle.height / 2);
                     if (pos.x > mid_x) {
                         if (pos.y > mid_y)
                             frozen_pointer->corner = CORNER_BOTTOM_RIGHT;
@@ -347,21 +344,48 @@ void grab_pointer(pointer_action_t pac)
                             frozen_pointer->corner = CORNER_TOP_LEFT;
                     }
                 }
-                break;
-            case ACTION_RESIZE_TILED:
-                fd = nearest_fence(pos, mon->desk->root);
-                if (fd.fence != NULL && fd.distance < fence_grip) {
-                    frozen_pointer->node = fd.fence;
-                    frozen_pointer->action = pac;
-                    frozen_pointer->rectangle = fd.fence->rectangle;
-                } else {
-                    frozen_pointer->action = ACTION_NONE;
+                if (frozen_pointer->is_tiled) {
+                    if (pac == ACTION_RESIZE_SIDE) {
+                        switch (frozen_pointer->side) {
+                            case SIDE_TOP:
+                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
+                                break;
+                            case SIDE_RIGHT:
+                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
+                                break;
+                            case SIDE_BOTTOM:
+                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
+                                break;
+                            case SIDE_LEFT:
+                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
+                                break;
+                        }
+                    } else if (pac == ACTION_RESIZE_CORNER) {
+                        switch (frozen_pointer->corner) {
+                            case CORNER_TOP_LEFT:
+                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
+                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
+                                break;
+                            case CORNER_TOP_RIGHT:
+                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
+                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
+                                break;
+                            case CORNER_BOTTOM_RIGHT:
+                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
+                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
+                                break;
+                            case CORNER_BOTTOM_LEFT:
+                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
+                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
+                                break;
+                        }
+                    }
+                    if (frozen_pointer->horizontal_fence != NULL)
+                        frozen_pointer->horizontal_ratio = frozen_pointer->horizontal_fence->split_ratio;
+                    if (frozen_pointer->vertical_fence != NULL)
+                        frozen_pointer->vertical_ratio = frozen_pointer->vertical_fence->split_ratio;
                 }
                 break;
-            case ACTION_MOVE_TILED:
-                if (!is_tiled(c))
-                    frozen_pointer->action = ACTION_NONE;
-                break;
             case ACTION_NONE:
                 break;
         }
@@ -378,113 +402,127 @@ void track_pointer(int root_x, int root_y)
     int16_t delta_x, delta_y, x, y, w, h;
     uint16_t width, height;
 
+    pointer_action_t pac = frozen_pointer->action;
     monitor_t *m = frozen_pointer->monitor;
     desktop_t *d = frozen_pointer->desktop;
     node_t *n = frozen_pointer->node;
     client_t *c = frozen_pointer->client;
     xcb_window_t win = frozen_pointer->window;
     xcb_rectangle_t rect = frozen_pointer->rectangle;
+    node_t *vertical_fence = frozen_pointer->vertical_fence;
+    node_t *horizontal_fence = frozen_pointer->horizontal_fence;
 
     x = y = 0;
     w = h = 1;
 
     delta_x = root_x - frozen_pointer->position.x;
     delta_y = root_y - frozen_pointer->position.y;
-    double sr;
-    xcb_query_pointer_reply_t *qpr;
-    xcb_window_t pwin;
-    window_location_t loc;
 
-    switch (frozen_pointer->action) {
+    switch (pac) {
         case ACTION_MOVE:
-            x = rect.x + delta_x;
-            y = rect.y + delta_y;
-            window_move(win, x, y);
-            break;
-        case ACTION_RESIZE_SIDE:
-            switch (frozen_pointer->side) {
-                case SIDE_TOP:
-                    x = rect.x;
-                    y = rect.y + delta_y;
-                    w = rect.width;
-                    h = rect.height - delta_y;
-                    break;
-                case SIDE_RIGHT:
-                    x = rect.x;
-                    y = rect.y;
-                    w = rect.width + delta_x;
-                    h = rect.height;
-                    break;
-                case SIDE_BOTTOM:
-                    x = rect.x;
-                    y = rect.y;
-                    w = rect.width;
-                    h = rect.height + delta_y;
-                    break;
-                case SIDE_LEFT:
-                    x = rect.x + delta_x;
-                    y = rect.y;
-                    w = rect.width - delta_x;
-                    h = rect.height;
-                    break;
+            if (frozen_pointer->is_tiled) {
+                xcb_query_pointer_reply_t *qpr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), NULL);
+                if (qpr != NULL) {
+                    xcb_window_t pwin = qpr->child;
+                    free(qpr);
+                    window_location_t loc;
+                    if (locate_window(pwin, &loc) && is_tiled(loc.node->client)) {
+                        swap_nodes(n, loc.node);
+                        arrange(m, d);
+                        if (m != loc.monitor) {
+                            arrange(loc.monitor, loc.desktop);
+                            frozen_pointer->monitor = loc.monitor;
+                            frozen_pointer->desktop = loc.desktop;
+                        }
+                    }
+                }
+            } else {
+                x = rect.x + delta_x;
+                y = rect.y + delta_y;
+                window_move(win, x, y);
             }
-            width = MAX(1, w);
-            height = MAX(1, h);
-            window_move_resize(win, x, y, width, height);
-            c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
-            window_draw_border(n, d->focus == n, mon == m);
             break;
+        case ACTION_RESIZE_SIDE:
         case ACTION_RESIZE_CORNER:
-            switch (frozen_pointer->corner) {
-                case CORNER_TOP_LEFT:
-                    x = rect.x + delta_x;
-                    y = rect.y + delta_y;
-                    w = rect.width - delta_x;
-                    h = rect.height - delta_y;
-                    break;
-                case CORNER_TOP_RIGHT:
-                    x = rect.x;
-                    y = rect.y + delta_y;
-                    w = rect.width + delta_x;
-                    h = rect.height - delta_y;
-                    break;
-                case CORNER_BOTTOM_LEFT:
-                    x = rect.x + delta_x;
-                    y = rect.y;
-                    w = rect.width - delta_x;
-                    h = rect.height + delta_y;
-                    break;
-                case CORNER_BOTTOM_RIGHT:
-                    x = rect.x;
-                    y = rect.y;
-                    w = rect.width + delta_x;
-                    h = rect.height + delta_y;
-                    break;
-            }
-            width = MAX(1, w);
-            height = MAX(1, h);
-            window_move_resize(win, x, y, width, height);
-            c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
-            window_draw_border(n, d->focus == n, mon == m);
-            break;
-        case ACTION_RESIZE_TILED:
-            if (n->split_type == TYPE_VERTICAL)
-                sr = (double) (root_x - rect.x + window_gap / 2) / rect.width;
-            else
-                sr = (double) (root_y - rect.y + window_gap / 2) / rect.height;
-            sr = MAX(0, sr);
-            sr = MIN(1, sr);
-            n->split_ratio = sr;
-            arrange(mon, mon->desk);
-            break;
-        case ACTION_MOVE_TILED:
-            qpr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), NULL);
-            if (qpr != NULL) {
-                pwin = qpr->child;
-                free(qpr);
-                if (locate_window(pwin, &loc) && loc.monitor == m && loc.desktop == d && is_tiled(loc.node->client)) {
-                    swap_nodes(n, loc.node);
-                    arrange(m, d);
+            if (frozen_pointer->is_tiled) {
+                if (vertical_fence != NULL) {
+                    double sr = frozen_pointer->vertical_ratio + (double) delta_x / vertical_fence->rectangle.width;
+                    sr = MAX(0, sr);
+                    sr = MIN(1, sr);
+                    vertical_fence->split_ratio = sr;
+                }
+                if (horizontal_fence != NULL) {
+                    double sr = frozen_pointer->horizontal_ratio + (double) delta_y / horizontal_fence->rectangle.height;
+                    sr = MAX(0, sr);
+                    sr = MIN(1, sr);
+                    horizontal_fence->split_ratio = sr;
+                }
+                arrange(mon, mon->desk);
+            } else {
+                if (pac == ACTION_RESIZE_SIDE) {
+                    switch (frozen_pointer->side) {
+                        case SIDE_TOP:
+                            x = rect.x;
+                            y = rect.y + delta_y;
+                            w = rect.width;
+                            h = rect.height - delta_y;
+                            break;
+                        case SIDE_RIGHT:
+                            x = rect.x;
+                            y = rect.y;
+                            w = rect.width + delta_x;
+                            h = rect.height;
+                            break;
+                        case SIDE_BOTTOM:
+                            x = rect.x;
+                            y = rect.y;
+                            w = rect.width;
+                            h = rect.height + delta_y;
+                            break;
+                        case SIDE_LEFT:
+                            x = rect.x + delta_x;
+                            y = rect.y;
+                            w = rect.width - delta_x;
+                            h = rect.height;
+                            break;
+                    }
+                    width = MAX(1, w);
+                    height = MAX(1, h);
+                    window_move_resize(win, x, y, width, height);
+                    c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
+                    window_draw_border(n, d->focus == n, mon == m);
+                } else if (pac == ACTION_RESIZE_CORNER) {
+                    switch (frozen_pointer->corner) {
+                        case CORNER_TOP_LEFT:
+                            x = rect.x + delta_x;
+                            y = rect.y + delta_y;
+                            w = rect.width - delta_x;
+                            h = rect.height - delta_y;
+                            break;
+                        case CORNER_TOP_RIGHT:
+                            x = rect.x;
+                            y = rect.y + delta_y;
+                            w = rect.width + delta_x;
+                            h = rect.height - delta_y;
+                            break;
+                        case CORNER_BOTTOM_LEFT:
+                            x = rect.x + delta_x;
+                            y = rect.y;
+                            w = rect.width - delta_x;
+                            h = rect.height + delta_y;
+                            break;
+                        case CORNER_BOTTOM_RIGHT:
+                            x = rect.x;
+                            y = rect.y;
+                            w = rect.width + delta_x;
+                            h = rect.height + delta_y;
+                            break;
+                    }
+                    width = MAX(1, w);
+                    height = MAX(1, h);
+                    window_move_resize(win, x, y, width, height);
+                    c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
+                    window_draw_border(n, d->focus == n, mon == m);
                 }
             }
             break;
index c1442c8600f8c8998737ec08f9b6f53588908514..3abdd83e24305fbc5cb4a3195286d8f777df6b0f 100644 (file)
@@ -449,8 +449,6 @@ void set_setting(char *name, char *value, char *rsp)
 
     if (strcmp(name, "border_width") == 0) {
         sscanf(value, "%u", &border_width);
-    } else if (strcmp(name, "fence_grip") == 0) {
-        sscanf(value, "%u", &fence_grip);
     } else if (strcmp(name, "window_gap") == 0) {
         sscanf(value, "%i", &window_gap);
     } else if (strcmp(name, "left_padding") == 0) {
@@ -533,8 +531,6 @@ void get_setting(char *name, char* rsp)
 
     if (strcmp(name, "border_width") == 0)
         snprintf(rsp, BUFSIZ, "%u", border_width);
-    else if (strcmp(name, "fence_grip") == 0)
-        snprintf(rsp, BUFSIZ, "%u", fence_grip);
     else if (strcmp(name, "window_gap") == 0)
         snprintf(rsp, BUFSIZ, "%i", window_gap);
     else if (strcmp(name, "left_padding") == 0)
@@ -768,12 +764,6 @@ bool parse_pointer_action(char *s, pointer_action_t *a)
     } else if (strcmp(s, "focus") == 0) {
         *a = ACTION_FOCUS;
         return true;
-    } else if (strcmp(s, "move_tiled") == 0) {
-        *a = ACTION_MOVE_TILED;
-        return true;
-    } else if (strcmp(s, "resize_tiled") == 0) {
-        *a = ACTION_RESIZE_TILED;
-        return true;
     }
     return false;
 }
index 756dfe56e07791b500f1463dbf960a610bbc78e3..d6dcdec993420e6dc58ab5b9efc8dd82634e0b52 100644 (file)
@@ -58,7 +58,6 @@ void load_settings(void)
 
     border_width = BORDER_WIDTH;
     window_gap = WINDOW_GAP;
-    fence_grip = FENCE_GRIP;
 
     borderless_monocle = BORDERLESS_MONOCLE;
     gapless_monocle = GAPLESS_MONOCLE;
index 2970cc3e1c6d9729f3e838ef814e8bbb246d0506..4ed1ec0be4d303b085ffc767da363643b95b374a 100644 (file)
@@ -19,7 +19,6 @@
 #define BORDER_WIDTH   1
 #define WINDOW_GAP     6
 #define SPLIT_RATIO    0.5
-#define FENCE_GRIP     20
 
 #define BORDERLESS_MONOCLE     false
 #define GAPLESS_MONOCLE        false
@@ -47,7 +46,6 @@ uint32_t urgent_border_color_pxl;
 
 unsigned int border_width;
 int window_gap;
-unsigned int fence_grip;
 
 bool borderless_monocle;
 bool gapless_monocle;
diff --git a/tree.c b/tree.c
index 6d41fb665e2781b292ac95b702e9d16044a76337..8e6901c634dcb35beb1ef7e0fd21b17879b78e62 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -140,40 +140,6 @@ void move_fence(node_t *n, direction_t dir, fence_move_t mov)
         change_split_ratio(fence, CHANGE_DECREASE);
 }
 
-unsigned int distance_to_fence(xcb_point_t pt, node_t *fence)
-{
-    xcb_rectangle_t rect = fence->rectangle;
-    if (fence->split_type == TYPE_VERTICAL) {
-        int fx = rect.x + fence->split_ratio * rect.width - window_gap / 2;
-        return ABS(pt.x - fx);
-    } else {
-        int fy = rect.y + fence->split_ratio * rect.height - window_gap / 2;
-        return ABS(pt.y - fy);
-    }
-}
-
-fence_distance_t nearest_fence(xcb_point_t pt, node_t *tree)
-{
-    fence_distance_t fd;
-    if (tree == NULL || is_leaf(tree)) {
-        fd.fence = NULL;
-    } else {
-        fd.fence = tree;
-        fd.distance = distance_to_fence(pt, tree);
-        fence_distance_t first_fd = nearest_fence(pt, tree->first_child);
-        fence_distance_t second_fd = nearest_fence(pt, tree->second_child);
-        if (first_fd.fence != NULL && fd.distance > first_fd.distance) {
-            fd.fence = first_fd.fence;
-            fd.distance = first_fd.distance;
-        }
-        if (second_fd.fence != NULL && fd.distance > second_fd.distance) {
-            fd.fence = second_fd.fence;
-            fd.distance = second_fd.distance;
-        }
-    }
-    return fd;
-}
-
 void rotate_tree(node_t *n, rotate_t rot)
 {
     if (n == NULL || is_leaf(n))
diff --git a/types.c b/types.c
index 20f43a1f0812109b6564fed5b8ebe07e3ea96e17..9d5eafefd2c59b4f2cb0d6389e1b876c796819cd 100644 (file)
--- a/types.c
+++ b/types.c
@@ -156,7 +156,7 @@ pointer_state_t *make_pointer_state(void)
     pointer_state_t *p = malloc(sizeof(pointer_state_t));
     p->monitor = NULL;
     p->desktop = NULL;
-    p->node = NULL;
+    p->node = p->vertical_fence = p->horizontal_fence = NULL;
     p->client = NULL;
     p->window = XCB_NONE;
     return p;
diff --git a/types.h b/types.h
index 6477aa1b790f12df572c45a281030cfc3589a1e0..6e00d7d4f8dbf3013137e6e88af2fd43db5164b3 100644 (file)
--- a/types.h
+++ b/types.h
@@ -109,12 +109,10 @@ typedef enum {
 
 typedef enum {
     ACTION_NONE,
+    ACTION_FOCUS,
     ACTION_MOVE,
-    ACTION_RESIZE_CORNER,
     ACTION_RESIZE_SIDE,
-    ACTION_FOCUS,
-    ACTION_MOVE_TILED,
-    ACTION_RESIZE_TILED
+    ACTION_RESIZE_CORNER
 } pointer_action_t;
 
 typedef struct {
@@ -205,11 +203,16 @@ typedef struct {
     xcb_point_t position;
     pointer_action_t action;
     xcb_rectangle_t rectangle;
+    node_t *vertical_fence;
+    node_t *horizontal_fence;
     monitor_t *monitor;
     desktop_t *desktop;
     node_t *node;
     client_t *client;
     xcb_window_t window;
+    bool is_tiled;
+    double vertical_ratio;
+    double horizontal_ratio;
     corner_t corner;
     side_t side;
 } pointer_state_t;