]> git.sur5r.net Git - i3/i3/commitdiff
Implement snapping
authorMichael Stapelberg <michael+git@stapelberg.de>
Tue, 10 Feb 2009 22:42:28 +0000 (23:42 +0100)
committerMichael Stapelberg <michael+git@stapelberg.de>
Tue, 10 Feb 2009 22:42:28 +0000 (23:42 +0100)
TODO
mainx.c

diff --git a/TODO b/TODO
index d3bd7b28fe0e80b23d1272b5c6028f2791c6c1e9..628853ae8eb7e21e07ab335e02f3a4199c60e380 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
 TODO list, in order of importance:
 
- * colspan/rowspan (snap)
  * freely resizable (e.g. using your mouse, for now) percentage of rows/cols
  * fullscreen (handling of applications)
  * fullscreen (implementing a mode, like default, stacked)
diff --git a/mainx.c b/mainx.c
index af1d5e9f67be8b8b871e9110bf7574ca0a127e2b..a6a0401b5e0944b0833fd1df8490689d724668a3 100644 (file)
--- a/mainx.c
+++ b/mainx.c
@@ -740,6 +740,73 @@ static void move_current_window(xcb_connection_t *connection, direction_t direct
        render_layout(connection);
 }
 
+/*
+ * "Snaps" the current container (not possible for windows, because it works at table base)
+ * to the given direction, that is, adjusts cellspan/rowspan
+ *
+ */
+static void snap_current_container(xcb_connection_t *connection, direction_t direction) {
+       printf("snapping container to direction %d\n", direction);
+
+       Container *container = CUR_CELL;
+       int i;
+
+       assert(container != NULL);
+
+       switch (direction) {
+               case D_LEFT:
+                       /* Snap to the left is actually a move to the left and then a snap right */
+                       move_current_window(connection, D_LEFT);
+                       snap_current_container(connection, D_RIGHT);
+                       return;
+               case D_RIGHT:
+                       /* Check if the cell is used */
+                       if (!cell_exists(container->col + 1, container->row) ||
+                               table[container->col+1][container->row]->currently_focused != NULL) {
+                               printf("cannot snap to right - the cell is already used\n");
+                               return;
+                       }
+
+                       /* Check if there are other cells with rowspan, which are in our way.
+                        * If so, reduce their rowspan. */
+                       for (i = container->row-1; i >= 0; i--) {
+                               printf("we got cell %d, %d with rowspan %d\n",
+                                               container->col+1, i, table[container->col+1][i]->rowspan);
+                               while ((table[container->col+1][i]->rowspan-1) >= (container->row - i))
+                                       table[container->col+1][i]->rowspan--;
+                               printf("new rowspan = %d\n", table[container->col+1][i]->rowspan);
+                       }
+
+                       container->colspan++;
+                       break;
+               case D_UP:
+                       move_current_window(connection, D_UP);
+                       snap_current_container(connection, D_DOWN);
+                       return;
+               case D_DOWN:
+                       printf("snapping down\n");
+                       if (!cell_exists(container->col, container->row+1) ||
+                               table[container->col][container->row+1]->currently_focused != NULL) {
+                               printf("cannot snap down - the cell is already used\n");
+                               return;
+                       }
+
+                       for (i = container->col-1; i >= 0; i--) {
+                               printf("we got cell %d, %d with colspan %d\n",
+                                               i, container->row+1, table[i][container->row+1]->colspan);
+                               while ((table[i][container->row+1]->colspan-1) >= (container->col - i))
+                                       table[i][container->row+1]->colspan--;
+                               printf("new colspan = %d\n", table[i][container->row+1]->colspan);
+
+                       }
+
+                       container->rowspan++;
+                       break;
+       }
+
+       render_layout(connection);
+}
+
 int format_event(xcb_generic_event_t *e)
 {           
     uint8_t sendEvent;
@@ -870,8 +937,7 @@ static void parse_command(xcb_connection_t *conn, const char *command) {
                else if (action == ACTION_MOVE)
                        move_current_window(conn, direction);
                else if (action == ACTION_SNAP)
-                       /* TODO: implement */
-                       printf("snap not yet implemented\n");
+                       snap_current_container(conn, direction);
 
                rest++;
 
@@ -910,9 +976,12 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
                }
        }
 
+       /* No match? Then it was an actively grabbed key, that is with Mode_switch, and
+          the user did not press Mode_switch, so just pass it… */
        if (best_match == TAILQ_END(&bindings)) {
-               printf("This key was not bound by us?! (most likely a bug)\n");
-               return 1; /* TODO: return 0? what do the codes mean? */
+               xcb_allow_events(conn, ReplayKeyboard, event->time);
+               xcb_flush(conn);
+               return 1;
        }
 
        if (event->state & 0x2) {
@@ -924,14 +993,6 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
                return 1;
        }
 
-       /* If this was an actively grabbed key, and we did not handle it, we need to pass it */
-       if (best_match->mods & BIND_MODE_SWITCH) {
-               printf("passing...\n");
-               xcb_allow_events(conn, ReplayKeyboard, event->time);
-               xcb_flush(conn);
-               return 1;
-       }
-
        parse_command(conn, best_match->command);
        return 1;
 }
@@ -1169,10 +1230,15 @@ int main(int argc, char *argv[], char *env[]) {
        BIND(46, BIND_MOD_1, "k");
        BIND(47, BIND_MOD_1, "l");
 
-       BIND(44, BIND_MOD_1 | BIND_CONTROL, "mh");
-       BIND(45, BIND_MOD_1 | BIND_CONTROL, "mj");
-       BIND(46, BIND_MOD_1 | BIND_CONTROL, "mk");
-       BIND(47, BIND_MOD_1 | BIND_CONTROL, "ml");
+       BIND(44, BIND_MOD_1 | BIND_CONTROL, "sh");
+       BIND(45, BIND_MOD_1 | BIND_CONTROL, "sj");
+       BIND(46, BIND_MOD_1 | BIND_CONTROL, "sk");
+       BIND(47, BIND_MOD_1 | BIND_CONTROL, "sl");
+
+       BIND(44, BIND_MOD_1 | BIND_SHIFT, "mh");
+       BIND(45, BIND_MOD_1 | BIND_SHIFT, "mj");
+       BIND(46, BIND_MOD_1 | BIND_SHIFT, "mk");
+       BIND(47, BIND_MOD_1 | BIND_SHIFT, "ml");
 
        Binding *bind;
        TAILQ_FOREACH(bind, &bindings, bindings) {