aboutsummaryrefslogtreecommitdiffstats
path: root/sway/criteria.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-05-12 08:52:48 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-05-12 08:52:48 -0400
commitac0e62584f6101277b76622a7274866cd50f615c (patch)
treebc4b40d375e765a9cc7bc9f812bea56e04047cbf /sway/criteria.c
parentMerge pull request #1952 from Dudemanguy911/fix-crash-on-fullscreen (diff)
downloadsway-ac0e62584f6101277b76622a7274866cd50f615c.tar.gz
sway-ac0e62584f6101277b76622a7274866cd50f615c.tar.zst
sway-ac0e62584f6101277b76622a7274866cd50f615c.zip
Revert "Merge pull request #1953 from RyanDwyer/criteria-focused"
Diffstat (limited to 'sway/criteria.c')
-rw-r--r--sway/criteria.c204
1 files changed, 42 insertions, 162 deletions
diff --git a/sway/criteria.c b/sway/criteria.c
index 294b2922..7da790e6 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -190,128 +190,19 @@ static bool generate_regex(pcre **regex, char *value) {
190 return true; 190 return true;
191} 191}
192 192
193enum criteria_token {
194 T_APP_ID,
195 T_CLASS,
196 T_CON_ID,
197 T_CON_MARK,
198 T_FLOATING,
199 T_ID,
200 T_INSTANCE,
201 T_TILING,
202 T_TITLE,
203 T_URGENT,
204 T_WINDOW_ROLE,
205 T_WINDOW_TYPE,
206 T_WORKSPACE,
207
208 T_INVALID,
209};
210
211static enum criteria_token token_from_name(char *name) {
212 if (strcmp(name, "app_id") == 0) {
213 return T_APP_ID;
214 } else if (strcmp(name, "class") == 0) {
215 return T_CLASS;
216 } else if (strcmp(name, "con_id") == 0) {
217 return T_CON_ID;
218 } else if (strcmp(name, "con_mark") == 0) {
219 return T_CON_MARK;
220 } else if (strcmp(name, "id") == 0) {
221 return T_ID;
222 } else if (strcmp(name, "instance") == 0) {
223 return T_INSTANCE;
224 } else if (strcmp(name, "title") == 0) {
225 return T_TITLE;
226 } else if (strcmp(name, "urgent") == 0) {
227 return T_URGENT;
228 } else if (strcmp(name, "window_role") == 0) {
229 return T_WINDOW_ROLE;
230 } else if (strcmp(name, "window_type") == 0) {
231 return T_WINDOW_TYPE;
232 } else if (strcmp(name, "workspace") == 0) {
233 return T_WORKSPACE;
234 }
235 return T_INVALID;
236}
237
238/**
239 * Get a property of the focused view.
240 *
241 * Note that we are taking the focused view at the time of criteria parsing, not
242 * at the time of execution. This is because __focused__ only makes sense when
243 * using criteria via IPC. Using __focused__ in config is not useful because
244 * criteria is only executed once per view.
245 */
246static char *get_focused_prop(enum criteria_token token) {
247 struct sway_seat *seat = input_manager_current_seat(input_manager);
248 struct sway_container *focus = seat_get_focus(seat);
249
250 if (!focus || focus->type != C_VIEW) {
251 return NULL;
252 }
253 struct sway_view *view = focus->sway_view;
254 const char *value = NULL;
255
256 switch (token) {
257 case T_APP_ID:
258 value = view_get_app_id(view);
259 break;
260 case T_CLASS:
261 value = view_get_class(view);
262 break;
263 case T_INSTANCE:
264 value = view_get_instance(view);
265 break;
266 case T_TITLE:
267 value = view_get_class(view);
268 break;
269 case T_WINDOW_ROLE:
270 value = view_get_class(view);
271 break;
272 case T_WORKSPACE:
273 {
274 struct sway_container *ws = container_parent(focus, C_WORKSPACE);
275 if (ws) {
276 value = ws->name;
277 }
278 }
279 break;
280 case T_CON_ID: // These do not support __focused__
281 case T_CON_MARK:
282 case T_FLOATING:
283 case T_ID:
284 case T_TILING:
285 case T_URGENT:
286 case T_WINDOW_TYPE:
287 case T_INVALID:
288 break;
289 }
290 if (value) {
291 return strdup(value);
292 }
293 return NULL;
294}
295
296static bool parse_token(struct criteria *criteria, char *name, char *value) { 193static bool parse_token(struct criteria *criteria, char *name, char *value) {
297 enum criteria_token token = token_from_name(name);
298 if (token == T_INVALID) {
299 const char *fmt = "Token '%s' is not recognized";
300 int len = strlen(fmt) + strlen(name) - 1;
301 error = malloc(len);
302 snprintf(error, len, fmt, name);
303 return false;
304 }
305
306 char *effective_value = NULL;
307 if (value && strcmp(value, "__focused__") == 0) {
308 effective_value = get_focused_prop(token);
309 } else if (value) {
310 effective_value = strdup(value);
311 }
312
313 // Require value, unless token is floating or tiled 194 // Require value, unless token is floating or tiled
314 if (!effective_value && token != T_FLOATING && token != T_TILING) { 195 if (!value && (strcmp(name, "title") == 0
196 || strcmp(name, "app_id") == 0
197 || strcmp(name, "class") == 0
198 || strcmp(name, "instance") == 0
199 || strcmp(name, "con_id") == 0
200 || strcmp(name, "con_mark") == 0
201 || strcmp(name, "window_role") == 0
202 || strcmp(name, "window_type") == 0
203 || strcmp(name, "id") == 0
204 || strcmp(name, "urgent") == 0
205 || strcmp(name, "workspace") == 0)) {
315 const char *fmt = "Token '%s' requires a value"; 206 const char *fmt = "Token '%s' requires a value";
316 int len = strlen(fmt) + strlen(name) - 1; 207 int len = strlen(fmt) + strlen(name) - 1;
317 error = malloc(len); 208 error = malloc(len);
@@ -319,64 +210,53 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
319 return false; 210 return false;
320 } 211 }
321 212
322 char *endptr = NULL; 213 if (strcmp(name, "title") == 0) {
323 switch (token) { 214 generate_regex(&criteria->title, value);
324 case T_TITLE: 215 } else if (strcmp(name, "app_id") == 0) {
325 generate_regex(&criteria->title, effective_value); 216 generate_regex(&criteria->app_id, value);
326 break; 217 } else if (strcmp(name, "class") == 0) {
327 case T_APP_ID: 218 generate_regex(&criteria->class, value);
328 generate_regex(&criteria->app_id, effective_value); 219 } else if (strcmp(name, "instance") == 0) {
329 break; 220 generate_regex(&criteria->instance, value);
330 case T_CLASS: 221 } else if (strcmp(name, "con_id") == 0) {
331 generate_regex(&criteria->class, effective_value); 222 char *endptr;
332 break; 223 criteria->con_id = strtoul(value, &endptr, 10);
333 case T_INSTANCE:
334 generate_regex(&criteria->instance, effective_value);
335 break;
336 case T_CON_ID:
337 criteria->con_id = strtoul(effective_value, &endptr, 10);
338 if (*endptr != 0) { 224 if (*endptr != 0) {
339 error = strdup("The value for 'con_id' should be numeric"); 225 error = strdup("The value for 'con_id' should be numeric");
340 } 226 }
341 break; 227 } else if (strcmp(name, "con_mark") == 0) {
342 case T_CON_MARK: 228 generate_regex(&criteria->con_mark, value);
343 generate_regex(&criteria->con_mark, effective_value); 229 } else if (strcmp(name, "window_role") == 0) {
344 break; 230 generate_regex(&criteria->window_role, value);
345 case T_WINDOW_ROLE: 231 } else if (strcmp(name, "window_type") == 0) {
346 generate_regex(&criteria->window_role, effective_value);
347 break;
348 case T_WINDOW_TYPE:
349 // TODO: This is a string but will be stored as an enum or integer 232 // TODO: This is a string but will be stored as an enum or integer
350 break; 233 } else if (strcmp(name, "id") == 0) {
351 case T_ID: 234 char *endptr;
352 criteria->id = strtoul(effective_value, &endptr, 10); 235 criteria->id = strtoul(value, &endptr, 10);
353 if (*endptr != 0) { 236 if (*endptr != 0) {
354 error = strdup("The value for 'id' should be numeric"); 237 error = strdup("The value for 'id' should be numeric");
355 } 238 }
356 break; 239 } else if (strcmp(name, "floating") == 0) {
357 case T_FLOATING:
358 criteria->floating = true; 240 criteria->floating = true;
359 break; 241 } else if (strcmp(name, "tiling") == 0) {
360 case T_TILING:
361 criteria->tiling = true; 242 criteria->tiling = true;
362 break; 243 } else if (strcmp(name, "urgent") == 0) {
363 case T_URGENT: 244 if (strcmp(value, "latest") == 0) {
364 if (strcmp(effective_value, "latest") == 0) {
365 criteria->urgent = 'l'; 245 criteria->urgent = 'l';
366 } else if (strcmp(effective_value, "oldest") == 0) { 246 } else if (strcmp(value, "oldest") == 0) {
367 criteria->urgent = 'o'; 247 criteria->urgent = 'o';
368 } else { 248 } else {
369 error = 249 error =
370 strdup("The value for 'urgent' must be 'latest' or 'oldest'"); 250 strdup("The value for 'urgent' must be 'latest' or 'oldest'");
371 } 251 }
372 break; 252 } else if (strcmp(name, "workspace") == 0) {
373 case T_WORKSPACE: 253 criteria->workspace = strdup(value);
374 criteria->workspace = strdup(effective_value); 254 } else {
375 break; 255 const char *fmt = "Token '%s' is not recognized";
376 case T_INVALID: 256 int len = strlen(fmt) + strlen(name) - 1;
377 break; 257 error = malloc(len);
258 snprintf(error, len, fmt, name);
378 } 259 }
379 free(effective_value);
380 260
381 if (error) { 261 if (error) {
382 return false; 262 return false;