[i3] [PATCH 2/5] Added "focus" IPC message/event.

  • From: Kevin Murphy <kemurphy.cmu@xxxxxxxxx>
  • To: i3-discuss@xxxxxxxxxxxxx
  • Date: Sun, 18 Nov 2012 05:56:52 -0500

From: Kevin Murphy <kemurphy@xxxxxxxxxxxxxx>

The IPC message is used to query the window ID and title of the focused
window. The event is used to notify subscribers when the currently
focused window changes.
---
include/i3/ipc.h | 9 +++++++++
src/con.c | 1 +
src/handlers.c | 3 +++
src/ipc.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/include/i3/ipc.h b/include/i3/ipc.h
index 93b2ae8..04464f2 100644
--- a/include/i3/ipc.h
+++ b/include/i3/ipc.h
@@ -43,6 +43,9 @@
/** Request the i3 version */
#define I3_IPC_MESSAGE_TYPE_GET_VERSION 7

+/** Request the id and title of the focused window */
+#define I3_IPC_MESSAGE_TYPE_GET_FOCUS 8
+
/*
* Messages from i3 to clients
*
@@ -72,6 +75,9 @@
/** i3 version reply type */
#define I3_IPC_REPLY_TYPE_VERSION 7

+/** Focus reply type */
+#define I3_IPC_REPLY_TYPE_FOCUS 8
+
/*
* Events from i3 to clients. Events have the first bit set high.
*
@@ -87,4 +93,7 @@
/* The output event will be triggered upon mode changes */
#define I3_IPC_EVENT_MODE (I3_IPC_EVENT_MASK | 2)

+/* The output event will be triggered upon change of active window focus */
+#define I3_IPC_EVENT_FOCUS (I3_IPC_EVENT_MASK | 3)
+
#endif
diff --git a/src/con.c b/src/con.c
index 5b5dce9..9ad7716 100644
--- a/src/con.c
+++ b/src/con.c
@@ -210,6 +210,7 @@ void con_focus(Con *con) {
con_focus(con->parent);

focused = con;
+ ipc_send_event("focus", I3_IPC_EVENT_FOCUS, "{\"change\":\"window\"}");
/* We can't blindly reset non-leaf containers since they might have
* other urgent children. Therefore we only reset leafs and propagate
* the changes upwards via con_update_parents_urgency() which does proper
diff --git a/src/handlers.c b/src/handlers.c
index 7fa29e1..0fc396e 100644
--- a/src/handlers.c
+++ b/src/handlers.c
@@ -521,6 +521,9 @@ static bool handle_windowname_change(void *data,
xcb_connection_t *conn, uint8_t

window_update_name(con->window, prop, false);

+ if (con == focused)
+ ipc_send_event("focus", I3_IPC_EVENT_FOCUS, "{\"change\":\"title\"}");
+
x_push_changes(croot);

return true;
diff --git a/src/ipc.c b/src/ipc.c
index 17c15b9..ab45407 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -705,6 +705,48 @@ IPC_HANDLER(get_bar_config) {
}

/*
+ * Formats the reply message for a FOCUS request and sends it to the
+ * client
+ *
+ */
+IPC_HANDLER(focus) {
+#if YAJL_MAJOR >= 2
+ yajl_gen gen = yajl_gen_alloc(NULL);
+#else
+ yajl_gen gen = yajl_gen_alloc(NULL, NULL);
+#endif
+ y(map_open);
+
+ ystr("id");
+ if (focused->window != NULL) {
+ y(integer, focused->window->id);
+ } else {
+ y(integer, focused->frame);
+ }
+
+ ystr("title");
+ if (focused->window && focused->window->name)
+ ystr(i3string_as_utf8(focused->window->name));
+ else if (focused->type != CT_WORKSPACE && focused->name)
+ ystr(focused->name);
+ else
+ ystr("");
+
+ y(map_close);
+
+ const unsigned char *payload;
+#if YAJL_MAJOR >= 2
+ size_t length;
+#else
+ unsigned int length;
+#endif
+ y(get_buf, &payload, &length);
+
+ ipc_send_message(fd, length, I3_IPC_REPLY_TYPE_FOCUS, payload);
+ y(free);
+}
+
+/*
* Callback for the YAJL parser (will be called when a string is parsed).
*
*/
@@ -780,7 +822,7 @@ IPC_HANDLER(subscribe) {

/* The index of each callback function corresponds to the numeric
* value of the message type (see include/i3/ipc.h) */
-handler_t handlers[8] = {
+handler_t handlers[9] = {
handle_command,
handle_get_workspaces,
handle_subscribe,
@@ -789,6 +831,7 @@ handler_t handlers[8] = {
handle_get_marks,
handle_get_bar_config,
handle_get_version,
+ handle_focus,
};

/*
--
1.8.0


Other related posts:

  • » [i3] [PATCH 2/5] Added "focus" IPC message/event. - Kevin Murphy