]> git.sur5r.net Git - i3/i3/blobdiff - src/ipc.c
Don’t overwrite border width when already set (placeholders).
[i3/i3] / src / ipc.c
index 8413d0a6b6412edf6a84c92a5d55ff754bcae1fc..acd2267bdb61f761f34511d3adaf3bec7afcff50 100644 (file)
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -151,6 +151,60 @@ static void dump_rect(yajl_gen gen, const char *name, Rect r) {
     y(map_close);
 }
 
+static void dump_binding(yajl_gen gen, Binding *bind) {
+    y(map_open);
+    ystr("input_code");
+    y(integer, bind->keycode);
+
+    ystr("input_type");
+    ystr((const char *)(bind->input_type == B_KEYBOARD ? "keyboard" : "mouse"));
+
+    ystr("symbol");
+    if (bind->symbol == NULL)
+        y(null);
+    else
+        ystr(bind->symbol);
+
+    ystr("command");
+    ystr(bind->command);
+
+    ystr("mods");
+    y(array_open);
+    for (int i = 0; i < 8; i++) {
+        if (bind->mods & (1 << i)) {
+            switch (1 << i) {
+                case XCB_MOD_MASK_SHIFT:
+                    ystr("shift");
+                    break;
+                case XCB_MOD_MASK_LOCK:
+                    ystr("lock");
+                    break;
+                case XCB_MOD_MASK_CONTROL:
+                    ystr("ctrl");
+                    break;
+                case XCB_MOD_MASK_1:
+                    ystr("Mod1");
+                    break;
+                case XCB_MOD_MASK_2:
+                    ystr("Mod2");
+                    break;
+                case XCB_MOD_MASK_3:
+                    ystr("Mod3");
+                    break;
+                case XCB_MOD_MASK_4:
+                    ystr("Mod4");
+                    break;
+                case XCB_MOD_MASK_5:
+                    ystr("Mod5");
+                    break;
+            }
+        }
+    }
+    y(array_close);
+
+    y(map_close);
+}
+
 void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
     y(map_open);
     ystr("id");
@@ -293,14 +347,17 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
     y(integer, con->current_border_width);
 
     dump_rect(gen, "rect", con->rect);
+    dump_rect(gen, "deco_rect", con->deco_rect);
     dump_rect(gen, "window_rect", con->window_rect);
     dump_rect(gen, "geometry", con->geometry);
 
     ystr("name");
     if (con->window && con->window->name)
         ystr(i3string_as_utf8(con->window->name));
-    else
+    else if (con->name != NULL)
         ystr(con->name);
+    else
+        y(null);
 
     if (con->type == CT_WORKSPACE) {
         ystr("num");
@@ -337,6 +394,12 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
             ystr(i3string_as_utf8(con->window->name));
         }
 
+        ystr("transient_for");
+        if (con->window->transient_for == XCB_NONE)
+            y(null);
+        else
+            y(integer, con->window->transient_for);
+
         y(map_close);
     }
 
@@ -512,6 +575,16 @@ static void dump_bar_config(yajl_gen gen, Barconfig *config) {
             break;
     }
 
+    if (config->wheel_up_cmd) {
+        ystr("wheel_up_cmd");
+        ystr(config->wheel_up_cmd);
+    }
+
+    if (config->wheel_down_cmd) {
+        ystr("wheel_down_cmd");
+        ystr(config->wheel_down_cmd);
+    }
+
     ystr("position");
     if (config->position == P_BOTTOM)
         ystr("bottom");
@@ -600,10 +673,7 @@ IPC_HANDLER(get_workspaces) {
             y(map_open);
 
             ystr("num");
-            if (ws->num == -1)
-                y(null);
-            else
-                y(integer, ws->num);
+            y(integer, ws->num);
 
             ystr("name");
             ystr(ws->name);
@@ -1051,21 +1121,23 @@ int ipc_create_socket(const char *filename) {
 }
 
 /*
- * For the workspace "focus" event we send, along the usual "change" field,
- * also the current and previous workspace, in "current" and "old"
- * respectively.
+ * Generates a json workspace event. Returns a dynamically allocated yajl
+ * generator. Free with yajl_gen_free().
  */
-void ipc_send_workspace_focus_event(Con *current, Con *old) {
+yajl_gen ipc_marshal_workspace_event(const char *change, Con *current, Con *old) {
     setlocale(LC_NUMERIC, "C");
     yajl_gen gen = ygenalloc();
 
     y(map_open);
 
     ystr("change");
-    ystr("focus");
+    ystr(change);
 
     ystr("current");
-    dump_node(gen, current, false);
+    if (current == NULL)
+        y(null);
+    else
+        dump_node(gen, current, false);
 
     ystr("old");
     if (old == NULL)
@@ -1075,13 +1147,26 @@ void ipc_send_workspace_focus_event(Con *current, Con *old) {
 
     y(map_close);
 
+    setlocale(LC_NUMERIC, "");
+
+    return gen;
+}
+
+/*
+ * For the workspace events we send, along with the usual "change" field, also
+ * the workspace container in "current". For focus events, we send the
+ * previously focused workspace in "old".
+ */
+void ipc_send_workspace_event(const char *change, Con *current, Con *old) {
+    yajl_gen gen = ipc_marshal_workspace_event(change, current, old);
+
     const unsigned char *payload;
     ylength length;
     y(get_buf, &payload, &length);
 
     ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, (const char *)payload);
+
     y(free);
-    setlocale(LC_NUMERIC, "");
 }
 
 /**
@@ -1132,3 +1217,33 @@ void ipc_send_barconfig_update_event(Barconfig *barconfig) {
     y(free);
     setlocale(LC_NUMERIC, "");
 }
+
+/*
+ * For the binding events, we send the serialized binding struct.
+ */
+void ipc_send_binding_event(const char *event_type, Binding *bind) {
+    DLOG("Issue IPC binding %s event (sym = %s, code = %d)\n", event_type, bind->symbol, bind->keycode);
+
+    setlocale(LC_NUMERIC, "C");
+
+    yajl_gen gen = ygenalloc();
+
+    y(map_open);
+
+    ystr("change");
+    ystr(event_type);
+
+    ystr("binding");
+    dump_binding(gen, bind);
+
+    y(map_close);
+
+    const unsigned char *payload;
+    ylength length;
+    y(get_buf, &payload, &length);
+
+    ipc_send_event("binding", I3_IPC_EVENT_BINDING, (const char *)payload);
+
+    y(free);
+    setlocale(LC_NUMERIC, "");
+}