summaryrefslogtreecommitdiffstats
path: root/source/dialogs/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/dialogs/window.c')
-rw-r--r--source/dialogs/window.c1580
1 files changed, 802 insertions, 778 deletions
diff --git a/source/dialogs/window.c b/source/dialogs/window.c
index 527fa43a..a132fcc7 100644
--- a/source/dialogs/window.c
+++ b/source/dialogs/window.c
@@ -26,118 +26,127 @@
*/
/** The log domain of this dialog. */
-#define G_LOG_DOMAIN "Dialogs.Window"
+#define G_LOG_DOMAIN "Dialogs.Window"
#include <config.h>
#ifdef WINDOW_MODE
-#include <stdlib.h>
-#include <stdio.h>
+#include <errno.h>
#include <stdint.h>
-#include <unistd.h>
-#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <errno.h>
+#include <strings.h>
+#include <unistd.h>
#include <xcb/xcb.h>
+#include <xcb/xcb_atom.h>
#include <xcb/xcb_ewmh.h>
#include <xcb/xcb_icccm.h>
-#include <xcb/xcb_atom.h>
#include <glib.h>
#include "xcb-internal.h"
#include "xcb.h"
+#include "dialogs/window.h"
+#include "helper.h"
#include "rofi.h"
#include "settings.h"
-#include "helper.h"
#include "widgets/textbox.h"
-#include "dialogs/window.h"
#include "timings.h"
-#include "rofi-icon-fetcher.h"
#include "mode-private.h"
+#include "rofi-icon-fetcher.h"
-#define WINLIST 32
+#define WINLIST 32
-#define CLIENTSTATE 10
-#define CLIENTWINDOWTYPE 10
+#define CLIENTSTATE 10
+#define CLIENTWINDOWTYPE 10
// Fields to match in window mode
-typedef struct
-{
- char *field_name;
- gboolean enabled;
+typedef struct {
+ char *field_name;
+ gboolean enabled;
} WinModeField;
-typedef enum
-{
- WIN_MATCH_FIELD_TITLE,
- WIN_MATCH_FIELD_CLASS,
- WIN_MATCH_FIELD_ROLE,
- WIN_MATCH_FIELD_NAME,
- WIN_MATCH_FIELD_DESKTOP,
- WIN_MATCH_NUM_FIELDS,
+typedef enum {
+ WIN_MATCH_FIELD_TITLE,
+ WIN_MATCH_FIELD_CLASS,
+ WIN_MATCH_FIELD_ROLE,
+ WIN_MATCH_FIELD_NAME,
+ WIN_MATCH_FIELD_DESKTOP,
+ WIN_MATCH_NUM_FIELDS,
} WinModeMatchingFields;
static WinModeField matching_window_fields[WIN_MATCH_NUM_FIELDS] = {
- { .field_name = "title", .enabled = TRUE, },
- { .field_name = "class", .enabled = TRUE, },
- { .field_name = "role", .enabled = TRUE, },
- { .field_name = "name", .enabled = TRUE, },
- { .field_name = "desktop", .enabled = TRUE, }
-};
-
-static gboolean window_matching_fields_parsed = FALSE;
+ {
+ .field_name = "title",
+ .enabled = TRUE,
+ },
+ {
+ .field_name = "class",
+ .enabled = TRUE,
+ },
+ {
+ .field_name = "role",
+ .enabled = TRUE,
+ },
+ {
+ .field_name = "name",
+ .enabled = TRUE,
+ },
+ {
+ .field_name = "desktop",
+ .enabled = TRUE,
+ }};
+
+static gboolean window_matching_fields_parsed = FALSE;
// a manageable window
-typedef struct
-{
- xcb_window_t window;
- xcb_get_window_attributes_reply_t xattr;
- char *title;
- char *class;
- char *name;
- char *role;
- int states;
- xcb_atom_t state[CLIENTSTATE];
- int window_types;
- xcb_atom_t window_type[CLIENTWINDOWTYPE];
- int active;
- int demands;
- long hint_flags;
- uint32_t wmdesktop;
- char *wmdesktopstr;
- unsigned int wmdesktopstr_len;
- cairo_surface_t *icon;
- gboolean icon_checked;
- uint32_t icon_fetch_uid;
- gboolean thumbnail_checked;
+typedef struct {
+ xcb_window_t window;
+ xcb_get_window_attributes_reply_t xattr;
+ char *title;
+ char *class;
+ char *name;
+ char *role;
+ int states;
+ xcb_atom_t state[CLIENTSTATE];
+ int window_types;
+ xcb_atom_t window_type[CLIENTWINDOWTYPE];
+ int active;
+ int demands;
+ long hint_flags;
+ uint32_t wmdesktop;
+ char *wmdesktopstr;
+ unsigned int wmdesktopstr_len;
+ cairo_surface_t *icon;
+ gboolean icon_checked;
+ uint32_t icon_fetch_uid;
+ gboolean thumbnail_checked;
} client;
// window lists
-typedef struct
-{
- xcb_window_t *array;
- client **data;
- int len;
+typedef struct {
+ xcb_window_t *array;
+ client **data;
+ int len;
} winlist;
-typedef struct
-{
- unsigned int id;
- winlist *ids;
- // Current window.
- unsigned int index;
- char *cache;
- unsigned int wmdn_len;
- unsigned int clf_len;
- unsigned int name_len;
- unsigned int title_len;
- unsigned int role_len;
- GRegex *window_regex;
+typedef struct {
+ unsigned int id;
+ winlist *ids;
+ // Current window.
+ unsigned int index;
+ char *cache;
+ unsigned int wmdn_len;
+ unsigned int clf_len;
+ unsigned int name_len;
+ unsigned int title_len;
+ unsigned int role_len;
+ GRegex *window_regex;
} ModeModePrivateData;
winlist *cache_client = NULL;
@@ -147,13 +156,12 @@ winlist *cache_client = NULL;
*
* @returns A new window list.
*/
-static winlist* winlist_new ()
-{
- winlist *l = g_malloc ( sizeof ( winlist ) );
- l->len = 0;
- l->array = g_malloc_n ( WINLIST + 1, sizeof ( xcb_window_t ) );
- l->data = g_malloc_n ( WINLIST + 1, sizeof ( client* ) );
- return l;
+static winlist *winlist_new() {
+ winlist *l = g_malloc(sizeof(winlist));
+ l->len = 0;
+ l->array = g_malloc_n(WINLIST + 1, sizeof(xcb_window_t));
+ l->data = g_malloc_n(WINLIST + 1, sizeof(client *));
+ return l;
}
/**
@@ -165,46 +173,44 @@ static winlist* winlist_new ()
*
* @returns 0 if failed, 1 is successful.
*/
-static int winlist_append ( winlist *l, xcb_window_t w, client *d )
-{
- if ( l->len > 0 && !( l->len % WINLIST ) ) {
- l->array = g_realloc ( l->array, sizeof ( xcb_window_t ) * ( l->len + WINLIST + 1 ) );
- l->data = g_realloc ( l->data, sizeof ( client* ) * ( l->len + WINLIST + 1 ) );
- }
- // Make clang-check happy.
- // TODO: make clang-check clear this should never be 0.
- if ( l->data == NULL || l->array == NULL ) {
- return 0;
- }
+static int winlist_append(winlist *l, xcb_window_t w, client *d) {
+ if (l->len > 0 && !(l->len % WINLIST)) {
+ l->array =
+ g_realloc(l->array, sizeof(xcb_window_t) * (l->len + WINLIST + 1));
+ l->data = g_realloc(l->data, sizeof(client *) * (l->len + WINLIST + 1));
+ }
+ // Make clang-check happy.
+ // TODO: make clang-check clear this should never be 0.
+ if (l->data == NULL || l->array == NULL) {
+ return 0;
+ }
- l->data[l->len] = d;
- l->array[l->len++] = w;
- return l->len - 1;
+ l->data[l->len] = d;
+ l->array[l->len++] = w;
+ return l->len - 1;
}
-static void client_free ( client *c )
-{
- if ( c == NULL ) {
+static void client_free(client *c) {
+ if (c == NULL) {
return;
}
- if ( c->icon ) {
- cairo_surface_destroy ( c->icon );
+ if (c->icon) {
+ cairo_surface_destroy(c->icon);
}
- g_free ( c->title );
- g_free ( c->class );
- g_free ( c->name );
- g_free ( c->role );
- g_free ( c->wmdesktopstr );
+ g_free(c->title);
+ g_free(c->class);
+ g_free(c->name);
+ g_free(c->role);
+ g_free(c->wmdesktopstr);
}
-static void winlist_empty ( winlist *l )
-{
- while ( l->len > 0 ) {
- client *c = l->data[--l->len];
- if ( c != NULL ) {
- client_free ( c );
- g_free ( c );
- }
+static void winlist_empty(winlist *l) {
+ while (l->len > 0) {
+ client *c = l->data[--l->len];
+ if (c != NULL) {
+ client_free(c);
+ g_free(c);
}
+ }
}
/**
@@ -212,14 +218,13 @@ static void winlist_empty ( winlist *l )
*
* Free the winlist.
*/
-static void winlist_free ( winlist *l )
-{
- if ( l != NULL ) {
- winlist_empty ( l );
- g_free ( l->array );
- g_free ( l->data );
- g_free ( l );
- }
+static void winlist_free(winlist *l) {
+ if (l != NULL) {
+ winlist_empty(l);
+ g_free(l->array);
+ g_free(l->data);
+ g_free(l);
+ }
}
/**
@@ -230,37 +235,34 @@ static void winlist_free ( winlist *l )
*
* @returns -1 if failed, index is successful.
*/
-static int winlist_find ( winlist *l, xcb_window_t w )
-{
-// iterate backwards. Theory is: windows most often accessed will be
-// nearer the end. Testing with kcachegrind seems to support this...
- int i;
-
- for ( i = ( l->len - 1 ); i >= 0; i-- ) {
- if ( l->array[i] == w ) {
- return i;
- }
+static int winlist_find(winlist *l, xcb_window_t w) {
+ // iterate backwards. Theory is: windows most often accessed will be
+ // nearer the end. Testing with kcachegrind seems to support this...
+ int i;
+
+ for (i = (l->len - 1); i >= 0; i--) {
+ if (l->array[i] == w) {
+ return i;
}
+ }
- return -1;
+ return -1;
}
/**
* Create empty X11 cache for windows and windows attributes.
*/
-static void x11_cache_create ( void )
-{
- if ( cache_client == NULL ) {
- cache_client = winlist_new ();
- }
+static void x11_cache_create(void) {
+ if (cache_client == NULL) {
+ cache_client = winlist_new();
+ }
}
/**
* Free the cache.
*/
-static void x11_cache_free ( void )
-{
- winlist_free ( cache_client );
- cache_client = NULL;
+static void x11_cache_free(void) {
+ winlist_free(cache_client);
+ cache_client = NULL;
}
/**
@@ -272,591 +274,618 @@ static void x11_cache_free ( void )
*
* @returns a XWindowAttributes
*/
-static xcb_get_window_attributes_reply_t * window_get_attributes ( xcb_window_t w )
-{
- xcb_get_window_attributes_cookie_t c = xcb_get_window_attributes ( xcb->connection, w );
- xcb_get_window_attributes_reply_t *r = xcb_get_window_attributes_reply ( xcb->connection, c, NULL );
- if ( r ) {
- return r;
- }
- return NULL;
+static xcb_get_window_attributes_reply_t *
+window_get_attributes(xcb_window_t w) {
+ xcb_get_window_attributes_cookie_t c =
+ xcb_get_window_attributes(xcb->connection, w);
+ xcb_get_window_attributes_reply_t *r =
+ xcb_get_window_attributes_reply(xcb->connection, c, NULL);
+ if (r) {
+ return r;
+ }
+ return NULL;
}
// _NET_WM_STATE_*
-static int client_has_state ( client *c, xcb_atom_t state )
-{
- for ( int i = 0; i < c->states; i++ ) {
- if ( c->state[i] == state ) {
- return 1;
- }
+static int client_has_state(client *c, xcb_atom_t state) {
+ for (int i = 0; i < c->states; i++) {
+ if (c->state[i] == state) {
+ return 1;
}
+ }
- return 0;
+ return 0;
}
-static int client_has_window_type ( client *c, xcb_atom_t type )
-{
- for ( int i = 0; i < c->window_types; i++ ) {
- if ( c->window_type[i] == type ) {
- return 1;
- }
+static int client_has_window_type(client *c, xcb_atom_t type) {
+ for (int i = 0; i < c->window_types; i++) {
+ if (c->window_type[i] == type) {
+ return 1;
}
+ }
- return 0;
+ return 0;
}
-static client* window_client ( ModeModePrivateData *pd, xcb_window_t win )
-{
- if ( win == XCB_WINDOW_NONE ) {
- return NULL;
- }
+static client *window_client(ModeModePrivateData *pd, xcb_window_t win) {
+ if (win == XCB_WINDOW_NONE) {
+ return NULL;
+ }
- int idx = winlist_find ( cache_client, win );
+ int idx = winlist_find(cache_client, win);
- if ( idx >= 0 ) {
- return cache_client->data[idx];
- }
+ if (idx >= 0) {
+ return cache_client->data[idx];
+ }
- // if this fails, we're up that creek
- xcb_get_window_attributes_reply_t *attr = window_get_attributes ( win );
+ // if this fails, we're up that creek
+ xcb_get_window_attributes_reply_t *attr = window_get_attributes(win);
- if ( !attr ) {
- return NULL;
- }
- client *c = g_malloc0 ( sizeof ( client ) );
- c->window = win;
-
- // copy xattr so we don't have to care when stuff is freed
- memmove ( &c->xattr, attr, sizeof ( xcb_get_window_attributes_reply_t ) );
-
- xcb_get_property_cookie_t cky = xcb_ewmh_get_wm_state ( &xcb->ewmh, win );
- xcb_ewmh_get_atoms_reply_t states;
- if ( xcb_ewmh_get_wm_state_reply ( &xcb->ewmh, cky, &states, NULL ) ) {
- c->states = MIN ( CLIENTSTATE, states.atoms_len );
- memcpy ( c->state, states.atoms, MIN ( CLIENTSTATE, states.atoms_len ) * sizeof ( xcb_atom_t ) );
- xcb_ewmh_get_atoms_reply_wipe ( &states );
- }
- cky = xcb_ewmh_get_wm_window_type ( &xcb->ewmh, win );
- if ( xcb_ewmh_get_wm_window_type_reply ( &xcb->ewmh, cky, &states, NULL ) ) {
- c->window_types = MIN ( CLIENTWINDOWTYPE, states.atoms_len );
- memcpy ( c->window_type, states.atoms, MIN ( CLIENTWINDOWTYPE, states.atoms_len ) * sizeof ( xcb_atom_t ) );
- xcb_ewmh_get_atoms_reply_wipe ( &states );
- }
+ if (!attr) {
+ return NULL;
+ }
+ client *c = g_malloc0(sizeof(client));
+ c->window = win;
+
+ // copy xattr so we don't have to care when stuff is freed
+ memmove(&c->xattr, attr, sizeof(xcb_get_window_attributes_reply_t));
+
+ xcb_get_property_cookie_t cky = xcb_ewmh_get_wm_state(&xcb->ewmh, win);
+ xcb_ewmh_get_atoms_reply_t states;
+ if (xcb_ewmh_get_wm_state_reply(&xcb->ewmh, cky, &states, NULL)) {
+ c->states = MIN(CLIENTSTATE, states.atoms_len);
+ memcpy(c->state, states.atoms,
+ MIN(CLIENTSTATE, states.atoms_len) * sizeof(xcb_atom_t));
+ xcb_ewmh_get_atoms_reply_wipe(&states);
+ }
+ cky = xcb_ewmh_get_wm_window_type(&xcb->ewmh, win);
+ if (xcb_ewmh_get_wm_window_type_reply(&xcb->ewmh, cky, &states, NULL)) {
+ c->window_types = MIN(CLIENTWINDOWTYPE, states.atoms_len);
+ memcpy(c->window_type, states.atoms,
+ MIN(CLIENTWINDOWTYPE, states.atoms_len) * sizeof(xcb_atom_t));
+ xcb_ewmh_get_atoms_reply_wipe(&states);
+ }
- char *tmp_title = window_get_text_prop ( c->window, xcb->ewmh._NET_WM_NAME );
- if ( tmp_title == NULL ) {
- tmp_title = window_get_text_prop ( c->window, XCB_ATOM_WM_NAME );
- }
- c->title = g_markup_escape_text ( tmp_title, -1 );
- pd->title_len = MAX ( c->title ? g_utf8_strlen ( c->title, -1 ) : 0, pd->title_len );
- g_free ( tmp_title );
-
- char *tmp_role = window_get_text_prop ( c->window, netatoms[WM_WINDOW_ROLE] );
- c->role = g_markup_escape_text ( tmp_role ? tmp_role : "", -1 );
- pd->role_len = MAX ( c->role ? g_utf8_strlen ( c->role, -1 ) : 0, pd->role_len );
- g_free ( tmp_role );
-
- cky = xcb_icccm_get_wm_class ( xcb->connection, c->window );
- xcb_icccm_get_wm_class_reply_t wcr;
- if ( xcb_icccm_get_wm_class_reply ( xcb->connection, cky, &wcr, NULL ) ) {
- c->class = g_markup_escape_text ( wcr.class_name, -1 );
- c->name = g_markup_escape_text ( wcr.instance_name, -1 );
- pd->name_len = MAX ( c->name ? g_utf8_strlen ( c->name, -1 ) : 0, pd->name_len );
- xcb_icccm_get_wm_class_reply_wipe ( &wcr );
- }
+ char *tmp_title = window_get_text_prop(c->window, xcb->ewmh._NET_WM_NAME);
+ if (tmp_title == NULL) {
+ tmp_title = window_get_text_prop(c->window, XCB_ATOM_WM_NAME);
+ }
+ c->title = g_markup_escape_text(tmp_title, -1);
+ pd->title_len =
+ MAX(c->title ? g_utf8_strlen(c->title, -1) : 0, pd->title_len);
+ g_free(tmp_title);
+
+ char *tmp_role = window_get_text_prop(c->window, netatoms[WM_WINDOW_ROLE]);
+ c->role = g_markup_escape_text(tmp_role ? tmp_role : "", -1);
+ pd->role_len = MAX(c->role ? g_utf8_strlen(c->role, -1) : 0, pd->role_len);
+ g_free(tmp_role);
+
+ cky = xcb_icccm_get_wm_class(xcb->connection, c->window);
+ xcb_icccm_get_wm_class_reply_t wcr;
+ if (xcb_icccm_get_wm_class_reply(xcb->connection, cky, &wcr, NULL)) {
+ c->class = g_markup_escape_text(wcr.class_name, -1);
+ c->name = g_markup_escape_text(wcr.instance_name, -1);
+ pd->name_len = MAX(c->name ? g_utf8_strlen(c->name, -1) : 0, pd->name_len);
+ xcb_icccm_get_wm_class_reply_wipe(&wcr);
+ }
- xcb_get_property_cookie_t cc = xcb_icccm_get_wm_hints ( xcb->connection, c->window );
- xcb_icccm_wm_hints_t r;
- if ( xcb_icccm_get_wm_hints_reply ( xcb->connection, cc, &r, NULL ) ) {
- c->hint_flags = r.flags;
- }
+ xcb_get_property_cookie_t cc =
+ xcb_icccm_get_wm_hints(xcb->connection, c->window);
+ xcb_icccm_wm_hints_t r;
+ if (xcb_icccm_get_wm_hints_reply(xcb->connection, cc, &r, NULL)) {
+ c->hint_flags = r.flags;
+ }
- winlist_append ( cache_client, c->window, c );
- g_free ( attr );
- return c;
+ winlist_append(cache_client, c->window, c);
+ g_free(attr);
+ return c;
}
-static int window_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index )
-{
- ModeModePrivateData *rmpd = (ModeModePrivateData *) mode_get_private_data ( sw );
- int match = 1;
- const winlist *ids = ( winlist * ) rmpd->ids;
- // Want to pull directly out of cache, X calls are not thread safe.
- int idx = winlist_find ( cache_client, ids->array[index] );
- g_assert ( idx >= 0 );
- client *c = cache_client->data[idx];
-
- if ( tokens ) {
- for ( int j = 0; match && tokens != NULL && tokens[j] != NULL; j++ ) {
- int test = 0;
- // Dirty hack. Normally helper_token_match does _all_ the matching,
- // Now we want it to match only one item at the time.
- // If hack not in place it would not match queries spanning multiple fields.
- // e.g. when searching 'title element' and 'class element'
- rofi_int_matcher *ftokens[2] = { tokens[j], NULL };
- if ( c->title != NULL && c->title[0] != '\0' && matching_window_fields[WIN_MATCH_FIELD_TITLE].enabled ) {
- test = helper_token_match ( ftokens, c->title );
- }
-
- if ( test == tokens[j]->invert && c->class != NULL && c->class[0] != '\0' && matching_window_fields[WIN_MATCH_FIELD_CLASS].enabled ) {
- test = helper_token_match ( ftokens, c->class );
- }
-
- if ( test == tokens[j]->invert && c->role != NULL && c->role[0] != '\0' && matching_window_fields[WIN_MATCH_FIELD_ROLE].enabled ) {
- test = helper_token_match ( ftokens, c->role );
- }
-
- if ( test == tokens[j]->invert && c->name != NULL && c->name[0] != '\0' && matching_window_fields[WIN_MATCH_FIELD_NAME].enabled ) {
- test = helper_token_match ( ftokens, c->name );
- }
- if ( test == tokens[j]->invert && c->wmdesktopstr != NULL && c->wmdesktopstr[0] != '\0' && matching_window_fields[WIN_MATCH_FIELD_DESKTOP].enabled ) {
- test = helper_token_match ( ftokens, c->wmdesktopstr );
- }
-
- if ( test == 0 ) {
- match = 0;
- }
- }
+static int window_match(const Mode *sw, rofi_int_matcher **tokens,
+ unsigned int index) {
+ ModeModePrivateData *rmpd = (ModeModePrivateData *)mode_get_private_data(sw);
+ int match = 1;
+ const winlist *ids = (winlist *)rmpd->ids;
+ // Want to pull directly out of cache, X calls are not thread safe.
+ int idx = winlist_find(cache_client, ids->array[index]);
+ g_assert(idx >= 0);
+ client *c = cache_client->data[idx];
+
+ if (tokens) {
+ for (int j = 0; match && tokens != NULL && tokens[j] != NULL; j++) {
+ int test = 0;
+ // Dirty hack. Normally helper_token_match does _all_ the matching,
+ // Now we want it to match only one item at the time.
+ // If hack not in place it would not match queries spanning multiple
+ // fields. e.g. when searching 'title element' and 'class element'
+ rofi_int_matcher *ftokens[2] = {tokens[j], NULL};
+ if (c->title != NULL && c->title[0] != '\0' &&
+ matching_window_fields[WIN_MATCH_FIELD_TITLE].enabled) {
+ test = helper_token_match(ftokens, c->title);
+ }
+
+ if (test == tokens[j]->invert && c->class != NULL &&
+ c->class[0] != '\0' &&
+ matching_window_fields[WIN_MATCH_FIELD_CLASS].enabled) {
+ test = helper_token_match(ftokens, c->class);
+ }
+
+ if (test == tokens[j]->invert && c->role != NULL && c->role[0] != '\0' &&
+ matching_window_fields[WIN_MATCH_FIELD_ROLE].enabled) {
+ test = helper_token_match(ftokens, c->role);
+ }
+
+ if (test == tokens[j]->invert && c->name != NULL && c->name[0] != '\0' &&
+ matching_window_fields[WIN_MATCH_FIELD_NAME].enabled) {
+ test = helper_token_match(ftokens, c->name);
+ }
+ if (test == tokens[j]->invert && c->wmdesktopstr != NULL &&
+ c->wmdesktopstr[0] != '\0' &&
+ matching_window_fields[WIN_MATCH_FIELD_DESKTOP].enabled) {
+ test = helper_token_match(ftokens, c->wmdesktopstr);
+ }
+
+ if (test == 0) {
+ match = 0;
+ }
}
+ }
- return match;
+ return match;
}
-static void window_mode_parse_fields ()
-{
- window_matching_fields_parsed = TRUE;
- char *savept = NULL;
- // Make a copy, as strtok will modify it.
- char *switcher_str = g_strdup ( config.window_match_fields );
- const char * const sep = ",#";
- // Split token on ','. This modifies switcher_str.
- for ( unsigned int i = 0; i < WIN_MATCH_NUM_FIELDS; i++ ) {
- matching_window_fields[i].enabled = FALSE;
+static void window_mode_parse_fields() {
+ window_matching_fields_parsed = TRUE;
+ char *savept = NULL;
+ // Make a copy, as strtok will modify it.
+ char *switcher_str = g_strdup(config.window_match_fields);
+ const char *const sep = ",#";
+ // Split token on ','. This modifies switcher_str.
+ for (unsigned int i = 0; i < WIN_MATCH_NUM_FIELDS; i++) {
+ matching_window_fields[i].enabled = FALSE;
+ }
+ for (char *token = strtok_r(switcher_str, sep, &savept); token != NULL;
+ token = strtok_r(NULL, sep, &savept)) {
+ if (strcmp(token, "all") == 0) {
+ for (unsigned int i = 0; i < WIN_MATCH_NUM_FIELDS; i++) {
+ matching_window_fields[i].enabled = TRUE;
+ }
+ break;
}
- for ( char *token = strtok_r ( switcher_str, sep, &savept ); token != NULL;
- token = strtok_r ( NULL, sep, &savept ) ) {
- if ( strcmp ( token, "all" ) == 0 ) {
- for ( unsigned int i = 0; i < WIN_MATCH_NUM_FIELDS; i++ ) {
- matching_window_fields[i].enabled = TRUE;
- }
- break;
- }
- else {
- gboolean matched = FALSE;
- for ( unsigned int i = 0; i < WIN_MATCH_NUM_FIELDS; i++ ) {
- const char * field_name = matching_window_fields[i].field_name;
- if ( strcmp ( token, field_name ) == 0 ) {
- matching_window_fields[i].enabled = TRUE;
- matched = TRUE;
- }
- }
- if ( !matched ) {
- g_warning ( "Invalid window field name :%s", token );
- }
- }
+ gboolean matched = FALSE;
+ for (unsigned int i = 0; i < WIN_MATCH_NUM_FIELDS; i++) {
+ const char *field_name = matching_window_fields[i].field_name;
+ if (strcmp(token, field_name) == 0) {
+ matching_window_fields[i].enabled = TRUE;
+ matched = TRUE;
+ }
}
- // Free string that was modified by strtok_r
- g_free ( switcher_str );
+ if (!matched) {
+ g_warning("Invalid window field name :%s", token);
+ }
+ }
+ // Free string that was modified by strtok_r
+ g_free(switcher_str);
}
-static unsigned int window_mode_get_num_entries ( const Mode *sw )
-{
- const ModeModePrivateData *pd = (const ModeModePrivateData *) mode_get_private_data ( sw );
+static unsigned int window_mode_get_num_entries(const Mode *sw) {
+ const ModeModePrivateData *pd =
+ (const ModeModePrivateData *)mode_get_private_data(sw);
- return pd->ids ? pd->ids->len : 0;
+ return pd->ids ? pd->ids->len : 0;
}
/**
* Small helper function to find the right entry in the ewmh reply.
* Is there a call for this?
*/
const char *invalid_desktop_name = "n/a";
-static const char * _window_name_list_entry ( const char *str, uint32_t length, int entry )
-{
- uint32_t offset = 0;
- int index = 0;
- while ( index < entry && offset < length ) {
- if ( str[offset] == 0 ) {
- index++;
- }
- offset++;
+static const char *_window_name_list_entry(const char *str, uint32_t length,
+ int entry) {
+ uint32_t offset = 0;
+ int index = 0;
+ while (index < entry && offset < length) {
+ if (str[offset] == 0) {
+ index++;
}
- if ( offset >= length ) {
- return invalid_desktop_name;
- }
- return &str[offset];
+ offset++;
+ }
+ if (offset >= length) {
+ return invalid_desktop_name;
+ }
+ return &str[offset];
}
-static void _window_mode_load_data ( Mode *sw, unsigned int cd )
-{
- ModeModePrivateData *pd = (ModeModePrivateData *) mode_get_private_data ( sw );
- // find window list
- xcb_window_t curr_win_id;
- int found = 0;
-
- // Create cache
-
- x11_cache_create ();
- xcb_get_property_cookie_t c = xcb_ewmh_get_active_window ( &( xcb->ewmh ), xcb->screen_nbr );
- if ( !xcb_ewmh_get_active_window_reply ( &xcb->ewmh, c, &curr_win_id, NULL ) ) {
- curr_win_id = 0;
- }
+static void _window_mode_load_data(Mode *sw, unsigned int cd) {
+ ModeModePrivateData *pd = (ModeModePrivateData *)mode_get_private_data(sw);
+ // find window list
+ xcb_window_t curr_win_id;
+ int found = 0;
+
+ // Create cache
+
+ x11_cache_create();
+ xcb_get_property_cookie_t c =
+ xcb_ewmh_get_active_window(&(xcb->ewmh), xcb->screen_nbr);
+ if (!xcb_ewmh_get_active_window_reply(&xcb->ewmh, c, &curr_win_id, NULL)) {
+ curr_win_id = 0;
+ }
- // Get the current desktop.
- unsigned int current_desktop = 0;
- c = xcb_ewmh_get_current_desktop ( &xcb->ewmh, xcb->screen_nbr );
- if ( !xcb_ewmh_get_current_desktop_reply ( &xcb->ewmh, c, &current_desktop, NULL ) ) {
- current_desktop = 0;
+ // Get the current desktop.
+ unsigned int current_desktop = 0;
+ c = xcb_ewmh_get_current_desktop(&xcb->ewmh, xcb->screen_nbr);
+ if (!xcb_ewmh_get_current_desktop_reply(&xcb->ewmh, c, &current_desktop,
+ NULL)) {
+ current_desktop = 0;
+ }
+
+ g_debug("Get list from: %d", xcb->screen_nbr);
+ c = xcb_ewmh_get_client_list_stacking(&xcb->ewmh, xcb->screen_nbr);
+ xcb_ewmh_get_windows_reply_t clients = {
+ 0,
+ };
+ if (xcb_ewmh_get_client_list_stacking_reply(&xcb->ewmh, c, &clients, NULL)) {
+ found = 1;
+ } else {
+ c = xcb_ewmh_get_client_list(&xcb->ewmh, xcb->screen_nbr);
+ if (xcb_ewmh_get_client_list_reply(&xcb->ewmh, c, &clients, NULL)) {
+ found = 1;
}
+ }
+ if (!found) {
+ return;
+ }
- g_debug ( "Get list from: %d", xcb->screen_nbr );
- c = xcb_ewmh_get_client_list_stacking ( &xcb->ewmh, xcb->screen_nbr );
- xcb_ewmh_get_windows_reply_t clients = { 0, };
- if ( xcb_ewmh_get_client_list_stacking_reply ( &xcb->ewmh, c, &clients, NULL ) ) {
- found = 1;
+ if (clients.windows_len > 0) {
+ int i;
+ // windows we actually display. May be slightly different to
+ // _NET_CLIENT_LIST_STACKING if we happen to have a window destroyed while
+ // we're working...
+ pd->ids = winlist_new();
+
+ xcb_get_property_cookie_t c =
+ xcb_ewmh_get_desktop_names(&xcb->ewmh, xcb->screen_nbr);
+ xcb_ewmh_get_utf8_strings_reply_t names;
+ int has_names = FALSE;
+ if (xcb_ewmh_get_desktop_names_reply(&xcb->ewmh, c, &names, NULL)) {
+ has_names = TRUE;
}
- else {
- c = xcb_ewmh_get_client_list ( &xcb->ewmh, xcb->screen_nbr );
- if ( xcb_ewmh_get_client_list_reply ( &xcb->ewmh, c, &clients, NULL ) ) {
- found = 1;
+ // calc widths of fields
+ for (i = clients.windows_len - 1; i > -1; i--) {
+ client *c = window_client(pd, clients.windows[i]);
+ if ((c != NULL) && !c->xattr.override_redirect &&
+ !client_has_window_type(c, xcb->ewmh._NET_WM_WINDOW_TYPE_DOCK) &&
+ !client_has_window_type(c, xcb->ewmh._NET_WM_WINDOW_TYPE_DESKTOP) &&
+ !client_has_state(c, xcb->ewmh._NET_WM_STATE_SKIP_PAGER) &&
+ !client_has_state(c, xcb->ewmh._NET_WM_STATE_SKIP_TASKBAR)) {
+ pd->clf_len =
+ MAX(pd->clf_len,
+ (c->class != NULL) ? (g_utf8_strlen(c->class, -1)) : 0);
+
+ if (client_has_state(c, xcb->ewmh._NET_WM_STATE_DEMANDS_ATTENTION)) {
+ c->demands = TRUE;
+ }
+ if ((c->hint_flags & XCB_ICCCM_WM_HINT_X_URGENCY) != 0) {
+ c->demands = TRUE;
}
- }
- if ( !found ) {
- return;
- }
- if ( clients.windows_len > 0 ) {
- int i;
- // windows we actually display. May be slightly different to _NET_CLIENT_LIST_STACKING
- // if we happen to have a window destroyed while we're working...
- pd->ids = winlist_new ();
-
- xcb_get_property_cookie_t c = xcb_ewmh_get_desktop_names ( &xcb->ewmh, xcb->screen_nbr );
- xcb_ewmh_get_utf8_strings_reply_t names;
- int has_names = FALSE;
- if ( xcb_ewmh_get_desktop_names_reply ( &xcb->ewmh, c, &names, NULL ) ) {
- has_names = TRUE;
+ if (c->window == curr_win_id) {
+ c->active = TRUE;
+ }
+ // find client's desktop.
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *r;
+
+ c->wmdesktop = 0xFFFFFFFF;
+ cookie = xcb_get_property(xcb->connection, 0, c->window,
+ xcb->ewmh._NET_WM_DESKTOP, XCB_ATOM_CARDINAL,
+ 0, 1);
+ r = xcb_get_property_reply(xcb->connection, cookie, NULL);
+ if (r) {
+ if (r->type == XCB_ATOM_CARDINAL) {
+ c->wmdesktop = *((uint32_t *)xcb_get_property_value(r));
+ }
+ free(r);
}
- // calc widths of fields
- for ( i = clients.windows_len - 1; i > -1; i-- ) {
- client *c = window_client ( pd, clients.windows[i] );
- if ( ( c != NULL )
- && !c->xattr.override_redirect
- && !client_has_window_type ( c, xcb->ewmh._NET_WM_WINDOW_TYPE_DOCK )
- && !client_has_window_type ( c, xcb->ewmh._NET_WM_WINDOW_TYPE_DESKTOP )
- && !client_has_state ( c, xcb->ewmh._NET_WM_STATE_SKIP_PAGER )
- && !client_has_state ( c, xcb->ewmh._NET_WM_STATE_SKIP_TASKBAR ) ) {
- pd->clf_len = MAX ( pd->clf_len, ( c->class != NULL ) ? ( g_utf8_strlen ( c->class, -1 ) ) : 0 );
-
- if ( client_has_state ( c, xcb->ewmh._NET_WM_STATE_DEMANDS_ATTENTION ) ) {
- c->demands = TRUE;
- }
- if ( ( c->hint_flags & XCB_ICCCM_WM_HINT_X_URGENCY ) != 0 ) {
- c->demands = TRUE;
- }
-
- if ( c->window == curr_win_id ) {
- c->active = TRUE;
- }
- // find client's desktop.
- xcb_get_property_cookie_t cookie;
- xcb_get_property_reply_t *r;
-
- c->wmdesktop = 0xFFFFFFFF;
- cookie =
- xcb_get_property ( xcb->connection, 0, c->window, xcb->ewmh._NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 0,
- 1 );
- r = xcb_get_property_reply ( xcb->connection, cookie, NULL );
- if ( r ) {
- if ( r->type == XCB_ATOM_CARDINAL ) {
- c->wmdesktop = *( (uint32_t *) xcb_get_property_value ( r ) );
- }
- free ( r );
- }
- if ( c->wmdesktop != 0xFFFFFFFF ) {
- if ( has_names ) {
- if ( ( current_window_manager & WM_PANGO_WORKSPACE_NAMES ) == WM_PANGO_WORKSPACE_NAMES ) {
- char *output = NULL;
- if ( pango_parse_markup ( _window_name_list_entry ( names.strings, names.strings_len,
- c->wmdesktop ), -1, 0, NULL, &output, NULL, NULL ) ) {
- c->wmdesktopstr = g_strdup ( _window_name_list_entry ( names.strings, names.strings_len, c->wmdesktop ) );
- c->wmdesktopstr_len = g_utf8_strlen ( output, -1 );
- pd->wmdn_len = MAX ( pd->wmdn_len, c->wmdesktopstr_len );
- g_free ( output );
- }
- else {
- c->wmdesktopstr = g_strdup ( "Invalid name" );
- pd->wmdn_len = MAX ( pd->wmdn_len, g_utf8_strlen ( c->wmdesktopstr, -1 ) );
- }
- }
- else {
- c->wmdesktopstr = g_markup_escape_text ( _window_name_list_entry ( names.strings, names.strings_len, c->wmdesktop ), -1 );
- pd->wmdn_len = MAX ( pd->wmdn_len, g_utf8_strlen ( c->wmdesktopstr, -1 ) );
- }
- }
- else {
- c->wmdesktopstr = g_strdup_printf ( "%u", (uint32_t) c->wmdesktop );
- pd->wmdn_len = MAX ( pd->wmdn_len, g_utf8_strlen ( c->wmdesktopstr, -1 ) );
- }
- }
- else {
- c->wmdesktopstr = g_strdup ( "" );
- pd->wmdn_len = MAX ( pd->wmdn_len, g_utf8_strlen ( c->wmdesktopstr, -1 ) );
- }
- if ( cd && c->wmdesktop != current_desktop ) {
- continue;
- }
- winlist_append ( pd->ids, c->window, NULL );
+ if (c->wmdesktop != 0xFFFFFFF