]> 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 6dab654c06c8c1e2653172ea1bfae40fcd874b50..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,6 +347,7 @@ 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);
 
@@ -342,7 +397,8 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
         ystr("transient_for");
         if (con->window->transient_for == XCB_NONE)
             y(null);
-        else y(integer, con->window->transient_for);
+        else
+            y(integer, con->window->transient_for);
 
         y(map_close);
     }
@@ -1065,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)
@@ -1089,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, "");
 }
 
 /**
@@ -1146,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, "");
+}