rofi  1.6.1
theme.c
Go to the documentation of this file.
1 /*
2  * rofi
3  *
4  * MIT/X11 License
5  * Copyright © 2013-2020 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 <stdio.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <string.h>
36 // GFile stuff.
37 #include <gio/gio.h>
38 #include "theme.h"
39 #include "theme-parser.h"
40 #include "helper.h"
41 #include "settings.h"
42 #include "widgets/textbox.h"
43 #include "view.h"
44 #include "rofi.h"
45 #include "rofi-types.h"
46 
47 void yyerror ( YYLTYPE *yylloc, const char *, const char * );
48 static gboolean distance_compare ( RofiDistance d, RofiDistance e )
49 {
50  // TODO UPDATE
51  return d.base.type == e.base.type && d.base.distance == e.base.distance && d.style == e.style;
52 }
53 
54 static gpointer rofi_g_list_strdup ( gconstpointer data, G_GNUC_UNUSED gpointer user_data )
55 {
56  return g_strdup ( data );
57 }
58 
60 {
61  for ( unsigned int i = 0; i < base->num_widgets; i++ ) {
62  if ( g_strcmp0 ( base->widgets[i]->name, name ) == 0 ) {
63  return base->widgets[i];
64  }
65  }
66 
67  base->widgets = g_realloc ( base->widgets, sizeof ( ThemeWidget* ) * ( base->num_widgets + 1 ) );
68  base->widgets[base->num_widgets] = g_slice_new0 ( ThemeWidget );
69  ThemeWidget *retv = base->widgets[base->num_widgets];
70  retv->parent = base;
71  retv->name = g_strdup ( name );
72  base->num_widgets++;
73  return retv;
74 }
79 {
80  Property *retv = g_slice_new0 ( Property );
81  retv->type = type;
82  return retv;
83 }
84 
86 {
87  RofiDistanceUnit *retv = g_slice_new0 ( RofiDistanceUnit );
88  *retv = *unit;
89  if ( unit->left ) {
91  }
92  if ( unit->right ) {
94  }
95  return retv;
96 }
98 {
99  RofiDistance retv = distance;
100  if ( distance.base.left ) {
102  }
103  if ( distance.base.right ) {
105  }
106  return retv;
107 }
108 
110 {
112  retv->name = g_strdup ( p->name );
113 
114  switch ( p->type )
115  {
116  case P_STRING:
117  retv->value.s = g_strdup ( p->value.s );
118  break;
119  case P_LIST:
120  retv->value.list = g_list_copy_deep ( p->value.list, rofi_g_list_strdup, NULL );
121  break;
122  case P_LINK:
123  retv->value.link.name = g_strdup ( p->value.link.name );
124  retv->value.link.ref = NULL;
125  if ( p->value.link.def_value ) {
127  }
128  break;
129  case P_PADDING:
130  {
131  retv->value = p->value;
136  break;
137  }
138  default:
139  retv->value = p->value;
140  }
141  return retv;
142 }
143 
145 {
146  if ( unit->left ) {
148  unit->left = NULL;
149  }
150  if ( unit->right ) {
152  unit->right = NULL;
153  }
154  g_slice_free ( RofiDistanceUnit, unit );
155 }
157 {
158  if ( distance->base.left ) {
160  distance->base.left = NULL;
161  }
162  if ( distance->base.right ) {
164  distance->base.right = NULL;
165  }
166 }
167 
169 {
170  if ( p == NULL ) {
171  return;
172  }
173  g_free ( p->name );
174  if ( p->type == P_STRING ) {
175  g_free ( p->value.s );
176  }
177  else if ( p->type == P_LINK ) {
178  g_free ( p->value.link.name );
179  if ( p->value.link.def_value ) {
181  }
182  }
183  if ( p->type == P_PADDING ) {
188  }
189  g_slice_free ( Property, p );
190 }
191 
196 {
197  GHashTable *table = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify) rofi_theme_property_free );
199  ThemeWidget *tt = rofi_theme_find_or_create_name ( rofi_theme, "element-text" );
200  ThemeWidget *ti = rofi_theme_find_or_create_name ( rofi_theme, "element-icon" );
201 
202  // Inherit text color
204  ptc->name = g_strdup ( "text-color" );
205  g_hash_table_replace ( table, ptc->name, ptc );
206  // Transparent background
208  ptb->name = g_strdup ( "background-color" );
209  ptb->value.color.red = 0.0;
210  ptb->value.color.green = 0.0;
211  ptb->value.color.blue = 0.0;
212  ptb->value.color.alpha = 0.0;
213  g_hash_table_replace ( table, ptb->name, ptb );
214 
215  rofi_theme_widget_add_properties ( tt, table );
216 
217  RofiDistance dsize = (RofiDistance){ .base = { 1.2, ROFI_PU_CH, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
219  pts->value.padding.top = pts->value.padding.right = pts->value.padding.bottom = pts->value.padding.left = dsize;
220  pts->name = g_strdup ( "size" );
221  g_hash_table_replace ( table, pts->name, pts );
222 
223  rofi_theme_widget_add_properties ( ti, table );
224 
226  g_hash_table_destroy ( table );
227  table = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify) rofi_theme_property_free );
229  psp->name = g_strdup ( "spacing" );
230  RofiDistance d = (RofiDistance){ .base = { 5, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
231  psp->value.padding = (RofiPadding){ d, d, d, d };
232  g_hash_table_replace ( table, psp->name, psp );
234  g_hash_table_destroy ( table );
235 }
236 
237 void rofi_theme_reset ( void )
238 {
240  rofi_theme = g_slice_new0 ( ThemeWidget );
241  rofi_theme->name = g_strdup ( "Root" );
242  // Hack to fix backwards compatibility.
244 }
245 
247 {
248  if ( widget == NULL ) {
249  return;
250  }
251  if ( widget->properties ) {
252  g_hash_table_destroy ( widget->properties );
253  widget->properties = NULL;
254  }
255  if ( widget->media ) {
256  g_slice_free ( ThemeMedia, widget->media );
257  }
258  for ( unsigned int i = 0; i < widget->num_widgets; i++ ) {
259  rofi_theme_free ( widget->widgets[i] );
260  }
261  g_free ( widget->widgets );
262  g_free ( widget->name );
263  g_slice_free ( ThemeWidget, widget );
264 }
265 
269 inline static void printf_double ( double d )
270 {
271  char buf[G_ASCII_DTOSTR_BUF_SIZE];
272  g_ascii_formatd ( buf, G_ASCII_DTOSTR_BUF_SIZE, "%.4lf", d );
273  fputs ( buf, stdout );
274 }
275 
277 {
278  if ( unit->modtype == ROFI_DISTANCE_MODIFIER_GROUP ) {
279  fputs ( "( ", stdout );
280  }
281  if ( unit->left ) {
283  }
284 
285  if ( unit->modtype == ROFI_DISTANCE_MODIFIER_ADD ) {
286  fputs ( " + ", stdout );
287  }
288  else if ( unit->modtype == ROFI_DISTANCE_MODIFIER_SUBTRACT ) {
289  fputs ( " - ", stdout );
290  }
291  else if ( unit->modtype == ROFI_DISTANCE_MODIFIER_DIVIDE ) {
292  fputs ( " / ", stdout );
293  }
294  else if ( unit->modtype == ROFI_DISTANCE_MODIFIER_MULTIPLY ) {
295  fputs ( " * ", stdout );
296  }
297  else if ( unit->modtype == ROFI_DISTANCE_MODIFIER_MODULO ) {
298  fputs ( " % ", stdout );
299  }
300  else if ( unit->modtype == ROFI_DISTANCE_MODIFIER_MIN ) {
301  fputs ( " min ", stdout );
302  }
303  else if ( unit->modtype == ROFI_DISTANCE_MODIFIER_MAX ) {
304  fputs ( " max ", stdout );
305  }
306  if ( unit->right ) {
308  }
309 
310  if ( unit->modtype == ROFI_DISTANCE_MODIFIER_NONE ) {
311  if ( unit->type == ROFI_PU_PX ) {
312  printf ( "%upx ", (unsigned int) unit->distance );
313  }
314  else if ( unit->type == ROFI_PU_MM ) {
315  printf_double ( unit->distance );
316  fputs ( "mm ", stdout );
317  }
318  else if ( unit->type == ROFI_PU_PERCENT ) {
319  printf_double ( unit->distance );
320  fputs ( "% ", stdout );
321  }
322  else if ( unit->type == ROFI_PU_CH ) {
323  printf_double ( unit->distance );
324  fputs ( "ch ", stdout );
325  }
326  else {
327  printf_double ( unit->distance );
328  fputs ( "em ", stdout );
329  }
330  }
331  if ( unit->modtype == ROFI_DISTANCE_MODIFIER_GROUP ) {
332  fputs ( " )", stdout );
333  }
334 }
335 
337 {
339  fputs ( "calc( ", stdout );
340  }
343  fputs ( ")", stdout );
344  }
345  if ( d.style == ROFI_HL_DASH ) {
346  printf ( "dash " );
347  }
348 }
350 const char * const WindowLocationStr[9] = {
351  "center",
352  "northwest",
353  "north",
354  "northeast",
355  "east",
356  "southeast",
357  "south",
358  "southwest",
359  "west"
360 };
361 
363 {
364  switch ( p->type )
365  {
366  case P_LIST:
367  printf ( "[ " );
368  for ( GList *iter = p->value.list; iter != NULL; iter = g_list_next ( iter ) ) {
369  printf ( "%s", (char *) ( iter->data ) );
370  if ( iter->next != NULL ) {
371  printf ( "," );
372  }
373  }
374  printf ( " ]" );
375  break;
376  case P_ORIENTATION:
377  printf ( "%s", ( p->value.i == ROFI_ORIENTATION_HORIZONTAL ) ? "horizontal" : "vertical" );
378  break;
379  case P_HIGHLIGHT:
380  if ( p->value.highlight.style & ROFI_HL_BOLD ) {
381  printf ( "bold " );
382  }
383  if ( p->value.highlight.style & ROFI_HL_UNDERLINE ) {
384  printf ( "underline " );
385  }
387  printf ( "strikethrough " );
388  }
389  if ( p->value.highlight.style & ROFI_HL_ITALIC ) {
390  printf ( "italic " );
391  }
392  if ( p->value.highlight.style & ROFI_HL_COLOR ) {
393  printf ( "rgba ( %.0f, %.0f, %.0f, %.0f %% )",
394  ( p->value.highlight.color.red * 255.0 ),
395  ( p->value.highlight.color.green * 255.0 ),
396  ( p->value.highlight.color.blue * 255.0 ),
397  ( p->value.highlight.color.alpha * 100.0 ) );
398  }
399  break;
400  case P_POSITION:
401  printf ( "%s", WindowLocationStr[p->value.i] );
402  break;
403  case P_STRING:
404  printf ( "\"%s\"", p->value.s );
405  break;
406  case P_INTEGER:
407  printf ( "%d", p->value.i );
408  break;
409  case P_DOUBLE:
410  printf ( "%.2f", p->value.f );
411  break;
412  case P_BOOLEAN:
413  printf ( "%s", p->value.b ? "true" : "false" );
414  break;
415  case P_COLOR:
416  printf ( "rgba ( %.0f, %.0f, %.0f, %.0f %% )",
417  ( p->value.color.red * 255.0 ),
418  ( p->value.color.green * 255.0 ),
419  ( p->value.color.blue * 255.0 ),
420  ( p->value.color.alpha * 100.0 ) );
421  break;
422  case P_PADDING:
427  }
428  else if ( distance_compare ( p->value.padding.top, p->value.padding.bottom ) &&
432  }
433  else if ( !distance_compare ( p->value.padding.top, p->value.padding.bottom ) &&
438  }
439  else {
444  }
445  break;
446  case P_LINK:
447  if ( p->value.link.def_value ) {
448  printf ( "var( %s, ", p->value.link.name );
450  printf ( ")" );
451  }
452  else {
453  printf ( "var(%s)", p->value.link.name );
454  }
455  break;
456  case P_INHERIT:
457  printf ( "inherit" );
458  break;
459  default:
460  break;
461  }
462 }
463 
464 static void rofi_theme_print_property_index ( size_t pnl, int depth, Property *p )
465 {
466  int pl = strlen ( p->name );
467  printf ( "%*s%s:%*s ", depth, "", p->name, (int) pnl - pl, "" );
469  putchar ( ';' );
470  putchar ( '\n' );
471 }
472 
473 static void rofi_theme_print_index ( ThemeWidget *widget, int index )
474 {
475  GHashTableIter iter;
476  gpointer key, value;
477 
478  if ( widget->media ) {
479  printf ( "%s {\n", widget->name );
480  for ( unsigned int i = 0; i < widget->num_widgets; i++ ) {
481  rofi_theme_print_index ( widget->widgets[i], index + 4 );
482  }
483  printf ( "}\n" );
484  }
485  else {
486  if ( widget->properties ) {
487  GList *list = NULL;
488  ThemeWidget *w = widget;
489  while ( w ) {
490  if ( g_strcmp0 ( w->name, "Root" ) == 0 ) {
491  break;
492  }
493  if ( w->media ) {
494  break;
495  }
496  list = g_list_prepend ( list, w->name );
497  w = w->parent;
498  }
499  if ( g_list_length ( list ) > 0 ) {
500  printf ( "%*s", index, "" );
501  for ( GList *iter = g_list_first ( list ); iter != NULL; iter = g_list_next ( iter ) ) {
502  char *name = (char *) iter->data;
503  fputs ( name, stdout );
504  if ( iter->prev == NULL && iter->next ) {
505  putchar ( ' ' );
506  }
507  else if ( iter->next ) {
508  putchar ( '.' );
509  }
510  }
511  printf ( " {\n" );
512  }
513  else {
514  printf ( "%*s* {\n", index, "" );
515  }
516  size_t property_name_length = 0;
517  g_hash_table_iter_init ( &iter, widget->properties );
518  while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
519  Property *p = (Property *) value;
520  property_name_length = MAX ( strlen ( p->name ), property_name_length );
521  }
522  g_hash_table_iter_init ( &iter, widget->properties );
523  while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
524  Property *p = (Property *) value;
525  rofi_theme_print_property_index ( property_name_length, index + 4, p );
526  }
527  printf ( "%*s}\n", index, "" );
528  g_list_free ( list );
529  }
530  for ( unsigned int i = 0; i < widget->num_widgets; i++ ) {
531  rofi_theme_print_index ( widget->widgets[i], index );
532  }
533  }
534 }
535 
537 {
538  if ( widget != NULL ) {
539  printf ( "/**\n * rofi -dump-theme output.\n * Rofi version: %s\n **/\n", PACKAGE_VERSION );
541  }
542 }
543 
547 int yyparse ();
548 
552 void yylex_destroy ( void );
553 
557 extern FILE* yyin;
558 
566 void yyerror ( YYLTYPE *yylloc, const char *what, const char* s )
567 {
568  char *what_esc = what ? g_markup_escape_text ( what, -1 ) : g_strdup ( "" );
569  GString *str = g_string_new ( "" );
570  g_string_printf ( str, "<big><b>Error while parsing theme:</b></big> <i>%s</i>\n", what_esc );
571  g_free ( what_esc );
572  char *esc = g_markup_escape_text ( s, -1 );
573  g_string_append_printf ( str, "\tParser error: <span size=\"smaller\" style=\"italic\">%s</span>\n", esc );
574  g_free ( esc );
575  if ( yylloc->filename != NULL ) {
576  g_string_append_printf ( str, "\tLocation: line %d column %d to line %d column %d.\n" \
577  "\tFile '%s'\n", yylloc->first_line, yylloc->first_column, yylloc->last_line, yylloc->last_column, yylloc->filename );
578  }
579  else {
580  g_string_append_printf ( str, "\tLocation: line %d column %d to line %d column %d\n", yylloc->first_line, yylloc->first_column, yylloc->last_line, yylloc->last_column );
581  }
582  g_log ( "Parser", G_LOG_LEVEL_DEBUG, "Failed to parse theme:\n%s", str->str );
583  rofi_add_error_message ( str );
584 }
585 
586 static void rofi_theme_copy_property_int ( G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data )
587 {
588  GHashTable *table = (GHashTable *) user_data;
589  Property *p = rofi_theme_property_copy ( (Property *) value );
590  g_hash_table_replace ( table, p->name, p );
591 }
593 {
594  if ( table == NULL ) {
595  return;
596  }
597  if ( widget->properties == NULL ) {
598  widget->properties = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify) rofi_theme_property_free );
599  }
600  g_hash_table_foreach ( table, rofi_theme_copy_property_int, widget->properties );
601 }
602 
607 static inline ThemeWidget *rofi_theme_find_single ( ThemeWidget *widget, const char *name )
608 {
609  for ( unsigned int j = 0; widget && j < widget->num_widgets; j++ ) {
610  if ( g_strcmp0 ( widget->widgets[j]->name, name ) == 0 ) {
611  return widget->widgets[j];
612  }
613  }
614  return widget;
615 }
616 
617 static ThemeWidget *rofi_theme_find ( ThemeWidget *widget, const char *name, const gboolean exact )
618 {
619  if ( widget == NULL || name == NULL ) {
620  return widget;
621  }
622  char *tname = g_strdup ( name );
623  char *saveptr = NULL;
624  int found = TRUE;
625  for ( const char *iter = strtok_r ( tname, ".", &saveptr ); iter != NULL; iter = strtok_r ( NULL, ".", &saveptr ) ) {
626  found = FALSE;
628  if ( f != widget ) {
629  widget = f;
630  found = TRUE;
631  }
632  else if ( exact ) {
633  break;
634  }
635  }
636  g_free ( tname );
637  if ( !exact || found ) {
638  return widget;
639  }
640  else {
641  return NULL;
642  }
643 }
644 
646 {
647  // Set name, remove '@' prefix.
648  const char *name = p->value.link.name;// + (*(p->value.link.name)== '@'?1:0;
649  g_info ( "Resolving link to %s", p->value.link.name );
650  if ( depth > 20 ) {
651  g_warning ( "Found more then 20 redirects for property. Stopping." );
652  p->value.link.ref = p;
653  return;
654  }
655 
656  if ( rofi_theme->properties && g_hash_table_contains ( rofi_theme->properties, name ) ) {
657  Property *pr = g_hash_table_lookup ( rofi_theme->properties, name );
658  g_info ( "Resolving link %s found: %s", p->value.link.name, pr->name );
659  if ( pr->type == P_LINK ) {
660  if ( pr->value.link.ref == NULL ) {
662  }
663  if ( pr->value.link.ref != pr ) {
664  p->value.link.ref = pr->value.link.ref;
665  return;
666  }
667  }
668  else {
669  p->value.link.ref = pr;
670  return;
671  }
672  }
673  // No found and we have default value.
674  if ( p->value.link.def_value ) {
675  p->value.link.ref = p->value.link.def_value;
676  return;
677  }
678 
679  // No found, set ref to self.
680  p->value.link.ref = p;
681 }
682 
683 Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, const char *property, gboolean exact )
684 {
685  while ( widget ) {
686  if ( widget->properties && g_hash_table_contains ( widget->properties, property ) ) {
687  Property *p = g_hash_table_lookup ( widget->properties, property );
688  if ( p->type == P_INHERIT ) {
689  return p;
690  }
691  if ( p->type == P_LINK ) {
692  if ( p->value.link.ref == NULL ) {
693  // Resolve link.
695  }
696  if ( p->value.link.ref != NULL && p->value.link.ref->type == type ) {
697  return p->value.link.ref;
698  }
699  }
700  if ( p->type == type ) {
701  return p;
702  }
703  // RofiPadding and integer can be converted.
704  if ( p->type == P_INTEGER && type == P_PADDING ) {
705  return p;
706  }
707  g_debug ( "Found property: '%s' on '%s', but type %s does not match expected type %s.",
708  property, widget->name,
710  PropertyTypeName[type]
711  );
712  }
713  if ( exact ) {
714  return NULL;
715  }
716  // Fall back to defaults.
717  widget = widget->parent;
718  }
719  return NULL;
720 }
721 ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state, gboolean exact )
722 {
723  // First find exact match based on name.
725  widget = rofi_theme_find ( widget, state, exact );
726 
727  return widget;
728 }
729 
730 int rofi_theme_get_position ( const widget *widget, const char *property, int def )
731 {
733  Property *p = rofi_theme_find_property ( wid, P_POSITION, property, FALSE );
734  if ( p ) {
735  if ( p->type == P_INHERIT ) {
736  if ( widget->parent ) {
737  return rofi_theme_get_position ( widget->parent, property, def );
738  }
739  return def;
740  }
741  return p->value.i;
742  }
743  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
744  return def;
745 }
746 
747 int rofi_theme_get_integer ( const widget *widget, const char *property, int def )
748 {
750  Property *p = rofi_theme_find_property ( wid, P_INTEGER, property, FALSE );
751  if ( p ) {
752  if ( p->type == P_INHERIT ) {
753  if ( widget->parent ) {
754  return rofi_theme_get_integer ( widget->parent, property, def );
755  }
756  return def;
757  }
758  return p->value.i;
759  }
760  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
761  return def;
762 }
763 RofiDistance rofi_theme_get_distance ( const widget *widget, const char *property, int def )
764 {
766  Property *p = rofi_theme_find_property ( wid, P_PADDING, property, FALSE );
767  if ( p ) {
768  if ( p->type == P_INHERIT ) {
769  if ( widget->parent ) {
770  return rofi_theme_get_distance ( widget->parent, property, def );
771  }
772  return (RofiDistance){ .base = { def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
773  }
774  if ( p->type == P_INTEGER ) {
775  return (RofiDistance){ .base = { p->value.i, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
776  }
777  else {
778  return p->value.padding.left;
779  }
780  }
781  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
782  return (RofiDistance){ .base = { def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
783 }
784 
785 int rofi_theme_get_boolean ( const widget *widget, const char *property, int def )
786 {
788  Property *p = rofi_theme_find_property ( wid, P_BOOLEAN, property, FALSE );
789  if ( p ) {
790  if ( p->type == P_INHERIT ) {
791  if ( widget->parent ) {
792  return rofi_theme_get_boolean ( widget->parent, property, def );
793  }
794  return def;
795  }
796  return p->value.b;
797  }
798  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
799  return def;
800 }
802 {
804  Property *p = rofi_theme_find_property ( wid, P_ORIENTATION, property, FALSE );
805  if ( p ) {
806  if ( p->type == P_INHERIT ) {
807  if ( widget->parent ) {
808  return rofi_theme_get_orientation ( widget->parent, property, def );
809  }
810  return def;
811  }
812  return p->value.b;
813  }
814  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
815  return def;
816 }
817 
818 const char *rofi_theme_get_string ( const widget *widget, const char *property, const char *def )
819 {
821  Property *p = rofi_theme_find_property ( wid, P_STRING, property, FALSE );
822  if ( p ) {
823  if ( p->type == P_INHERIT ) {
824  if ( widget->parent ) {
825  return rofi_theme_get_string ( widget->parent, property, def );
826  }
827  return def;
828  }
829  return p->value.s;
830  }
831  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
832  return def;
833 }
834 double rofi_theme_get_double ( const widget *widget, const char *property, double def )
835 {
837  Property *p = rofi_theme_find_property ( wid, P_DOUBLE, property, FALSE );
838  if ( p ) {
839  if ( p->type == P_INHERIT ) {
840  if ( widget->parent ) {
841  return rofi_theme_get_double ( widget->parent, property, def );
842  }
843  return def;
844  }
845  return p->value.f;
846  }
847  // Fallback to integer if double is not found.
848  p = rofi_theme_find_property ( wid, P_INTEGER, property, FALSE );
849  if ( p ) {
850  if ( p->type == P_INHERIT ) {
851  if ( widget->parent ) {
852  return rofi_theme_get_double ( widget->parent, property, def );
853  }
854  return def;
855  }
856  return (double) p->value.i;
857  }
858  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
859  return def;
860 }
861 void rofi_theme_get_color ( const widget *widget, const char *property, cairo_t *d )
862 {
864  Property *p = rofi_theme_find_property ( wid, P_COLOR, property, FALSE );
865  if ( p ) {
866  if ( p->type == P_INHERIT ) {
867  if ( widget->parent ) {
868  rofi_theme_get_color ( widget->parent, property, d );
869  }
870  return;
871  }
872  cairo_set_source_rgba ( d,
873  p->value.color.red,
874  p->value.color.green,
875  p->value.color.blue,
876  p->value.color.alpha
877  );
878  }
879  else {
880  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
881  }
882 }
883 RofiPadding rofi_theme_get_padding ( const widget *widget, const char *property, RofiPadding pad )
884 {
886  Property *p = rofi_theme_find_property ( wid, P_PADDING, property, FALSE );
887  if ( p ) {
888  if ( p->type == P_INHERIT ) {
889  if ( widget->parent ) {
890  return rofi_theme_get_padding ( widget->parent, property, pad );
891  }
892  return pad;
893  }
894  if ( p->type == P_PADDING ) {
895  pad = p->value.padding;
896  }
897  else {
898  RofiDistance d = (RofiDistance){ .base = { p->value.i, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
899  return (RofiPadding){ d, d, d, d };
900  }
901  }
902  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
903  return pad;
904 }
905 
906 GList *rofi_theme_get_list ( const widget *widget, const char * property, const char *defaults )
907 {
909  Property *p = rofi_theme_find_property ( wid2, P_LIST, property, TRUE );
910  if ( p ) {
911  if ( p->type == P_INHERIT ) {
912  if ( widget->parent ) {
913  return rofi_theme_get_list ( widget->parent, property, defaults );
914  }
915  }
916  else if ( p->type == P_LIST ) {
917  return g_list_copy_deep ( p->value.list, rofi_g_list_strdup, NULL );
918  }
919  }
920  char **r = defaults ? g_strsplit ( defaults, ",", 0 ) : NULL;
921  if ( r ) {
922  GList *l = NULL;
923  for ( int i = 0; r[i] != NULL; i++ ) {
924  l = g_list_append ( l, r[i] );
925  }
926  g_free ( r );
927  return l;
928  }
929  return NULL;
930 }
931 
933 {
935  Property *p = rofi_theme_find_property ( wid, P_HIGHLIGHT, property, FALSE );
936  if ( p ) {
937  if ( p->type == P_INHERIT ) {
938  if ( widget->parent ) {
939  return rofi_theme_get_highlight ( widget->parent, property, th );
940  }
941  return th;
942  }
943  return p->value.highlight;
944  }
945  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
946  return th;
947 }
948 
949 static int get_pixels ( RofiDistanceUnit *unit, RofiOrientation ori )
950 {
951  int val = unit->distance;
952 
953  if ( unit->type == ROFI_PU_EM ) {
955  }
956  else if ( unit->type == ROFI_PU_CH ) {
957  val = unit->distance * textbox_get_estimated_ch ();
958  }
959  else if ( unit->type == ROFI_PU_PERCENT ) {
960  if ( ori == ROFI_ORIENTATION_VERTICAL ) {
961  int height = 0;
962  rofi_view_get_current_monitor ( NULL, &height );
963  val = ( unit->distance * height ) / ( 100.0 );
964  }
965  else {
966  int width = 0;
967  rofi_view_get_current_monitor ( &width, NULL );
968  val = ( unit->distance * width ) / ( 100.0 );
969  }
970  }
971  else if ( unit->type == ROFI_PU_MM ) {
972  val = unit->distance * config.dpi / 25.4;
973  }
974  return val;
975 }
976 
978 {
979  switch ( unit->modtype )
980  {
982  return distance_unit_get_pixel ( unit->left, ori );
983  break;
985  return distance_unit_get_pixel ( unit->left, ori ) + distance_unit_get_pixel ( unit->right, ori );
987  return distance_unit_get_pixel ( unit->left, ori ) - distance_unit_get_pixel ( unit->right, ori );
989  return distance_unit_get_pixel ( unit->left, ori ) * distance_unit_get_pixel ( unit->right, ori );
991  {
992  int a = distance_unit_get_pixel ( unit->left, ori );
993  int b = distance_unit_get_pixel ( unit->right, ori );
994  if ( b != 0 ) {
995  return a / b;
996  }
997  return a;
998  }
1000  {
1001  int a = distance_unit_get_pixel ( unit->left, ori );
1002  int b = distance_unit_get_pixel ( unit->right, ori );
1003  if ( b != 0 ) {
1004  return a % b;
1005  }
1006  return 0;
1007  }
1009  {
1010  int a = distance_unit_get_pixel ( unit->left, ori );
1011  int b = distance_unit_get_pixel ( unit->right, ori );
1012  return MIN ( a, b );
1013  }
1015  {
1016  int a = distance_unit_get_pixel ( unit->left, ori );
1017  int b = distance_unit_get_pixel ( unit->right, ori );
1018  return MAX ( a, b );
1019  }
1020  default:
1021  break;
1022  }
1023  return get_pixels ( unit, ori );
1024 }
1025 
1027 {
1028  return distance_unit_get_pixel ( &( d.base ), ori );
1029 }
1030 
1031 void distance_get_linestyle ( RofiDistance d, cairo_t *draw )
1032 {
1033  if ( d.style == ROFI_HL_DASH ) {
1034  const double dashes[1] = { 4 };
1035  cairo_set_dash ( draw, dashes, 1, 0.0 );
1036  }
1037  else {
1038  cairo_set_dash ( draw, NULL, 0, 0.0 );
1039  }
1040 }
1041 
1042 gboolean rofi_theme_is_empty ( void )
1043 {
1044  if ( rofi_theme == NULL ) {
1045  return TRUE;
1046  }
1047  if ( rofi_theme->properties == NULL && rofi_theme->num_widgets == 0 ) {
1048  return TRUE;
1049  }
1050  if ( rofi_theme->num_widgets == 3 ) {
1051  // HACK: check for default added elements.
1052  for ( unsigned int i = 0; i < rofi_theme->num_widgets; i++ ) {
1053  if ( strncmp ( rofi_theme->widgets[i]->name, "element", 7 ) != 0 ) {
1054  return FALSE;
1055  }
1056  }
1057  return TRUE;
1058  }
1059 
1060  return FALSE;
1061 }
1062 
1063 #ifdef THEME_CONVERTER
1064 
1065 static char * rofi_theme_convert_color ( char *col )
1066 {
1067  char *r = g_strstrip ( col );
1068  if ( *r == '#' && strlen ( r ) == 9 ) {
1069  char a1 = r[1];
1070  char a2 = r[2];
1071  r[1] = r[3];
1072  r[2] = r[4];
1073  r[3] = r[5];
1074  r[4] = r[6];
1075  r[5] = r[7];
1076  r[6] = r[8];
1077  r[7] = a1;
1078  r[8] = a2;
1079  }
1080 
1081  return r;
1082 }
1083 void rofi_theme_convert_old ( void )
1084 {
1085  {
1086  char *str = g_strdup_printf ( "#window { border: %d; padding: %d;}", config.menu_bw, config.padding );
1087  rofi_theme_parse_string ( str );
1088  g_free ( str );
1089  }
1090  if ( config.color_window ) {
1091  char **retv = g_strsplit ( config.color_window, ",", -1 );
1092  const char * const conf[] = {
1093  "* { background: %s; }",
1094  "* { border-color: %s; }",
1095  "* { separatorcolor: %s; }"
1096  };
1097  for ( int i = 0; retv && i < 3 && retv[i]; i++ ) {
1098  char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1099  rofi_theme_parse_string ( str );
1100  g_free ( str );
1101  }
1102  g_strfreev ( retv );
1103  }
1104  if ( config.color_normal ) {
1105  char **retv = g_strsplit ( config.color_normal, ",", -1 );
1106  const char * const conf[] = {
1107  "* { normal-background: %s; }",
1108  "* { foreground: %s; normal-foreground: @foreground; alternate-normal-foreground: @foreground; }",
1109  "* { alternate-normal-background: %s; }",
1110  "* { selected-normal-background: %s; }",
1111  "* { selected-normal-foreground: %s; }"
1112  };
1113  for ( int i = 0; retv && retv[i] && i < 5; i++ ) {
1114  char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1115  rofi_theme_parse_string ( str );
1116  g_free ( str );
1117  }
1118  g_strfreev ( retv );
1119  }
1120  if ( config.color_urgent ) {
1121  char **retv = g_strsplit ( config.color_urgent, ",", -1 );
1122  const char * const conf[] = {
1123  "* { urgent-background: %s; }",
1124  "* { urgent-foreground: %s; alternate-urgent-foreground: @urgent-foreground;}",
1125  "* { alternate-urgent-background: %s; }",
1126  "* { selected-urgent-background: %s; }",
1127  "* { selected-urgent-foreground: %s; }"
1128  };
1129  for ( int i = 0; retv && retv[i] && i < 5; i++ ) {
1130  char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1131  rofi_theme_parse_string ( str );
1132  g_free ( str );
1133  }
1134  g_strfreev ( retv );
1135  }
1136  if ( config.color_active ) {
1137  char **retv = g_strsplit ( config.color_active, ",", -1 );
1138  const char * const conf[] = {
1139  "* { active-background: %s; }",
1140  "* { active-foreground: %s; alternate-active-foreground: @active-foreground;}",
1141  "* { alternate-active-background: %s; }",
1142  "* { selected-active-background: %s; }",
1143  "* { selected-active-foreground: %s; }"
1144  };
1145  for ( int i = 0; retv && retv[i] && i < 5; i++ ) {
1146  char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1147  rofi_theme_parse_string ( str );
1148  g_free ( str );
1149  }
1150  g_strfreev ( retv );
1151  }
1152 
1153  if ( config.separator_style != NULL ) {
1154  if ( g_strcmp0 ( config.separator_style, "none" ) == 0 ) {
1155  const char *const str = "#listview { border: 0px; }";
1156  rofi_theme_parse_string ( str );
1157  const char *const str2 = "#mode-switcher { border: 0px; }";
1158  rofi_theme_parse_string ( str2 );
1159  const char *const str3 = "#message { border: 0px; }";
1160  rofi_theme_parse_string ( str3 );
1161  }
1162  else if ( g_strcmp0 ( config.separator_style, "solid" ) == 0 ) {
1163  const char *const str = "#listview { border: 2px solid 0px 0px 0px; }";
1164  rofi_theme_parse_string ( str );
1165  const char *const str2 = "#mode-switcher { border: 2px solid 0px 0px 0px; }";
1166  rofi_theme_parse_string ( str2 );
1167  const char *const str3 = "#message { border: 2px solid 0px 0px 0px; }";
1168  rofi_theme_parse_string ( str3 );
1169  } /* dash is default */
1170  }
1171  /* Line Margin */
1172  {
1173  char *str = g_strdup_printf ( "#listview { spacing: %dpx;}", config.line_margin );
1174  rofi_theme_parse_string ( str );
1175  g_free ( str );
1176  }
1177  /* Line Padding */
1178  {
1179  char *str = g_strdup_printf ( "#element, inputbar, message { padding: %dpx;}", config.line_padding );
1180  rofi_theme_parse_string ( str );
1181  g_free ( str );
1182  }
1183  if ( config.hide_scrollbar ) {
1184  const char *str = "#listview { scrollbar: false; }";
1185  rofi_theme_parse_string ( str );
1186  }
1187  else {
1188  const char *str = "#listview { scrollbar: true; }";
1189  rofi_theme_parse_string ( str );
1190  char *str2 = g_strdup_printf ( "#scrollbar { handle-width: %dpx; }", config.scrollbar_width );
1191  rofi_theme_parse_string ( str2 );
1192  g_free ( str2 );
1193  }
1194  if ( config.fake_transparency ) {
1195  char *str = g_strdup_printf ( "#window { transparency: \"%s\"; }", config.fake_background );
1196  rofi_theme_parse_string ( str );
1197  g_free ( str );
1198  }
1199 }
1200 #endif // THEME_CONVERTER
1201 
1202 char * rofi_theme_parse_prepare_file ( const char *file, const char *parent_file )
1203 {
1204  char *filename = rofi_expand_path ( file );
1205  // If no absolute path specified, expand it.
1206  if ( parent_file != NULL && !g_path_is_absolute ( filename ) ) {
1207  char *basedir = g_path_get_dirname ( parent_file );
1208  char *path = g_build_filename ( basedir, filename, NULL );
1209  g_free ( filename );
1210  filename = path;
1211  g_free ( basedir );
1212  }
1213  GFile *gf = g_file_new_for_path ( filename );
1214  g_free ( filename );
1215  filename = g_file_get_path ( gf );
1216  g_object_unref ( gf );
1217 
1218  return filename;
1219 }
1220 
1222 {
1223  g_assert ( parent != NULL );
1224  g_assert ( child != NULL );
1225 
1226  if ( parent == rofi_theme && g_strcmp0 ( child->name, "*" ) == 0 ) {
1227  rofi_theme_widget_add_properties ( parent, child->properties );
1228  return;
1229  }
1230 
1231  ThemeWidget *w = rofi_theme_find_or_create_name ( parent, child->name );
1233  for ( unsigned int i = 0; i < child->num_widgets; i++ ) {
1235  }
1236 }
1238 {
1239  g_assert ( parent != NULL );
1240  g_assert ( child != NULL );
1241 
1242  if ( parent == rofi_theme && g_strcmp0 ( child->name, "*" ) == 0 ) {
1243  rofi_theme_widget_add_properties ( parent, child->properties );
1244  return;
1245  }
1246 
1247  ThemeWidget *w = rofi_theme_find_or_create_name ( parent, child->name );
1248  if ( child->media ) {
1249  w->media = g_slice_new0 ( ThemeMedia );
1250  *( w->media ) = *( child->media );
1251  }
1253  for ( unsigned int i = 0; i < child->num_widgets; i++ ) {
1254  rofi_theme_parse_merge_widgets ( w, child->widgets[i] );
1255  }
1256 }
1257 
1259 {
1260  if ( rwidget == NULL ) {
1261  return;
1262  }
1263  for ( unsigned int i = 0; i < rwidget->num_widgets; i++ ) {
1264  ThemeWidget *widget = rwidget->widgets[i];
1266  if ( widget->media != NULL ) {
1267  switch ( widget->media->type )
1268  {
1270  {
1271  int w = widget->media->value;
1272  if ( mon.w >= w ) {
1273  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1275  }
1276  }
1277  break;
1278  }
1280  {
1281  int w = widget->media->value;
1282  if ( mon.w < w ) {
1283  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1285  }
1286  }
1287  break;
1288  }
1290  {
1291  int h = widget->media->value;
1292  if ( mon.h >= h ) {
1293  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1295  }
1296  }
1297  break;
1298  }
1300  {
1301  int h = widget->media->value;
1302  if ( mon.h < h ) {
1303  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1305  }
1306  }
1307  break;
1308  }
1310  {
1311  if ( mon.monitor_id == widget->media->value ) {
1312  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1314  }
1315  }
1316  break;
1317  }
1319  {
1320  double r = widget->media->value;
1321  if ( ( mon.w / (double) mon.h ) >= r ) {
1322  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1324  }
1325  }
1326  break;
1327  }
1329  {
1330  double r = widget->media->value;
1331  if ( ( mon.w / (double) mon.h ) < r ) {
1332  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1334  }
1335  }
1336  break;
1337  }
1338  default:
1339  {
1340  break;
1341  }
1342  }
1343  }
1344  }
1345 }
1347 {
1348  workarea mon;
1349  monitor_active ( &mon );
1351 }
1352 
1354 {
1355  if ( g_strcmp0 ( type, "monitor-id" ) == 0 ) {
1356  return THEME_MEDIA_TYPE_MON_ID;
1357  }
1358  else if ( g_strcmp0 ( type, "min-width" ) == 0 ) {
1360  }
1361  else if ( g_strcmp0 ( type, "min-height" ) == 0 ) {
1363  }
1364  else if ( g_strcmp0 ( type, "max-width" ) == 0 ) {
1366  }
1367  else if ( g_strcmp0 ( type, "max-height" ) == 0 ) {
1369  }
1370  else if ( g_strcmp0 ( type, "min-aspect-ratio" ) == 0 ) {
1372  }
1373  else if ( g_strcmp0 ( type, "max-aspect-ratio" ) == 0 ) {
1375  }
1376  return THEME_MEDIA_TYPE_INVALID;
1377 }
1378 
1379 gboolean rofi_theme_has_property ( const widget *widget, const char *property )
1380 {
1382  Property *p = rofi_theme_find_property ( wid, P_STRING, property, FALSE );
1383  if ( p ) {
1384  if ( p->type == P_INHERIT ) {
1385  if ( widget->parent ) {
1386  return rofi_theme_has_property ( widget->parent, property );
1387  }
1388  return FALSE;
1389  }
1390  return TRUE;
1391  }
1392  return FALSE;
1393 }
char * rofi_expand_path(const char *input)
Definition: helper.c:711
void rofi_add_error_message(GString *str)
Definition: rofi.c:90
double textbox_get_estimated_char_height(void)
Definition: textbox.c:888
double textbox_get_estimated_ch(void)
Definition: textbox.c:906
struct _widget widget
Definition: widget.h:51
const char *const PropertyTypeName[P_NUM_TYPES]
Definition: rofi-types.c:6
PropertyType
Definition: rofi-types.h:11
@ P_INTEGER
Definition: rofi-types.h:13
@ P_INHERIT
Definition: rofi-types.h:37
@ P_HIGHLIGHT
Definition: rofi-types.h:31
@ P_LINK
Definition: rofi-types.h:27
@ P_PADDING
Definition: rofi-types.h:25
@ P_LIST
Definition: rofi-types.h:33
@ P_BOOLEAN
Definition: rofi-types.h:21
@ P_COLOR
Definition: rofi-types.h:23
@ P_DOUBLE
Definition: rofi-types.h:15
@ P_ORIENTATION
Definition: rofi-types.h:35
@ P_STRING
Definition: rofi-types.h:17
@ P_POSITION
Definition: rofi-types.h:29
@ 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:138
@ ROFI_ORIENTATION_HORIZONTAL
Definition: rofi-types.h:140
@ ROFI_ORIENTATION_VERTICAL
Definition: rofi-types.h:139
@ ROFI_DISTANCE_MODIFIER_GROUP
Definition: rofi-types.h:104
@ ROFI_DISTANCE_MODIFIER_SUBTRACT
Definition: rofi-types.h:100
@ ROFI_DISTANCE_MODIFIER_MODULO
Definition: rofi-types.h:103
@ ROFI_DISTANCE_MODIFIER_MULTIPLY
Definition: rofi-types.h:102
@ ROFI_DISTANCE_MODIFIER_MAX
Definition: rofi-types.h:106
@ ROFI_DISTANCE_MODIFIER_MIN
Definition: rofi-types.h:105
@ ROFI_DISTANCE_MODIFIER_DIVIDE
Definition: rofi-types.h:101
@ ROFI_DISTANCE_MODIFIER_ADD
Definition: rofi-types.h:99
@ ROFI_DISTANCE_MODIFIER_NONE
Definition: rofi-types.h:98
@ ROFI_HL_SOLID
Definition: rofi-types.h:71
@ ROFI_HL_DASH
Definition: rofi-types.h:73
@ ROFI_HL_STRIKETHROUGH
Definition: rofi-types.h:58
@ ROFI_HL_ITALIC
Definition: rofi-types.h:62
@ ROFI_HL_UNDERLINE
Definition: rofi-types.h:56
@ ROFI_HL_BOLD
Definition: rofi-types.h:54
@ ROFI_HL_COLOR
Definition: rofi-types.h:64
Settings config
PropertyValue value
Definition: rofi-types.h:253
PropertyType type
Definition: rofi-types.h:251
char * name
Definition: rofi-types.h:249
RofiDistanceModifier modtype
Definition: rofi-types.h:117
RofiPixelUnit type
Definition: rofi-types.h:114
struct RofiDistanceUnit * right
Definition: rofi-types.h:123
struct RofiDistanceUnit * left
Definition: rofi-types.h:120
RofiDistanceUnit base
Definition: rofi-types.h:129
RofiLineStyle style
Definition: rofi-types.h:131
RofiHighlightStyle style
Definition: rofi-types.h:175
RofiDistance bottom
Definition: rofi-types.h:165
RofiDistance top
Definition: rofi-types.h:163
RofiDistance right
Definition: rofi-types.h:164
RofiDistance left
Definition: rofi-types.h:166
unsigned int line_padding
Definition: settings.h:159
unsigned int line_margin
Definition: settings.h:158
char * fake_background
Definition: settings.h:177
unsigned int padding
Definition: settings.h:105
char * color_urgent
Definition: settings.h:77
char * color_normal
Definition: settings.h:75
char * color_window
Definition: settings.h:78
char * separator_style
Definition: settings.h:163
unsigned int scrollbar_width
Definition: settings.h:175
unsigned int hide_scrollbar
Definition: settings.h:165
unsigned int fake_transparency
Definition: settings.h:169
int dpi
Definition: settings.h:171
char * color_active
Definition: settings.h:76
unsigned int menu_bw
Definition: settings.h:64
double blue
Definition: rofi-types.h:153
double green
Definition: rofi-types.h:151
double red
Definition: rofi-types.h:149
double alpha
Definition: rofi-types.h:155
struct ThemeWidget ** widgets
Definition: theme.h:76
struct ThemeWidget * parent
Definition: theme.h:82
ThemeMedia * media
Definition: theme.h:78
unsigned int num_widgets
Definition: theme.h:75
char * name
Definition: theme.h:73
GHashTable * properties
Definition: theme.h:80
const char * state
char * name
struct _widget * parent
WidgetType type
Definition: xcb.h:100
int w
Definition: xcb.h:110
int monitor_id
Definition: xcb.h:102
int h
Definition: xcb.h:112
RofiPadding rofi_theme_get_padding(const widget *widget, const char *property, RofiPadding pad)
Definition: theme.c:883
static void rofi_theme_print_property_index(size_t pnl, int depth, Property *p)
Definition: theme.c:464
static RofiDistanceUnit * rofi_theme_property_copy_distance_unit(RofiDistanceUnit *unit)
Definition: theme.c:85
static int distance_unit_get_pixel(RofiDistanceUnit *unit, RofiOrientation ori)
Definition: theme.c:977
static void int_rofi_theme_print_property(Property *p)
Definition: theme.c:362
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
Definition: theme.c:763
int rofi_theme_get_boolean(const widget *widget, const char *property, int def)
Definition: theme.c:785
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
Definition: theme.c:1026
FILE * yyin
Property * rofi_theme_find_property(ThemeWidget *widget, PropertyType type, const char *property, gboolean exact)
Definition: theme.c:683
void yylex_destroy(void)
ThemeWidget * rofi_theme_find_widget(const char *name, const char *state, gboolean exact)
Definition: theme.c:721
static void rofi_theme_print_index(ThemeWidget *widget, int index)
Definition: theme.c:473
static gboolean distance_compare(RofiDistance d, RofiDistance e)
Definition: theme.c:48
void rofi_theme_parse_process_conditionals(void)
Definition: theme.c:1346
void rofi_theme_get_color(const widget *widget, const char *property, cairo_t *d)
Definition: theme.c:861
RofiHighlightColorStyle rofi_theme_get_highlight(widget *widget, const char *property, RofiHighlightColorStyle th)
Definition: theme.c:932
static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit)
Definition: theme.c:276
static void rofi_theme_copy_property_int(G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data)
Definition: theme.c:586
static void rofi_theme_distance_property_free(RofiDistance *distance)
Definition: theme.c:156
RofiOrientation rofi_theme_get_orientation(const widget *widget, const char *property, RofiOrientation def)
Definition: theme.c:801
static void rofi_theme_parse_merge_widgets_no_media(ThemeWidget *parent, ThemeWidget *child)
Definition: theme.c:1221
static int get_pixels(RofiDistanceUnit *unit, RofiOrientation ori)
Definition: theme.c:949
Property * rofi_theme_property_copy(Property *p)
Definition: theme.c:109
Property * rofi_theme_property_create(PropertyType type)
Definition: theme.c:78
char * rofi_theme_parse_prepare_file(const char *file, const char *parent_file)
Definition: theme.c:1202
static gpointer rofi_g_list_strdup(gconstpointer data, G_GNUC_UNUSED gpointer user_data)
Definition: theme.c:54
ThemeMediaType rofi_theme_parse_media_type(const char *type)
Definition: theme.c:1353
void rofi_theme_widget_add_properties(ThemeWidget *widget, GHashTable *table)
Definition: theme.c:592
double rofi_theme_get_double(const widget *widget, const char *property, double def)
Definition: theme.c:834
static void rofi_theme_print_distance(RofiDistance d)
Definition: theme.c:336
int rofi_theme_get_integer(const widget *widget, const char *property, int def)
Definition: theme.c:747
void rofi_theme_print(ThemeWidget *widget)
Definition: theme.c:536
static void printf_double(double d)
Definition: theme.c:269
gboolean rofi_theme_has_property(const widget *widget, const char *property)
Definition: theme.c:1379
const char *const WindowLocationStr[9]
Definition: theme.c:350
void rofi_theme_reset(void)
Definition: theme.c:237
void rofi_theme_parse_merge_widgets(ThemeWidget *parent, ThemeWidget *child)
Definition: theme.c:1237
static void rofi_theme_distance_unit_property_free(RofiDistanceUnit *unit)
Definition: theme.c:144
static ThemeWidget * rofi_theme_find_single(ThemeWidget *widget, const char *name)
Definition: theme.c:607
int yyparse()
GList * rofi_theme_get_list(const widget *widget, const char *property, const char *defaults)
Definition: theme.c:906
int rofi_theme_get_position(const widget *widget, const char *property, int def)
Definition: theme.c:730
static void rofi_theme_resolve_link_property(Property *p, int depth)
Definition: theme.c:645
static void rofi_theme_parse_process_conditionals_int(workarea mon, ThemeWidget *rwidget)
Definition: theme.c:1258
void rofi_theme_free(ThemeWidget *widget)
Definition: theme.c:246
static void rofi_theme_insert_listview_backwards_fix(void)
Definition: theme.c:195
ThemeWidget * rofi_theme_find_or_create_name(ThemeWidget *base, const char *name)
Definition: theme.c:59
static ThemeWidget * rofi_theme_find(ThemeWidget *widget, const char *name, const gboolean exact)
Definition: theme.c:617
gboolean rofi_theme_is_empty(void)
Definition: theme.c:1042
void yyerror(YYLTYPE *yylloc, const char *, const char *)
Definition: theme.c:566
RofiDistance rofi_theme_property_copy_distance(RofiDistance const distance)
Definition: theme.c:97
void rofi_theme_property_free(Property *p)
Definition: theme.c:168
const char * rofi_theme_get_string(const widget *widget, const char *property, const char *def)
Definition: theme.c:818
void distance_get_linestyle(RofiDistance d, cairo_t *draw)
Definition: theme.c:1031
gboolean rofi_theme_parse_string(const char *string)
ThemeMediaType
Definition: theme.h:39
@ THEME_MEDIA_TYPE_MAX_HEIGHT
Definition: theme.h:47
@ THEME_MEDIA_TYPE_MON_ID
Definition: theme.h:49
@ THEME_MEDIA_TYPE_INVALID
Definition: theme.h:55
@ THEME_MEDIA_TYPE_MIN_WIDTH
Definition: theme.h:41
@ THEME_MEDIA_TYPE_MIN_ASPECT_RATIO
Definition: theme.h:51
@ THEME_MEDIA_TYPE_MAX_ASPECT_RATIO
Definition: theme.h:53
@ THEME_MEDIA_TYPE_MAX_WIDTH
Definition: theme.h:43
@ THEME_MEDIA_TYPE_MIN_HEIGHT
Definition: theme.h:45
ThemeWidget * rofi_theme
ThemeColor color
Definition: rofi-types.h:224
struct Property * ref
Definition: rofi-types.h:233
RofiHighlightColorStyle highlight
Definition: rofi-types.h:238
struct Property * def_value
Definition: rofi-types.h:235
GList * list
Definition: rofi-types.h:240
struct _PropertyValue::@4 link
gboolean b
Definition: rofi-types.h:222
RofiPadding padding
Definition: rofi-types.h:226
workarea mon
Definition: view.c:112
void rofi_view_get_current_monitor(int *width, int *height)
Definition: view.c:135
int monitor_active(workarea *mon)
Definition: xcb.c:750
xcb_depth_t * depth
Definition: xcb.c:91