@@ -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