Support a special value "__focused__" as a command criterion pattern for class, instance, title, window_role and workspace.

This special value will match if the window's property equals that of the currently focused window.

relates to #1770
This commit is contained in:
Ingo Bürk 2015-08-28 08:26:27 +02:00
parent b68a400abf
commit 54d270e359
2 changed files with 48 additions and 17 deletions

View File

@ -1604,11 +1604,17 @@ for_window [class="^evil-app$"] floating enable, move container to workspace 4
The criteria which are currently implemented are: The criteria which are currently implemented are:
class:: class::
Compares the window class (the second part of WM_CLASS) Compares the window class (the second part of WM_CLASS). Use the
special value +__focused__+ to match all windows having the same window
class as the currently focused window.
instance:: instance::
Compares the window instance (the first part of WM_CLASS) Compares the window instance (the first part of WM_CLASS). Use the
special value +__focused__+ to match all windows having the same window
instance as the currently focused window.
window_role:: window_role::
Compares the window role (WM_WINDOW_ROLE). Compares the window role (WM_WINDOW_ROLE). Use the special value
+__focused__+ to match all windows having the same window role as the
currently focused window.
window_type:: window_type::
Compare the window type (_NET_WM_WINDOW_TYPE). Possible values are Compare the window type (_NET_WM_WINDOW_TYPE). Possible values are
+normal+, +dialog+, +utility+, +toolbar+, +splash+, +menu+, +dropdown_menu+, +normal+, +dialog+, +utility+, +toolbar+, +splash+, +menu+, +dropdown_menu+,
@ -1617,12 +1623,16 @@ id::
Compares the X11 window ID, which you can get via +xwininfo+ for example. Compares the X11 window ID, which you can get via +xwininfo+ for example.
title:: title::
Compares the X11 window title (_NET_WM_NAME or WM_NAME as fallback). Compares the X11 window title (_NET_WM_NAME or WM_NAME as fallback).
Use the special value +__focused__+ to match all windows having the
same window title as the currently focused window.
urgent:: urgent::
Compares the urgent state of the window. Can be "latest" or "oldest". Compares the urgent state of the window. Can be "latest" or "oldest".
Matches the latest or oldest urgent window, respectively. Matches the latest or oldest urgent window, respectively.
(The following aliases are also available: newest, last, recent, first) (The following aliases are also available: newest, last, recent, first)
workspace:: workspace::
Compares the workspace name of the workspace the window belongs to. Compares the workspace name of the workspace the window belongs to. Use
the special value +__focused__+ to match all windows in the currently
focused workspace.
con_mark:: con_mark::
Compares the mark set for this container, see <<vim_like_marks>>. Compares the mark set for this container, see <<vim_like_marks>>.
con_id:: con_id::

View File

@ -90,8 +90,12 @@ bool match_matches_window(Match *match, i3Window *window) {
LOG("Checking window 0x%08x (class %s)\n", window->id, window->class_class); LOG("Checking window 0x%08x (class %s)\n", window->id, window->class_class);
if (match->class != NULL) { if (match->class != NULL) {
if (window->class_class != NULL && if (window->class_class == NULL)
regex_matches(match->class, window->class_class)) { return false;
if (strcmp(match->class->pattern, "__focused__") == 0 &&
strcmp(window->class_class, focused->window->class_class) == 0) {
LOG("window class matches focused window\n");
} else if (regex_matches(match->class, window->class_class)) {
LOG("window class matches (%s)\n", window->class_class); LOG("window class matches (%s)\n", window->class_class);
} else { } else {
return false; return false;
@ -99,8 +103,12 @@ bool match_matches_window(Match *match, i3Window *window) {
} }
if (match->instance != NULL) { if (match->instance != NULL) {
if (window->class_instance != NULL && if (window->class_instance == NULL)
regex_matches(match->instance, window->class_instance)) { return false;
if (strcmp(match->instance->pattern, "__focused__") == 0 &&
strcmp(window->class_instance, focused->window->class_instance) == 0) {
LOG("window instance matches focused window\n");
} else if (regex_matches(match->instance, window->class_instance)) {
LOG("window instance matches (%s)\n", window->class_instance); LOG("window instance matches (%s)\n", window->class_instance);
} else { } else {
return false; return false;
@ -117,17 +125,27 @@ bool match_matches_window(Match *match, i3Window *window) {
} }
if (match->title != NULL) { if (match->title != NULL) {
if (window->name != NULL && if (window->name == NULL)
regex_matches(match->title, i3string_as_utf8(window->name))) { return false;
LOG("title matches (%s)\n", i3string_as_utf8(window->name));
const char *title = i3string_as_utf8(window->name);
if (strcmp(match->title->pattern, "__focused__") == 0 &&
strcmp(title, i3string_as_utf8(focused->window->name)) == 0) {
LOG("window title matches focused window\n");
} else if (regex_matches(match->title, title)) {
LOG("title matches (%s)\n", title);
} else { } else {
return false; return false;
} }
} }
if (match->window_role != NULL) { if (match->window_role != NULL) {
if (window->role != NULL && if (window->role == NULL)
regex_matches(match->window_role, window->role)) { return false;
if (strcmp(match->window_role->pattern, "__focused__") == 0 &&
strcmp(window->role, focused->window->role) == 0) {
LOG("window role matches focused window\n");
} else if (regex_matches(match->window_role, window->role)) {
LOG("window_role matches (%s)\n", window->role); LOG("window_role matches (%s)\n", window->role);
} else { } else {
return false; return false;
@ -182,7 +200,10 @@ bool match_matches_window(Match *match, i3Window *window) {
if (ws == NULL) if (ws == NULL)
return false; return false;
if (regex_matches(match->workspace, ws->name)) { if (strcmp(match->workspace->pattern, "__focused__") == 0 &&
strcmp(ws->name, con_get_workspace(focused)->name) == 0) {
LOG("workspace matches focused workspace\n");
} else if (regex_matches(match->workspace, ws->name)) {
LOG("workspace matches (%s)\n", ws->name); LOG("workspace matches (%s)\n", ws->name);
} else { } else {
return false; return false;