rofi  1.7.0
theme.c
Go to the documentation of this file.
1 /*
2  * rofi
3  *
4  * MIT/X11 License
5  * Copyright © 2013-2021 Qball Cow <qball@gmpclient.org>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  */
27 
29 #define G_LOG_DOMAIN "Theme"
30 
31 #include "config.h"
32 #include <errno.h>
33 #include <math.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 // GFile stuff.
38 #include "helper.h"
39 #include "rofi-icon-fetcher.h"
40 #include "rofi-types.h"
41 #include "rofi.h"
42 #include "settings.h"
43 #include "theme-parser.h"
44 #include "theme.h"
45 #include "view.h"
46 #include "widgets/textbox.h"
47 #include <gio/gio.h>
48 
49 void yyerror(YYLTYPE *yylloc, const char *, const char *);
51  // TODO UPDATE
52  return d.base.type == e.base.type && d.base.distance == e.base.distance &&
53  d.style == e.style;
54 }
55 
56 static gpointer rofi_g_list_strdup(gconstpointer data,
57  G_GNUC_UNUSED gpointer user_data) {
58  return g_strdup(data);
59 }
60 
62  const char *name) {
63  for (unsigned int i = 0; i < base->num_widgets; i++) {
64  if (g_strcmp0(base->widgets[i]->name, name) == 0) {
65  return base->widgets[i];
66  }
67  }
68 
69  base->widgets =
70  g_realloc(base->widgets, sizeof(ThemeWidget *) * (base->num_widgets + 1));
71  base->widgets[base->num_widgets] = g_slice_new0(ThemeWidget);
72  ThemeWidget *retv = base->widgets[base->num_widgets];
73  retv->parent = base;
74  retv->name = g_strdup(name);
75  base->num_widgets++;
76  return retv;
77 }
82  Property *retv = g_slice_new0(Property);
83  retv->type = type;
84  return retv;
85 }
86 
87 static RofiDistanceUnit *
89  RofiDistanceUnit *retv = g_slice_new0(RofiDistanceUnit);
90  *retv = *unit;
91  if (unit->left) {
93  }
94  if (unit->right) {
96  }
97  return retv;
98 }
100  RofiDistance retv = distance;
101  if (distance.base.left) {
103  }
104  if (distance.base.right) {
105  retv.base.right =
107  }
108  return retv;
109 }
110 
113  retv->name = g_strdup(p->name);
114 
115  switch (p->type) {
116  case P_STRING:
117  retv->value.s = g_strdup(p->value.s);
118  break;
119  case P_LIST:
120  retv->value.list =
121  g_list_copy_deep(p->value.list, rofi_g_list_strdup, NULL);
122  break;
123  case P_LINK:
124  retv->value.link.name = g_strdup(p->value.link.name);
125  retv->value.link.ref = NULL;
126  if (p->value.link.def_value) {
127  retv->value.link.def_value =
129  }
130  break;
131  case P_PADDING: {
132  retv->value = p->value;
133  retv->value.padding.top =
135  retv->value.padding.left =
137  retv->value.padding.bottom =
139  retv->value.padding.right =
141  break;
142  }
143  case P_IMAGE: {
144  retv->value = p->value;
145  retv->value.image.url = g_strdup(p->value.image.url);
146  retv->value.image.colors = NULL;
147  for (GList *l = g_list_first(p->value.image.colors); l;
148  l = g_list_next(l)) {
149  retv->value.image.colors = g_list_append(
150  retv->value.image.colors, g_memdup(l->data, sizeof(ThemeColor)));
151  }
152  break;
153  }
154  default:
155  retv->value = p->value;
156  }
157  return retv;
158 }
159 
161  if (unit->left) {
163  unit->left = NULL;
164  }
165  if (unit->right) {
167  unit->right = NULL;
168  }
169  g_slice_free(RofiDistanceUnit, unit);
170 }
172  if (distance->base.left) {
174  distance->base.left = NULL;
175  }
176  if (distance->base.right) {
178  distance->base.right = NULL;
179  }
180 }
181 
183  if (p == NULL) {
184  return;
185  }
186  g_free(p->name);
187  if (p->type == P_STRING) {
188  g_free(p->value.s);
189  } else if (p->type == P_LINK) {
190  g_free(p->value.link.name);
191  if (p->value.link.def_value) {
193  }
194  } else if (p->type == P_PADDING) {
199  } else if (p->type == P_IMAGE) {
200  if (p->value.image.url) {
201  g_free(p->value.image.url);
202  }
203  if (p->value.image.colors) {
204  g_list_free_full(p->value.image.colors, g_free);
205  }
206  }
207  g_slice_free(Property, p);
208 }
209 
210 void rofi_theme_reset(void) {
212  rofi_theme = g_slice_new0(ThemeWidget);
213  rofi_theme->name = g_strdup("Root");
214 }
215 
217  if (widget == NULL) {
218  return;
219  }
220  if (widget->properties) {
221  g_hash_table_destroy(widget->properties);
222  widget->properties = NULL;
223  }
224  if (widget->media) {
225  g_slice_free(ThemeMedia, widget->media);
226  }
227  for (unsigned int i = 0; i < widget->num_widgets; i++) {
228  rofi_theme_free(widget->widgets[i]);
229  }
230  g_free(widget->widgets);
231  g_free(widget->name);
232  g_slice_free(ThemeWidget, widget);
233 }
234 
238 inline static void printf_double(double d) {
239  char buf[G_ASCII_DTOSTR_BUF_SIZE];
240  g_ascii_formatd(buf, G_ASCII_DTOSTR_BUF_SIZE, "%.4lf", d);
241  fputs(buf, stdout);
242 }
243 
245  if (unit->modtype == ROFI_DISTANCE_MODIFIER_GROUP) {
246  fputs("( ", stdout);
247  }
248  if (unit->left) {
250  }
251 
252  if (unit->modtype == ROFI_DISTANCE_MODIFIER_ADD) {
253  fputs(" + ", stdout);
254  } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_SUBTRACT) {
255  fputs(" - ", stdout);
256  } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_DIVIDE) {
257  fputs(" / ", stdout);
258  } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MULTIPLY) {
259  fputs(" * ", stdout);
260  } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MODULO) {
261  fputs(" % ", stdout);
262  } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MIN) {
263  fputs(" min ", stdout);
264  } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MAX) {
265  fputs(" max ", stdout);
266  }
267  if (unit->right) {
269  }
270 
271  if (unit->modtype == ROFI_DISTANCE_MODIFIER_NONE) {
272  if (unit->type == ROFI_PU_PX) {
273  printf("%upx ", (unsigned int)unit->distance);
274  } else if (unit->type == ROFI_PU_MM) {
275  printf_double(unit->distance);
276  fputs("mm ", stdout);
277  } else if (unit->type == ROFI_PU_PERCENT) {
278  printf_double(unit->distance);
279  fputs("% ", stdout);
280  } else if (unit->type == ROFI_PU_CH) {
281  printf_double(unit->distance);
282  fputs("ch ", stdout);
283  } else {
284  printf_double(unit->distance);
285  fputs("em ", stdout);
286  }
287  }
288  if (unit->modtype == ROFI_DISTANCE_MODIFIER_GROUP) {
289  fputs(" )", stdout);
290  }
291 }
292 
295  fputs("calc( ", stdout);
296  }
299  fputs(")", stdout);
300  }
301  if (d.style == ROFI_HL_DASH) {
302  printf("dash ");
303  }
304 }
306 const char *const RofiCursorTypeStr[3] = {
307  "default",
308  "pointer",
309  "text",
310 };
311 
313  switch (p->type) {
314  case P_LIST:
315  printf("[ ");
316  for (GList *iter = p->value.list; iter != NULL; iter = g_list_next(iter)) {
317  printf("%s", (char *)(iter->data));
318  if (iter->next != NULL) {
319  printf(",");
320  }
321  }
322  printf(" ]");
323  break;
324  case P_ORIENTATION:
325  printf("%s", (p->value.i == ROFI_ORIENTATION_HORIZONTAL) ? "horizontal"
326  : "vertical");
327  break;
328  case P_CURSOR:
329  printf("%s", RofiCursorTypeStr[p->value.i]);
330  break;
331  case P_HIGHLIGHT:
332  if (p->value.highlight.style & ROFI_HL_BOLD) {
333  printf("bold ");
334  }
336  printf("underline ");
337  }
339  printf("strikethrough ");
340  }
341  if (p->value.highlight.style & ROFI_HL_ITALIC) {
342  printf("italic ");
343  }
344  if (p->value.highlight.style & ROFI_HL_COLOR) {
345  printf("rgba ( %.0f, %.0f, %.0f, %.0f %% )",
346  (p->value.highlight.color.red * 255.0),
347  (p->value.highlight.color.green * 255.0),
348  (p->value.highlight.color.blue * 255.0),
349  (p->value.highlight.color.alpha * 100.0));
350  }
351  break;
352  case P_POSITION: {
353  switch (p->value.i) {
354  case WL_CENTER:
355  fputs("center", stdout);
356  break;
357  case WL_NORTH:
358  fputs("north", stdout);
359  break;
360  case WL_SOUTH:
361  fputs("south", stdout);
362  break;
363  case WL_WEST:
364  fputs("west", stdout);
365  break;
366  case WL_EAST:
367  fputs("east", stdout);
368  break;
369  case WL_NORTH | WL_EAST:
370  fputs("northeast", stdout);
371  break;
372  case WL_SOUTH | WL_EAST:
373  fputs("southeast", stdout);
374  break;
375  case WL_NORTH | WL_WEST:
376  fputs("northwest", stdout);
377  break;
378  case WL_SOUTH | WL_WEST:
379  fputs("southwest", stdout);
380  break;
381  }
382  break;
383  }
384  case P_STRING:
385  printf("\"%s\"", p->value.s);
386  break;
387  case P_INTEGER:
388  printf("%d", p->value.i);
389  break;
390  case P_DOUBLE: {
391  char sign = (p->value.f < 0);
392  int top = (int)fabs(p->value.f);
393  int bottom = (fabs(fmod(p->value.f, 1.0))) * 100;
394  printf("%s%d.%02d", sign ? "-" : "", top, bottom);
395  break;
396  }
397  case P_BOOLEAN:
398  printf("%s", p->value.b ? "true" : "false");
399  break;
400  case P_COLOR:
401  printf("rgba ( %.0f, %.0f, %.0f, %.0f %% )", (p->value.color.red * 255.0),
402  (p->value.color.green * 255.0), (p->value.color.blue * 255.0),
403  (p->value.color.alpha * 100.0));
404  break;
405  case P_IMAGE: {
406  if (p->value.image.type == ROFI_IMAGE_URL) {
407  printf("url (\"%s\")", p->value.s);
408  } else if (p->value.image.type == ROFI_IMAGE_LINEAR_GRADIENT) {
409  printf("linear-gradient ( ");
410  guint length = g_list_length(p->value.image.colors);
411  guint index = 0;
412  for (GList *l = g_list_first(p->value.image.colors); l != NULL;
413  l = g_list_next(l)) {
414  ThemeColor *color = (ThemeColor *)l->data;
415  printf("rgba ( %.0f, %.0f, %.0f, %.0f %% )", (color->red * 255.0),
416  (color->green * 255.0), (color->blue * 255.0),
417  (color->alpha * 100.0));
418  index++;
419  if (index < length) {
420  printf(", ");
421  }
422  }
423  printf(")");
424  }
425 
426  break;
427  }
428  case P_PADDING:
433  } else if (distance_compare(p->value.padding.top,
434  p->value.padding.bottom) &&
436  p->value.padding.right)) {
439  } else if (!distance_compare(p->value.padding.top,
440  p->value.padding.bottom) &&
442  p->value.padding.right)) {
446  } else {
451  }
452  break;
453  case P_LINK:
454  if (p->value.link.def_value) {
455  printf("var( %s, ", p->value.link.name);
457  printf(")");
458  } else {
459  printf("var(%s)", p->value.link.name);
460  }
461  break;
462  case P_INHERIT:
463  printf("inherit");
464  break;
465  default:
466  break;
467  }
468 }
469 
470 static void rofi_theme_print_property_index(size_t pnl, int depth,
471  Property *p) {
472  int pl = strlen(p->name);
473  printf("%*s%s:%*s ", depth, "", p->name, (int)pnl - pl, "");
475  putchar(';');
476  putchar('\n');
477 }
478 
480  GHashTableIter iter;
481  gpointer key, value;
482 
483  if (widget->media) {
484  printf("%s {\n", widget->name);
485  for (unsigned int i = 0; i < widget->num_widgets; i++) {
486  rofi_theme_print_index(widget->widgets[i], index + 4);
487  }
488  printf("}\n");
489  } else {
490  if (widget->properties) {
491  GList *list = NULL;
492  ThemeWidget *w = widget;
493  while (w) {
494  if (g_strcmp0(w->name, "Root") == 0) {
495  break;
496  }
497  if (w->media) {
498  break;
499  }
500  list = g_list_prepend(list, w->name);
501  w = w->parent;
502  }
503  if (g_list_length(list) > 0) {
504  printf("%*s", index, "");
505  for (GList *citer = g_list_first(list); citer != NULL;
506  citer = g_list_next(citer)) {
507  char *name = (char *)citer->data;
508  fputs(name, stdout);
509  if (citer->prev == NULL && citer->next) {
510  putchar(' ');
511  } else if (citer->next) {
512  putchar('.');
513  }
514  }
515  printf(" {\n");
516  } else {
517  printf("%*s* {\n", index, "");
518  }
519  size_t property_name_length = 0;
520  g_hash_table_iter_init(&iter, widget->properties);
521  while (g_hash_table_iter_next(&iter, &key, &value)) {
522  Property *pv = (Property *)value;
523  property_name_length = MAX(strlen(pv->name), property_name_length);
524  }
525  g_hash_table_iter_init(&iter, widget->properties);
526  while (g_hash_table_iter_next(&iter, &key, &value)) {
527  Property *pv = (Property *)value;
528  rofi_theme_print_property_index(property_name_length, index + 4, pv);
529  }
530  printf("%*s}\n", index, "");
531  g_list_free(list);
532  }
533  for (unsigned int i = 0; i < widget->num_widgets; i++) {
534  rofi_theme_print_index(widget->widgets[i], index);
535  }
536  }
537 }
538 
540  if (widget != NULL) {
541  printf("/**\n * rofi -dump-theme output.\n * Rofi version: %s\n **/\n",
542  PACKAGE_VERSION);
544  }
545 }
546 
550 int yyparse();
551 
555 void yylex_destroy(void);
556 
560 extern FILE *yyin;
561 
569 void yyerror(YYLTYPE *yylloc, const char *what, const char *s) {
570  char *what_esc = what ? g_markup_escape_text(what, -1) : g_strdup("");
571  GString *str = g_string_new("");
572  g_string_printf(str,
573  "<big><b>Error while parsing theme:</b></big> <i>%s</i>\n",
574  what_esc);
575  g_free(what_esc);
576  char *esc = g_markup_escape_text(s, -1);
577  g_string_append_printf(
578  str,
579  "\tParser error: <span size=\"smaller\" style=\"italic\">%s</span>\n",
580  esc);
581  g_free(esc);
582  if (yylloc->filename != NULL) {
583  g_string_append_printf(
584  str,
585  "\tLocation: line %d column %d to line %d column %d.\n"
586  "\tFile '%s'\n",
587  yylloc->first_line, yylloc->first_column, yylloc->last_line,
588  yylloc->last_column, yylloc->filename);
589  } else {
590  g_string_append_printf(
591  str, "\tLocation: line %d column %d to line %d column %d\n",
592  yylloc->first_line, yylloc->first_column, yylloc->last_line,
593  yylloc->last_column);
594  }
595  g_log("Parser", G_LOG_LEVEL_DEBUG, "Failed to parse theme:\n%s", str->str);
597 }
598 
599 static void rofi_theme_copy_property_int(G_GNUC_UNUSED gpointer key,
600  gpointer value, gpointer user_data) {
601  GHashTable *table = (GHashTable *)user_data;
603  g_hash_table_replace(table, p->name, p);
604 }
606  if (table == NULL) {
607  return;
608  }
609  if (widget->properties == NULL) {
610  widget->properties =
611  g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
612  (GDestroyNotify)rofi_theme_property_free);
613  }
614  g_hash_table_foreach(table, rofi_theme_copy_property_int, widget->properties);
615 }
616 
622  const char *name) {
623  for (unsigned int j = 0; widget && j < widget->num_widgets; j++) {
624  if (g_strcmp0(widget->widgets[j]->name, name) == 0) {
625  return widget->widgets[j];
626  }
627  }
628  return widget;
629 }
630 
631 static ThemeWidget *rofi_theme_find(ThemeWidget *widget, const char *name,
632  const gboolean exact) {
633  if (widget == NULL || name == NULL) {
634  return widget;
635  }
636  char *tname = g_strdup(name);
637  char *saveptr = NULL;
638  int found = TRUE;
639  for (const char *iter = strtok_r(tname, ".", &saveptr); iter != NULL;
640  iter = strtok_r(NULL, ".", &saveptr)) {
641  found = FALSE;
643  if (f != widget) {
644  widget = f;
645  found = TRUE;
646  } else if (exact) {
647  break;
648  }
649  }
650  g_free(tname);
651  if (!exact || found) {
652  return widget;
653  }
654  return NULL;
655 }
656 
658  // Set name, remove '@' prefix.
659  const char *name = p->value.link.name; // + (*(p->value.link.name)== '@'?1:0;
660  g_info("Resolving link to %s", p->value.link.name);
661  if (depth > 20) {
662  g_warning("Found more then 20 redirects for property. Stopping.");
663  p->value.link.ref = p;
664  return;
665  }
666 
667  if (rofi_theme->properties &&
668  g_hash_table_contains(rofi_theme->properties, name)) {
669  Property *pr = g_hash_table_lookup(rofi_theme->properties, name);
670  g_info("Resolving link %s found: %s", p->value.link.name, pr->name);
671  if (pr->type == P_LINK) {
672  if (pr->value.link.ref == NULL) {
674  }
675  if (pr->value.link.ref != pr) {
676  p->value.link.ref = pr->value.link.ref;
677  return;
678  }
679  } else {
680  p->value.link.ref = pr;
681  return;
682  }
683  }
684  // No found and we have default value.
685  if (p->value.link.def_value) {
686  p->value.link.ref = p->value.link.def_value;
687  return;
688  }
689 
690  // No found, set ref to self.
691  p->value.link.ref = p;
692 }
693 
695  const char *property, gboolean exact) {
696  while (widget) {
697  if (widget->properties &&
698  g_hash_table_contains(widget->properties, property)) {
699  Property *p = g_hash_table_lookup(widget->properties, property);
700  if (p->type == P_INHERIT) {
701  return p;
702  }
703  if (p->type == P_LINK) {
704  if (p->value.link.ref == NULL) {
705  // Resolve link.
707  }
708  if (p->value.link.ref != NULL && p->value.link.ref->type == type) {
709  return p->value.link.ref;
710  }
711  }
712  if (p->type == type) {
713  return p;
714  }
715  // RofiPadding and integer can be converted.
716  if (p->type == P_INTEGER && type == P_PADDING) {
717  return p;
718  }
719  g_debug("Found property: '%s' on '%s', but type %s does not match "
720  "expected type %s.",
721  property, widget->name, PropertyTypeName[p->type],
722  PropertyTypeName[type]);
723  }
724  if (exact) {
725  return NULL;
726  }
727  // Fall back to defaults.
728  widget = widget->parent;
729  }
730  return NULL;
731 }
732 ThemeWidget *rofi_config_find_widget(const char *name, const char *state,
733  gboolean exact) {
734  // First find exact match based on name.
736  widget = rofi_theme_find(widget, state, exact);
737 
738  return widget;
739 }
740 ThemeWidget *rofi_theme_find_widget(const char *name, const char *state,
741  gboolean exact) {
742  // First find exact match based on name.
744  widget = rofi_theme_find(widget, state, exact);
745 
746  return widget;
747 }
748 
750  const char *property, int def) {
751  if (p) {
752  if (p->type == P_INHERIT) {
753  if (widget->parent) {
754  ThemeWidget *parent =
756  Property *pv =
757  rofi_theme_find_property(parent, P_POSITION, property, FALSE);
758  return rofi_theme_get_position_inside(pv, widget->parent, property, def);
759  }
760  return def;
761  }
762  return p->value.i;
763  }
764  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
765  widget->state ? widget->state : "", property);
766  return def;
767 }
768 int rofi_theme_get_position(const widget *widget, const char *property,
769  int def) {
771  Property *p = rofi_theme_find_property(wid, P_POSITION, property, FALSE);
772  return rofi_theme_get_position_inside(p, widget, property, def);
773 }
775  const char *property, int def) {
776  if (p) {
777  if (p->type == P_INHERIT) {
778  if (widget->parent) {
779  ThemeWidget *parent =
781  Property *pv =
782  rofi_theme_find_property(parent, P_INTEGER, property, FALSE);
783  return rofi_theme_get_integer_inside(pv, widget->parent, property, def);
784  }
785  return def;
786  }
787  return p->value.i;
788  }
789  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
790  widget->state ? widget->state : "", property);
791  return def;
792 }
793 int rofi_theme_get_integer(const widget *widget, const char *property,
794  int def) {
796  Property *p = rofi_theme_find_property(wid, P_INTEGER, property, FALSE);
797  return rofi_theme_get_integer_inside(p, widget, property, def);
798 }
800  const widget *widget,
801  const char *property,
802  int def) {
803  if (p) {
804  if (p->type == P_INHERIT) {
805  if (widget->parent) {
806  ThemeWidget *parent =
808  Property *pv =
809  rofi_theme_find_property(parent, P_PADDING, property, FALSE);
810  return rofi_theme_get_distance_inside(pv, widget->parent, property,
811  def);
812  }
813  return (RofiDistance){
814  .base = {def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL},
815  .style = ROFI_HL_SOLID};
816  }
817  if (p->type == P_INTEGER) {
818  return (RofiDistance){.base = {p->value.i, ROFI_PU_PX,
819  ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL},
820  .style = ROFI_HL_SOLID};
821  }
822  return p->value.padding.left;
823  }
824  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
825  widget->state ? widget->state : "", property);
826  return (RofiDistance){
827  .base = {def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL},
828  .style = ROFI_HL_SOLID};
829 }
830 RofiDistance rofi_theme_get_distance(const widget *widget, const char *property,
831  int def) {
833  Property *p = rofi_theme_find_property(wid, P_PADDING, property, FALSE);
834  return rofi_theme_get_distance_inside(p, widget, property, def);
835 }
836 
838  const char *property, int def) {
839  if (p) {
840  if (p->type == P_INHERIT) {
841  if (widget->parent) {
842  ThemeWidget *parent =
844  Property *pv =
845  rofi_theme_find_property(parent, P_BOOLEAN, property, FALSE);
846  return rofi_theme_get_boolean_inside(pv, widget->parent, property, def);
847  }
848  return def;
849  }
850  return p->value.b;
851  }
852  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
853  widget->state ? widget->state : "", property);
854  return def;
855 }
856 int rofi_theme_get_boolean(const widget *widget, const char *property,
857  int def) {
859  Property *p = rofi_theme_find_property(wid, P_BOOLEAN, property, FALSE);
860  return rofi_theme_get_boolean_inside(p, widget, property, def);
861 }
862 
864  const widget *widget,
865  const char *property,
866  RofiOrientation def) {
867  if (p) {
868  if (p->type == P_INHERIT) {
869  if (widget->parent) {
870  ThemeWidget *parent =
872  Property *pv =
873  rofi_theme_find_property(parent, P_ORIENTATION, property, FALSE);
874  return rofi_theme_get_orientation_inside(pv, widget->parent, property, def);
875  }
876  return def;
877  }
878  return p->value.b;
879  }
880  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
881  widget->state ? widget->state : "", property);
882  return def;
883 }
885  const char *property,
886  RofiOrientation def) {
888  Property *p = rofi_theme_find_property(wid, P_ORIENTATION, property, FALSE);
889  return rofi_theme_get_orientation_inside(p, widget, property, def);
890 }
891 
893  const widget *widget,
894  const char *property,
895  RofiCursorType def) {
896  if (p) {
897  if (p->type == P_INHERIT) {
898  if (widget->parent) {
899  ThemeWidget *parent =
901  Property *pv =
902  rofi_theme_find_property(parent, P_CURSOR, property, FALSE);
903  return rofi_theme_get_cursor_type_inside(pv, widget->parent, property, def);
904  }
905  return def;
906  }
907  return p->value.i;
908  }
909  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
910  widget->state ? widget->state : "", property);
911  return def;
912 }
914  const char *property,
915  RofiCursorType def) {
917  Property *p = rofi_theme_find_property(wid, P_CURSOR, property, FALSE);
918  return rofi_theme_get_cursor_type_inside(p, widget, property, def);
919 }
921  const widget *widget,
922  const char *property,
923  const char *def) {
924  if (p) {
925  if (p->type == P_INHERIT) {
926  if (widget->parent) {
927  ThemeWidget *parent =
929  Property *pv =
930  rofi_theme_find_property(parent, P_STRING, property, FALSE);
931  return rofi_theme_get_string_inside(pv, widget->parent, property, def);
932  }
933  return def;
934  }
935  return p->value.s;
936  }
937  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
938  widget->state ? widget->state : "", property);
939  return def;
940 }
941 const char *rofi_theme_get_string(const widget *widget, const char *property,
942  const char *def) {
944  Property *p = rofi_theme_find_property(wid, P_STRING, property, FALSE);
945  return rofi_theme_get_string_inside(p, widget, property, def);
946 }
947 static double rofi_theme_get_double_inside(const widget *orig, Property *p,
948  const widget *widget,
949  const char *property, double def) {
950  if (p) {
951  if (p->type == P_INHERIT) {
952  if (widget->parent) {
953  ThemeWidget *parent =
955  Property *pv =
956  rofi_theme_find_property(parent, P_DOUBLE, property, FALSE);
957  return rofi_theme_get_double_inside(orig, pv, widget, property, def);
958  }
959  return def;
960  }
961  return p->value.f;
962  }
963  ThemeWidget *wid =
964  rofi_theme_find_widget(orig->name, widget->state, FALSE);
965  // Fallback to integer if double is not found.
966  p = rofi_theme_find_property(wid, P_INTEGER, property, FALSE);
967  return rofi_theme_get_integer_inside(p, widget, property, def);
968 }
969 double rofi_theme_get_double(const widget *widget, const char *property,
970  double def) {
972  Property *p = rofi_theme_find_property(wid, P_DOUBLE, property, FALSE);
973  return rofi_theme_get_double_inside(widget, p, widget, property, def);
974 }
976  const char *property, cairo_t *d) {
977  if (p) {
978  if (p->type == P_INHERIT) {
979  if (widget->parent) {
980  ThemeWidget *parent =
982  Property *pv =
983  rofi_theme_find_property(parent, P_COLOR, property, FALSE);
984  rofi_theme_get_color_inside(widget->parent, pv, property, d);
985  }
986  return;
987  }
988  cairo_set_source_rgba(d, p->value.color.red, p->value.color.green,
989  p->value.color.blue, p->value.color.alpha);
990  } else {
991  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
992  widget->state ? widget->state : "", property);
993  }
994 }
995 
996 void rofi_theme_get_color(const widget *widget, const char *property,
997  cairo_t *d) {
999  Property *p = rofi_theme_find_property(wid, P_COLOR, property, FALSE);
1000  rofi_theme_get_color_inside(widget, p, property, d);
1001 }
1002 
1004  const char *property, cairo_t *d) {
1005  if (p) {
1006  if (p->type == P_INHERIT) {
1007  if (widget->parent) {
1008  ThemeWidget *parent =
1010  Property *pv =
1011  rofi_theme_find_property(parent, P_IMAGE, property, FALSE);
1012  return rofi_theme_get_image_inside(pv, widget->parent, property, d);
1013  }
1014  return FALSE;
1015  }
1016  if (p->value.image.type == ROFI_IMAGE_URL) {
1017  int wsize = -1;
1018  int hsize = -1;
1019  switch (p->value.image.scaling) {
1020  case ROFI_SCALE_BOTH:
1021  wsize = widget->w;
1022  hsize = widget->h;
1023  break;
1024  case ROFI_SCALE_WIDTH:
1025  wsize = widget->w;
1026  break;
1027  case ROFI_SCALE_HEIGHT:
1028  hsize = widget->h;
1029  break;
1030  case ROFI_SCALE_NONE:
1031  default:
1032  break;
1033  }
1034  if (p->value.image.surface_id == 0 || p->value.image.wsize != wsize ||
1035  p->value.image.hsize != hsize) {
1036  p->value.image.surface_id =
1037  rofi_icon_fetcher_query_advanced(p->value.image.url, wsize, hsize);
1038  p->value.image.wsize = wsize;
1039  p->value.image.hsize = hsize;
1040  }
1041  cairo_surface_t *img = rofi_icon_fetcher_get(p->value.image.surface_id);
1042 
1043  if (img != NULL) {
1044  cairo_pattern_t *pat = cairo_pattern_create_for_surface(img);
1045  cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT);
1046  cairo_set_source(d, pat);
1047  cairo_pattern_destroy(pat);
1048  return TRUE;
1049  }
1050  } else if (p->value.image.type == ROFI_IMAGE_LINEAR_GRADIENT) {
1051  cairo_pattern_t *pat = NULL;
1052  switch (p->value.image.dir) {
1053  case ROFI_DIRECTION_RIGHT:
1054  pat = cairo_pattern_create_linear(0.0, 0.0, widget->w, 0.0);
1055  break;
1056  case ROFI_DIRECTION_LEFT:
1057  pat = cairo_pattern_create_linear(widget->w, 0.0, 0.0, 0.0);
1058  break;
1059  case ROFI_DIRECTION_BOTTOM:
1060  pat = cairo_pattern_create_linear(0.0, 0.0, 0.0, widget->h);
1061  break;
1062  case ROFI_DIRECTION_TOP:
1063  pat = cairo_pattern_create_linear(0.0, widget->h, 0.0, 0.0);
1064  break;
1065  case ROFI_DIRECTION_ANGLE: {
1066  double offsety1 =
1067  sin(G_PI * 2 * p->value.image.angle) * (widget->h / 2.0);
1068  double offsetx1 =
1069  cos(G_PI * 2 * p->value.image.angle) * (widget->w / 2.0);
1070  pat = cairo_pattern_create_linear(
1071  widget->w / 2.0 - offsetx1, widget->h / 2.0 - offsety1,
1072  widget->w / 2.0 + offsetx1, widget->h / 2.0 + offsety1);
1073  break;
1074  }
1075  };
1076  guint length = g_list_length(p->value.image.colors);
1077  if (length > 1) {
1078  length--;
1079  guint color_index = 0;
1080  for (GList *l = g_list_first(p->value.image.colors); l != NULL;
1081  l = g_list_next(l)) {
1082  ThemeColor *c = (ThemeColor *)(l->data);
1083  cairo_pattern_add_color_stop_rgba(pat, (color_index) / (double)length,
1084  c->red, c->green, c->blue,
1085  c->alpha);
1086  color_index++;
1087  }
1088  cairo_set_source(d, pat);
1089  cairo_pattern_destroy(pat);
1090  return TRUE;
1091  }
1092  if (length == 1) {
1093  ThemeColor *c = (ThemeColor *)(p->value.image.colors->data);
1094  cairo_pattern_add_color_stop_rgba(pat, 0, c->red, c->green, c->blue,
1095  c->alpha);
1096  cairo_set_source(d, pat);
1097  cairo_pattern_destroy(pat);
1098  return TRUE;
1099  }
1100  }
1101  } else {
1102  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
1103  widget->state ? widget->state : "", property);
1104  }
1105  return FALSE;
1106 }
1107 gboolean rofi_theme_get_image(const widget *widget, const char *property,
1108  cairo_t *d) {
1110  Property *p = rofi_theme_find_property(wid, P_IMAGE, property, FALSE);
1111  return rofi_theme_get_image_inside(p, widget, property, d);
1112 }
1114  const widget *widget,
1115  const char *property,
1116  RofiPadding pad) {
1117  if (p) {
1118  if (p->type == P_INHERIT) {
1119  if (widget->parent) {
1120  ThemeWidget *parent =
1122  Property *pv =
1123  rofi_theme_find_property(parent, P_PADDING, property, FALSE);
1124  return rofi_theme_get_padding_inside(pv, widget->parent, property, pad);
1125  }
1126  return pad;
1127  }
1128  if (p->type == P_PADDING) {
1129  pad = p->value.padding;
1130  } else {
1131  RofiDistance d =
1132  (RofiDistance){.base = {p->value.i, ROFI_PU_PX,
1133  ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL},
1134  .style = ROFI_HL_SOLID};
1135  return (RofiPadding){d, d, d, d};
1136  }
1137  }
1138  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
1139  widget->state ? widget->state : "", property);
1140  return pad;
1141 }
1142 RofiPadding rofi_theme_get_padding(const widget *widget, const char *property,
1143  RofiPadding pad) {
1145  Property *p = rofi_theme_find_property(wid, P_PADDING, property, FALSE);
1146  return rofi_theme_get_padding_inside(p, widget, property, pad);
1147 }
1148 
1150  const char *property,
1151  const char *defaults) {
1152  if (p) {
1153  if (p->type == P_INHERIT) {
1154  if (widget->parent) {
1155  ThemeWidget *parent =
1157  Property *pv =
1158  rofi_theme_find_property(parent, P_LIST, property, FALSE);
1159  return rofi_theme_get_list_inside(pv, widget->parent, property, defaults);
1160  }
1161  } else if (p->type == P_LIST) {
1162  return g_list_copy_deep(p->value.list, rofi_g_list_strdup, NULL);
1163  }
1164  }
1165  char **r = defaults ? g_strsplit(defaults, ",", 0) : NULL;
1166  if (r) {
1167  GList *l = NULL;
1168  for (int i = 0; r[i] != NULL; i++) {
1169  l = g_list_append(l, r[i]);
1170  }
1171  g_free(r);
1172  return l;
1173  }
1174  return NULL;
1175 }
1176 GList *rofi_theme_get_list(const widget *widget, const char *property,
1177  const char *defaults) {
1179  Property *p = rofi_theme_find_property(wid2, P_LIST, property, TRUE);
1180  return rofi_theme_get_list_inside(p, widget, property, defaults);
1181 }
1182 
1185  const char *property,
1187  if (p) {
1188  if (p->type == P_INHERIT) {
1189  if (widget->parent) {
1190  ThemeWidget *parent =
1192  Property *pv =
1193  rofi_theme_find_property(parent, P_HIGHLIGHT, property, FALSE);
1194  return rofi_theme_get_highlight_inside(pv, widget->parent, property,
1195  th);
1196  }
1197  return th;
1198  }
1199  return p->value.highlight;
1200  }
1201  g_debug("Theme entry: #%s %s property %s unset.", widget->name,
1202  widget->state ? widget->state : "", property);
1203  return th;
1204 }
1206  const char *property,
1209  Property *p = rofi_theme_find_property(wid, P_HIGHLIGHT, property, FALSE);
1210  return rofi_theme_get_highlight_inside(p, widget, property, th);
1211 }
1213  int val = unit->distance;
1214 
1215  if (unit->type == ROFI_PU_EM) {
1217  } else if (unit->type == ROFI_PU_CH) {
1218  val = unit->distance * textbox_get_estimated_ch();
1219  } else if (unit->type == ROFI_PU_PERCENT) {
1220  if (ori == ROFI_ORIENTATION_VERTICAL) {
1221  int height = 0;
1222  rofi_view_get_current_monitor(NULL, &height);
1223  val = (unit->distance * height) / (100.0);
1224  } else {
1225  int width = 0;
1226  rofi_view_get_current_monitor(&width, NULL);
1227  val = (unit->distance * width) / (100.0);
1228  }
1229  } else if (unit->type == ROFI_PU_MM) {
1230  val = unit->distance * config.dpi / 25.4;
1231  }
1232  return val;
1233 }
1234 
1236  RofiOrientation ori) {
1237  switch (unit->modtype) {
1239  return distance_unit_get_pixel(unit->left, ori);
1240  break;
1242  return distance_unit_get_pixel(unit->left, ori) +
1243  distance_unit_get_pixel(unit->right, ori);
1245  return distance_unit_get_pixel(unit->left, ori) -
1246  distance_unit_get_pixel(unit->right, ori);
1248  return distance_unit_get_pixel(unit->left, ori) *
1249  distance_unit_get_pixel(unit->right, ori);
1251  int a = distance_unit_get_pixel(unit->left, ori);
1252  int b = distance_unit_get_pixel(unit->right, ori);
1253  if (b != 0) {
1254  return a / b;
1255  }
1256  return a;
1257  }
1259  int a = distance_unit_get_pixel(unit->left, ori);
1260  int b = distance_unit_get_pixel(unit->right, ori);
1261  if (b != 0) {
1262  return a % b;
1263  }
1264  return 0;
1265  }
1267  int a = distance_unit_get_pixel(unit->left, ori);
1268  int b = distance_unit_get_pixel(unit->right, ori);
1269  return MIN(a, b);
1270  }
1272  int a = distance_unit_get_pixel(unit->left, ori);
1273  int b = distance_unit_get_pixel(unit->right, ori);
1274  return MAX(a, b);
1275  }
1276  default:
1277  break;
1278  }
1279  return get_pixels(unit, ori);
1280 }
1281 
1283  return distance_unit_get_pixel(&(d.base), ori);
1284 }
1285 
1286 void distance_get_linestyle(RofiDistance d, cairo_t *draw) {
1287  if (d.style == ROFI_HL_DASH) {
1288  const double dashes[1] = {4};
1289  cairo_set_dash(draw, dashes, 1, 0.0);
1290  } else {
1291  cairo_set_dash(draw, NULL, 0, 0.0);
1292  }
1293 }
1294 
1295 gboolean rofi_theme_is_empty(void) {
1296  if (rofi_theme == NULL) {
1297  return TRUE;
1298  }
1299  if (rofi_theme->properties == NULL && rofi_theme->num_widgets == 0) {
1300  return TRUE;
1301  }
1302  return FALSE;
1303 }
1304 
1305 char *rofi_theme_parse_prepare_file(const char *file, const char *parent_file) {
1306  char *filename = rofi_expand_path(file);
1307  // If no absolute path specified, expand it.
1308  if (parent_file != NULL && !g_path_is_absolute(filename)) {
1309  char *basedir = g_path_get_dirname(parent_file);
1310  char *path = g_build_filename(basedir, filename, NULL);
1311  g_free(filename);
1312  filename = path;
1313  g_free(basedir);
1314  }
1315  GFile *gf = g_file_new_for_path(filename);
1316  g_free(filename);
1317  filename = g_file_get_path(gf);
1318  g_object_unref(gf);
1319 
1320  return filename;
1321 }
1322 
1324  ThemeWidget *child) {
1325  g_assert(parent != NULL);
1326  g_assert(child != NULL);
1327 
1328  if (parent == rofi_theme && g_strcmp0(child->name, "*") == 0) {
1330  return;
1331  }
1332 
1333  ThemeWidget *w = rofi_theme_find_or_create_name(parent, child->name);
1335  for (unsigned int i = 0; i < child->num_widgets; i++) {
1337  }
1338 }
1340  g_assert(parent != NULL);
1341  g_assert(child != NULL);
1342 
1343  if (parent == rofi_theme && g_strcmp0(child->name, "*") == 0) {
1345  return;
1346  }
1347 
1348  ThemeWidget *w = rofi_theme_find_or_create_name(parent, child->name);
1349  if (child->media) {
1350  w->media = g_slice_new0(ThemeMedia);
1351  *(w->media) = *(child->media);
1352  }
1354  for (unsigned int i = 0; i < child->num_widgets; i++) {
1356  }
1357 }
1358 
1360  ThemeWidget *rwidget) {
1361  if (rwidget == NULL) {
1362  return;
1363  }
1364  for (unsigned int i = 0; i < rwidget->num_widgets; i++) {
1365  ThemeWidget *widget = rwidget->widgets[i];
1367  if (widget->media != NULL) {
1368  switch (widget->media->type) {
1370  int w = widget->media->value;
1371  if (mon.w >= w) {
1372  for (unsigned int x = 0; x < widget->num_widgets; x++) {
1374  widget->widgets[x]);
1375  }
1376  }
1377  break;
1378  }
1380  int w = widget->media->value;
1381  if (mon.w < w) {
1382  for (unsigned int x = 0; x < widget->num_widgets; x++) {
1384  widget->widgets[x]);
1385  }
1386  }
1387  break;
1388  }
1390  int h = widget->media->value;
1391  if (mon.h >= h) {
1392  for (unsigned int x = 0; x < widget->num_widgets; x++) {
1394  widget->widgets[x]);
1395  }
1396  }
1397  break;
1398  }
1400  int h = widget->media->value;
1401  if (mon.h < h) {
1402  for (unsigned int x = 0; x < widget->num_widgets; x++) {
1404  widget->widgets[x]);
1405  }
1406  }
1407  break;
1408  }
1409  case THEME_MEDIA_TYPE_MON_ID: {
1410  if (mon.monitor_id == widget->media->value) {
1411  for (unsigned int x = 0; x < widget->num_widgets; x++) {
1413  widget->widgets[x]);
1414  }
1415  }
1416  break;
1417  }
1419  double r = widget->media->value;
1420  if ((mon.w / (double)mon.h) >= r) {
1421  for (unsigned int x = 0; x < widget->num_widgets; x++) {
1423  widget->widgets[x]);
1424  }
1425  }
1426  break;
1427  }
1429  double r = widget->media->value;
1430  if ((mon.w / (double)mon.h) < r) {
1431  for (unsigned int x = 0; x < widget->num_widgets; x++) {
1433  widget->widgets[x]);
1434  }
1435  }
1436  break;
1437  }
1438  default: {
1439  break;
1440  }
1441  }
1442  }
1443  }
1444 }
1446  workarea mon;
1447  monitor_active(&mon);
1449 }
1450 
1452  if (g_strcmp0(type, "monitor-id") == 0) {
1453  return THEME_MEDIA_TYPE_MON_ID;
1454  }
1455  if (g_strcmp0(type, "min-width") == 0) {
1457  }
1458  if (g_strcmp0(type, "min-height") == 0) {
1460  }
1461  if (g_strcmp0(type, "max-width") == 0) {
1463  }
1464  if (g_strcmp0(type, "max-height") == 0) {
1466  }
1467  if (g_strcmp0(type, "min-aspect-ratio") == 0) {
1469  }
1470  if (g_strcmp0(type, "max-aspect-ratio") == 0) {
1472  }
1473  return THEME_MEDIA_TYPE_INVALID;
1474 }
1475 
1477  const widget *widget,
1478  const char *property) {
1479  if (p) {
1480  if (p->type == P_INHERIT) {
1481  if (widget->parent) {
1482  ThemeWidget *parent =
1484  Property *pp =
1485  rofi_theme_find_property(parent, P_STRING, property, FALSE);
1486  return rofi_theme_has_property_inside(pp, widget->parent, property);
1487  }
1488  return FALSE;
1489  }
1490  return TRUE;
1491  }
1492  return FALSE;
1493 }
1494 gboolean rofi_theme_has_property(const widget *widget, const char *property) {
1496  Property *p = rofi_theme_find_property(wid, P_STRING, property, FALSE);
1497  return rofi_theme_has_property_inside(p, widget, property);
1498 }
@ WL_CENTER
Definition: rofi-types.h:230
@ WL_SOUTH
Definition: rofi-types.h:236
@ WL_WEST
Definition: rofi-types.h:238
@ WL_NORTH
Definition: rofi-types.h:232
@ WL_EAST
Definition: rofi-types.h:234
char * rofi_expand_path(const char *input)
Definition: helper.c:713
uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, const int hsize)
cairo_surface_t * rofi_icon_fetcher_get(const uint32_t uid)
void rofi_add_error_message(GString *str)
Definition: rofi.c:89
double textbox_get_estimated_char_height(void)
Definition: textbox.c:876
double textbox_get_estimated_ch(void)
Definition: textbox.c:890
void rofi_view_get_current_monitor(int *width, int *height)
Definition: view.c:139
struct _widget widget
Definition: widget.h:51
const char *const PropertyTypeName[P_NUM_TYPES]
Definition: rofi-types.c:6
@ ROFI_IMAGE_URL
Definition: rofi-types.h:165
@ ROFI_IMAGE_LINEAR_GRADIENT
Definition: rofi-types.h:165
@ ROFI_DIRECTION_LEFT
Definition: rofi-types.h:168
@ ROFI_DIRECTION_RIGHT
Definition: rofi-types.h:169
@ ROFI_DIRECTION_BOTTOM
Definition: rofi-types.h:171
@ ROFI_DIRECTION_TOP
Definition: rofi-types.h:170
@ ROFI_DIRECTION_ANGLE
Definition: rofi-types.h:172
PropertyType
Definition: rofi-types.h:10
@ P_INTEGER
Definition: rofi-types.h:12
@ P_INHERIT
Definition: rofi-types.h:40
@ P_HIGHLIGHT
Definition: rofi-types.h:32
@ P_LINK
Definition: rofi-types.h:28
@ P_IMAGE
Definition: rofi-types.h:24
@ P_PADDING
Definition: rofi-types.h:26
@ P_LIST
Definition: rofi-types.h:34
@ P_BOOLEAN
Definition: rofi-types.h:20
@ P_COLOR
Definition: rofi-types.h:22
@ P_CURSOR
Definition: rofi-types.h:38
@ P_DOUBLE
Definition: rofi-types.h:14
@ P_ORIENTATION
Definition: rofi-types.h:36
@ P_STRING
Definition: rofi-types.h:16
@ P_POSITION
Definition: rofi-types.h:30
@ ROFI_PU_EM
Definition: rofi-types.h:86
@ ROFI_PU_CH
Definition: rofi-types.h:90
@ ROFI_PU_PX
Definition: rofi-types.h:82
@ ROFI_PU_MM
Definition: rofi-types.h:84
@ ROFI_PU_PERCENT
Definition: rofi-types.h:88
RofiOrientation
Definition: rofi-types.h:134
@ ROFI_ORIENTATION_HORIZONTAL
Definition: rofi-types.h:136
@ ROFI_ORIENTATION_VERTICAL
Definition: rofi-types.h:135
@ ROFI_DISTANCE_MODIFIER_GROUP
Definition: rofi-types.h:103
@ ROFI_DISTANCE_MODIFIER_SUBTRACT
Definition: rofi-types.h:99
@ ROFI_DISTANCE_MODIFIER_MODULO
Definition: rofi-types.h:102
@ ROFI_DISTANCE_MODIFIER_MULTIPLY
Definition: rofi-types.h:101
@ ROFI_DISTANCE_MODIFIER_MAX
Definition: rofi-types.h:105
@ ROFI_DISTANCE_MODIFIER_MIN
Definition: rofi-types.h:104
@ ROFI_DISTANCE_MODIFIER_DIVIDE
Definition: rofi-types.h:100
@ ROFI_DISTANCE_MODIFIER_ADD
Definition: rofi-types.h:98
@ ROFI_DISTANCE_MODIFIER_NONE
Definition: rofi-types.h:97
@ ROFI_HL_SOLID
Definition: rofi-types.h:72
@ ROFI_HL_DASH
Definition: rofi-types.h:74
@ ROFI_SCALE_HEIGHT
Definition: rofi-types.h:178
@ ROFI_SCALE_NONE
Definition: rofi-types.h:176
@ ROFI_SCALE_BOTH
Definition: rofi-types.h:177
@ ROFI_SCALE_WIDTH
Definition: rofi-types.h:179
RofiCursorType
Definition: rofi-types.h:142
@ ROFI_HL_STRIKETHROUGH
Definition: rofi-types.h:60
@ ROFI_HL_ITALIC
Definition: rofi-types.h:64
@ ROFI_HL_UNDERLINE
Definition: rofi-types.h:58
@ ROFI_HL_BOLD
Definition: rofi-types.h:56
@ ROFI_HL_COLOR
Definition: rofi-types.h:66
Settings config
PropertyValue value
Definition: rofi-types.h:290
PropertyType type
Definition: rofi-types.h:288
char * name
Definition: rofi-types.h:286
RofiDistanceModifier modtype
Definition: rofi-types.h:115
RofiPixelUnit type
Definition: rofi-types.h:112
struct RofiDistanceUnit * right
Definition: rofi-types.h:121
struct RofiDistanceUnit * left
Definition: rofi-types.h:118
RofiDistanceUnit base
Definition: rofi-types.h:126
RofiLineStyle style
Definition: rofi-types.h:128
RofiHighlightStyle style
Definition: rofi-types.h:214
RofiDirection dir
Definition: rofi-types.h:189
RofiImageType type
Definition: rofi-types.h:183
double angle
Definition: rofi-types.h:190
uint32_t surface_id
Definition: rofi-types.h:195
char * url
Definition: rofi-types.h:184
RofiScaleType scaling
Definition: rofi-types.h:185
GList * colors
Definition: rofi-types.h:192
RofiDistance bottom
Definition: rofi-types.h:205
RofiDistance top
Definition: rofi-types.h:203
RofiDistance right
Definition: rofi-types.h:204
RofiDistance left
Definition: rofi-types.h:206
int dpi
Definition: settings.h:141
double blue
Definition: rofi-types.h:157
double green
Definition: rofi-types.h:155
double red
Definition: rofi-types.h:153
double alpha
Definition: rofi-types.h:159
struct ThemeWidget ** widgets
Definition: theme.h:73
struct ThemeWidget * parent
Definition: theme.h:79
ThemeMedia * media
Definition: theme.h:75
unsigned int num_widgets
Definition: theme.h:72
char * name
Definition: theme.h:70
GHashTable * properties
Definition: theme.h:77
const char * state
char * name
struct _widget * parent
WidgetType type
Definition: xcb.h:94
int w
Definition: xcb.h:104
int monitor_id
Definition: xcb.h:96
int h
Definition: xcb.h:106
RofiPadding rofi_theme_get_padding(const widget *widget, const char *property, RofiPadding pad)
Definition: theme.c:1142
gboolean rofi_theme_get_image(const widget *widget, const char *property, cairo_t *d)
Definition: theme.c:1107
static void rofi_theme_print_property_index(size_t pnl, int depth, Property *p)
Definition: theme.c:470
const char *const RofiCursorTypeStr[3]
Definition: theme.c:306
static RofiDistanceUnit * rofi_theme_property_copy_distance_unit(RofiDistanceUnit *unit)
Definition: theme.c:88
static int distance_unit_get_pixel(RofiDistanceUnit *unit, RofiOrientation ori)
Definition: theme.c:1235
static void int_rofi_theme_print_property(Property *p)
Definition: theme.c:312
Property * rofi_theme_property_copy(const Property *p)
Definition: theme.c:111
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
Definition: theme.c:830
ThemeWidget * rofi_config_find_widget(const char *name, const char *state, gboolean exact)
Definition: theme.c:732
int rofi_theme_get_boolean(const widget *widget, const char *property, int def)
Definition: theme.c:856
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
Definition: theme.c:1282
FILE * yyin
static RofiHighlightColorStyle rofi_theme_get_highlight_inside(Property *p, widget *widget, const char *property, RofiHighlightColorStyle th)
Definition: theme.c:1184
Property * rofi_theme_find_property(ThemeWidget *widget, PropertyType type, const char *property, gboolean exact)
Definition: theme.c:694
RofiCursorType rofi_theme_get_cursor_type(const widget *widget, const char *property, RofiCursorType def)
Definition: theme.c:913
void yylex_destroy(void)
ThemeWidget * rofi_theme_find_widget(const char *name, const char *state, gboolean exact)
Definition: theme.c:740
static GList * rofi_theme_get_list_inside(Property *p, const widget *widget, const char *property, const char *defaults)
Definition: theme.c:1149
static int rofi_theme_get_integer_inside(Property *p, const widget *widget, const char *property, int def)
Definition: theme.c:774
static RofiDistance rofi_theme_get_distance_inside(Property *p, const widget *widget, const char *property, int def)
Definition: theme.c:799
static gboolean distance_compare(RofiDistance d, RofiDistance e)
Definition: theme.c:50
static void rofi_theme_get_color_inside(const widget *widget, Property *p, const char *property, cairo_t *d)
Definition: theme.c:975
void rofi_theme_parse_process_conditionals(void)
Definition: theme.c:1445
void rofi_theme_get_color(const widget *widget, const char *property, cairo_t *d)
Definition: theme.c:996
RofiHighlightColorStyle rofi_theme_get_highlight(widget *widget, const char *property, RofiHighlightColorStyle th)
Definition: theme.c:1205
static RofiCursorType rofi_theme_get_cursor_type_inside(Property *p, const widget *widget, const char *property, RofiCursorType def)
Definition: theme.c:892
static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit)
Definition: theme.c:244
static void rofi_theme_copy_property_int(G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data)
Definition: theme.c:599
static void rofi_theme_distance_property_free(RofiDistance *distance)
Definition: theme.c:171
RofiOrientation rofi_theme_get_orientation(const widget *widget, const char *property, RofiOrientation def)
Definition: theme.c:884
static void rofi_theme_parse_merge_widgets_no_media(ThemeWidget *parent, ThemeWidget *child)
Definition: theme.c:1323
static int get_pixels(RofiDistanceUnit *unit, RofiOrientation ori)
Definition: theme.c:1212
Property * rofi_theme_property_create(PropertyType type)
Definition: theme.c:81
char * rofi_theme_parse_prepare_file(const char *file, const char *parent_file)
Definition: theme.c:1305
static gpointer rofi_g_list_strdup(gconstpointer data, G_GNUC_UNUSED gpointer user_data)
Definition: theme.c:56
ThemeMediaType rofi_theme_parse_media_type(const char *type)
Definition: theme.c:1451
void rofi_theme_widget_add_properties(ThemeWidget *widget, GHashTable *table)
Definition: theme.c:605
static double rofi_theme_get_double_inside(const widget *orig, Property *p, const widget *widget, const char *property, double def)
Definition: theme.c:947
static RofiOrientation rofi_theme_get_orientation_inside(Property *p, const widget *widget, const char *property, RofiOrientation def)
Definition: theme.c:863
double rofi_theme_get_double(const widget *widget, const char *property, double def)
Definition: theme.c:969
static void rofi_theme_print_distance(RofiDistance d)
Definition: theme.c:293
int rofi_theme_get_integer(const widget *widget, const char *property, int def)
Definition: theme.c:793
void rofi_theme_print(ThemeWidget *widget)
Definition: theme.c:539
static gboolean rofi_theme_has_property_inside(Property *p, const widget *widget, const char *property)
Definition: theme.c:1476
static void printf_double(double d)
Definition: theme.c:238
gboolean rofi_theme_has_property(const widget *widget, const char *property)
Definition: theme.c:1494
void rofi_theme_reset(void)
Definition: theme.c:210
static int rofi_theme_get_position_inside(Property *p, const widget *widget, const char *property, int def)
Definition: theme.c:749
void rofi_theme_parse_merge_widgets(ThemeWidget *parent, ThemeWidget *child)
Definition: theme.c:1339
static void rofi_theme_distance_unit_property_free(RofiDistanceUnit *unit)
Definition: theme.c:160
static ThemeWidget * rofi_theme_find_single(ThemeWidget *widget, const char *name)
Definition: theme.c:621
int yyparse()
GList * rofi_theme_get_list(const widget *widget, const char *property, const char *defaults)
Definition: theme.c:1176
int rofi_theme_get_position(const widget *widget, const char *property, int def)
Definition: theme.c:768
static void rofi_theme_resolve_link_property(Property *p, int depth)
Definition: theme.c:657
static void rofi_theme_parse_process_conditionals_int(workarea mon, ThemeWidget *rwidget)
Definition: theme.c:1359
void rofi_theme_print_index(ThemeWidget *widget, int index)
Definition: theme.c:479
void rofi_theme_free(ThemeWidget *widget)
Definition: theme.c:216
static const char * rofi_theme_get_string_inside(Property *p, const widget *widget, const char *property, const char *def)
Definition: theme.c:920
ThemeWidget * rofi_theme_find_or_create_name(ThemeWidget *base, const char *name)
Definition: theme.c:61
static ThemeWidget * rofi_theme_find(ThemeWidget *widget, const char *name, const gboolean exact)
Definition: theme.c:631
gboolean rofi_theme_is_empty(void)
Definition: theme.c:1295
static int rofi_theme_get_boolean_inside(Property *p, const widget *widget, const char *property, int def)
Definition: theme.c:837
void yyerror(YYLTYPE *yylloc, const char *, const char *)
Definition: theme.c:569
RofiDistance rofi_theme_property_copy_distance(RofiDistance const distance)
Definition: theme.c:99
void rofi_theme_property_free(Property *p)
Definition: theme.c:182
static RofiPadding rofi_theme_get_padding_inside(Property *p, const widget *widget, const char *property, RofiPadding pad)
Definition: theme.c:1113
const char * rofi_theme_get_string(const widget *widget, const char *property, const char *def)
Definition: theme.c:941
static gboolean rofi_theme_get_image_inside(Property *p, const widget *widget, const char *property, cairo_t *d)
Definition: theme.c:1003
void distance_get_linestyle(RofiDistance d, cairo_t *draw)
Definition: theme.c:1286
ThemeMediaType
Definition: theme.h:38
@ THEME_MEDIA_TYPE_MAX_HEIGHT
Definition: theme.h:46
@ THEME_MEDIA_TYPE_MON_ID
Definition: theme.h:48
@ THEME_MEDIA_TYPE_INVALID
Definition: theme.h:54
@ THEME_MEDIA_TYPE_MIN_WIDTH
Definition: theme.h:40
@ THEME_MEDIA_TYPE_MIN_ASPECT_RATIO
Definition: theme.h:50
@ THEME_MEDIA_TYPE_MAX_ASPECT_RATIO
Definition: theme.h:52
@ THEME_MEDIA_TYPE_MAX_WIDTH
Definition: theme.h:42
@ THEME_MEDIA_TYPE_MIN_HEIGHT
Definition: theme.h:44
ThemeWidget * rofi_theme
Definition: theme.h:90
struct _PropertyValue::@6 link
ThemeColor color
Definition: rofi-types.h:261
struct Property * ref
Definition: rofi-types.h:269
RofiHighlightColorStyle highlight
Definition: rofi-types.h:274
struct Property * def_value
Definition: rofi-types.h:271
GList * list
Definition: rofi-types.h:278
RofiImage image
Definition: rofi-types.h:276
gboolean b
Definition: rofi-types.h:259
RofiPadding padding
Definition: rofi-types.h:263
workarea mon
Definition: view.c:111
int monitor_active(workarea *mon)
Definition: xcb.c:937
xcb_depth_t * depth
Definition: xcb.c:93
ThemeWidget * rofi_configuration
Definition: xrmoptions.c:46