Skip to content

Commit 188c91e

Browse files
committed
Add per-tab mode for web browsers
Allows to store keyboard layout for each tab separately. Currently only Firefox and Chromium are supported. Based on Dmitry Mikhin's implementation (PR #6). Co-developed-by: Dmitry Mikhin <dmikhin@webmonitorx.ru> Signed-off-by: Artem Senichev <artemsen@gmail.com>
1 parent 571bbed commit 188c91e

File tree

1 file changed

+35
-13
lines changed

1 file changed

+35
-13
lines changed

src/sway.c

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -213,23 +213,43 @@ static int ipc_change_layout(int sock, int layout)
213213
}
214214

215215
/**
216-
* Get window Id from event message.
216+
* Generate window Id from event message.
217217
* @param[in] msg event message
218218
* @return window Id
219219
*/
220-
static unsigned long container_id(struct json_object* msg)
220+
static unsigned long window_id(struct json_object* msg)
221221
{
222+
unsigned long wnd_id = INVALID_WINDOW;
223+
const char* app_id = NULL;
224+
const char* name = NULL;
222225
struct json_object* cnt_node;
226+
227+
// parse message
223228
if (json_object_object_get_ex(msg, "container", &cnt_node)) {
224-
struct json_object* id_node;
225-
if (json_object_object_get_ex(cnt_node, "id", &id_node)) {
226-
const int id = json_object_get_int(id_node);
227-
if (id != 0 || errno != EINVAL) {
228-
return id;
229-
}
229+
struct json_object* sub_node;
230+
if (json_object_object_get_ex(cnt_node, "id", &sub_node)) {
231+
wnd_id = json_object_get_int(sub_node);
232+
}
233+
if (json_object_object_get_ex(cnt_node, "app_id", &sub_node)) {
234+
app_id = json_object_get_string(sub_node);
235+
}
236+
if (json_object_object_get_ex(cnt_node, "name", &sub_node)) {
237+
name = json_object_get_string(sub_node);
230238
}
231239
}
232-
return INVALID_WINDOW;
240+
241+
// check if the current container belongs to the web browser, we will
242+
// use window title (which is a tab name) to generate unique id
243+
if (app_id && name &&
244+
(strcmp(app_id, "firefox") == 0 || strcmp(app_id, "chromium") == 0)) {
245+
// djb2 hash
246+
wnd_id = 5381;
247+
while (*name) {
248+
wnd_id = ((wnd_id << 5) + wnd_id) + *name++;
249+
}
250+
}
251+
252+
return wnd_id;
233253
}
234254

235255
/**
@@ -242,7 +262,8 @@ static int layout_index(struct json_object* msg)
242262
struct json_object* input_node;
243263
if (json_object_object_get_ex(msg, "input", &input_node)) {
244264
struct json_object* index_node;
245-
if (json_object_object_get_ex(input_node, "xkb_active_layout_index", &index_node)) {
265+
if (json_object_object_get_ex(input_node, "xkb_active_layout_index",
266+
&index_node)) {
246267
const int idx = json_object_get_int(index_node);
247268
if (idx != 0 || errno != EINVAL) {
248269
return idx;
@@ -275,14 +296,15 @@ int sway_monitor(on_focus fn_focus, on_close fn_close, on_layout fn_layout)
275296
struct json_object* event_node;
276297
if (json_object_object_get_ex(msg, "change", &event_node)) {
277298
const char* event_name = json_object_get_string(event_node);
278-
if (strcmp(event_name, "focus") == 0) {
279-
const unsigned long wid = container_id(msg);
299+
if (strcmp(event_name, "focus") == 0 ||
300+
strcmp(event_name, "title") == 0) {
301+
const unsigned long wid = window_id(msg);
280302
const int layout = fn_focus(wid);
281303
if (layout >= 0) {
282304
ipc_change_layout(sock, layout);
283305
}
284306
} else if (strcmp(event_name, "close") == 0) {
285-
fn_close(container_id(msg));
307+
fn_close(window_id(msg));
286308
} else if (strcmp(event_name, "xkb_layout") == 0) {
287309
fn_layout(layout_index(msg));
288310
}

0 commit comments

Comments
 (0)