rofi  1.6.0
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  if ( unit->right ) {
302  }
303 
304  if ( unit->modtype == ROFI_DISTANCE_MODIFIER_NONE ) {
305  if ( unit->type == ROFI_PU_PX ) {
306  printf ( "%upx ", (unsigned int) unit->distance );
307  }
308  else if ( unit->type == ROFI_PU_MM ) {
309  printf_double ( unit->distance );
310  fputs ( "mm ", stdout );
311  }
312  else if ( unit->type == ROFI_PU_PERCENT ) {
313  printf_double ( unit->distance );
314  fputs ( "% ", stdout );
315  }
316  else if ( unit->type == ROFI_PU_CH ) {
317  printf_double ( unit->distance );
318  fputs ( "ch ", stdout );
319  }
320  else {
321  printf_double ( unit->distance );
322  fputs ( "em ", stdout );
323  }
324  }
325  if ( unit->modtype == ROFI_DISTANCE_MODIFIER_GROUP ) {
326  fputs ( " )", stdout );
327  }
328 }
329 
331 {
333  fputs ( "calc( ", stdout );
334  }
337  fputs ( ")", stdout );
338  }
339  if ( d.style == ROFI_HL_DASH ) {
340  printf ( "dash " );
341  }
342 }
344 const char * const WindowLocationStr[9] = {
345  "center",
346  "northwest",
347  "north",
348  "northeast",
349  "east",
350  "southeast",
351  "south",
352  "southwest",
353  "west"
354 };
355 
357 {
358  switch ( p->type )
359  {
360  case P_LIST:
361  printf ( "[ " );
362  for ( GList *iter = p->value.list; iter != NULL; iter = g_list_next ( iter ) ) {
363  printf ( "%s", (char *) ( iter->data ) );
364  if ( iter->next != NULL ) {
365  printf ( "," );
366  }
367  }
368  printf ( " ]" );
369  break;
370  case P_ORIENTATION:
371  printf ( "%s", ( p->value.i == ROFI_ORIENTATION_HORIZONTAL ) ? "horizontal" : "vertical" );
372  break;
373  case P_HIGHLIGHT:
374  if ( p->value.highlight.style & ROFI_HL_BOLD ) {
375  printf ( "bold " );
376  }
377  if ( p->value.highlight.style & ROFI_HL_UNDERLINE ) {
378  printf ( "underline " );
379  }
381  printf ( "strikethrough " );
382  }
383  if ( p->value.highlight.style & ROFI_HL_ITALIC ) {
384  printf ( "italic " );
385  }
386  if ( p->value.highlight.style & ROFI_HL_COLOR ) {
387  printf ( "rgba ( %.0f, %.0f, %.0f, %.0f %% )",
388  ( p->value.highlight.color.red * 255.0 ),
389  ( p->value.highlight.color.green * 255.0 ),
390  ( p->value.highlight.color.blue * 255.0 ),
391  ( p->value.highlight.color.alpha * 100.0 ) );
392  }
393  break;
394  case P_POSITION:
395  printf ( "%s", WindowLocationStr[p->value.i] );
396  break;
397  case P_STRING:
398  printf ( "\"%s\"", p->value.s );
399  break;
400  case P_INTEGER:
401  printf ( "%d", p->value.i );
402  break;
403  case P_DOUBLE:
404  printf ( "%.2f", p->value.f );
405  break;
406  case P_BOOLEAN:
407  printf ( "%s", p->value.b ? "true" : "false" );
408  break;
409  case P_COLOR:
410  printf ( "rgba ( %.0f, %.0f, %.0f, %.0f %% )",
411  ( p->value.color.red * 255.0 ),
412  ( p->value.color.green * 255.0 ),
413  ( p->value.color.blue * 255.0 ),
414  ( p->value.color.alpha * 100.0 ) );
415  break;
416  case P_PADDING:
421  }
422  else if ( distance_compare ( p->value.padding.top, p->value.padding.bottom ) &&
426  }
427  else if ( !distance_compare ( p->value.padding.top, p->value.padding.bottom ) &&
432  }
433  else {
438  }
439  break;
440  case P_LINK:
441  if ( p->value.link.def_value ) {
442  printf ( "var( %s, ", p->value.link.name );
444  printf ( ")" );
445  }
446  else {
447  printf ( "var(%s)", p->value.link.name );
448  }
449  break;
450  case P_INHERIT:
451  printf ( "inherit" );
452  break;
453  default:
454  break;
455  }
456 }
457 
458 static void rofi_theme_print_property_index ( size_t pnl, int depth, Property *p )
459 {
460  int pl = strlen ( p->name );
461  printf ( "%*s%s:%*s ", depth, "", p->name, (int) pnl - pl, "" );
463  putchar ( ';' );
464  putchar ( '\n' );
465 }
466 
468 {
469  GHashTableIter iter;
470  gpointer key, value;
471  if ( widget->properties ) {
472  int index = 0;
473  GList *list = NULL;
474  ThemeWidget *w = widget;
475  while ( w ) {
476  if ( g_strcmp0 ( w->name, "Root" ) == 0 ) {
477  break;
478  }
479  list = g_list_prepend ( list, w->name );
480  w = w->parent;
481  }
482  if ( g_list_length ( list ) > 0 ) {
483  index = 4;
484  for ( GList *iter = g_list_first ( list ); iter != NULL; iter = g_list_next ( iter ) ) {
485  char *name = (char *) iter->data;
486  fputs ( name, stdout );
487  if ( iter->prev == NULL && iter->next ) {
488  putchar ( ' ' );
489  }
490  else if ( iter->next ) {
491  putchar ( '.' );
492  }
493  }
494  printf ( " {\n" );
495  }
496  else {
497  index = 4;
498  printf ( "* {\n" );
499  }
500  size_t property_name_length = 0;
501  g_hash_table_iter_init ( &iter, widget->properties );
502  while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
503  Property *p = (Property *) value;
504  property_name_length = MAX ( strlen ( p->name ), property_name_length );
505  }
506  g_hash_table_iter_init ( &iter, widget->properties );
507  while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
508  Property *p = (Property *) value;
509  rofi_theme_print_property_index ( property_name_length, index, p );
510  }
511  printf ( "}\n" );
512  g_list_free ( list );
513  }
514  for ( unsigned int i = 0; i < widget->num_widgets; i++ ) {
515  rofi_theme_print_index ( widget->widgets[i] );
516  }
517 }
519 {
520  if ( widget != NULL ) {
521  printf ( "/**\n * rofi -dump-theme output.\n * Rofi version: %s\n **/\n", PACKAGE_VERSION );
523  }
524 }
525 
529 int yyparse ();
530 
534 void yylex_destroy ( void );
535 
539 extern FILE* yyin;
540 
548 void yyerror ( YYLTYPE *yylloc, const char *what, const char* s )
549 {
550  char *what_esc = what ? g_markup_escape_text ( what, -1 ) : g_strdup ( "" );
551  GString *str = g_string_new ( "" );
552  g_string_printf ( str, "<big><b>Error while parsing theme:</b></big> <i>%s</i>\n", what_esc );
553  g_free ( what_esc );
554  char *esc = g_markup_escape_text ( s, -1 );
555  g_string_append_printf ( str, "\tParser error: <span size=\"smaller\" style=\"italic\">%s</span>\n", esc );
556  g_free ( esc );
557  if ( yylloc->filename != NULL ) {
558  g_string_append_printf ( str, "\tLocation: line %d column %d to line %d column %d.\n" \
559  "\tFile '%s'\n", yylloc->first_line, yylloc->first_column, yylloc->last_line, yylloc->last_column, yylloc->filename );
560  }
561  else {
562  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 );
563  }
564  g_log ( "Parser", G_LOG_LEVEL_DEBUG, "Failed to parse theme:\n%s", str->str );
565  rofi_add_error_message ( str );
566 }
567 
568 static void rofi_theme_copy_property_int ( G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data )
569 {
570  GHashTable *table = (GHashTable *) user_data;
571  Property *p = rofi_theme_property_copy ( (Property *) value );
572  g_hash_table_replace ( table, p->name, p );
573 }
575 {
576  if ( table == NULL ) {
577  return;
578  }
579  if ( widget->properties == NULL ) {
580  widget->properties = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify) rofi_theme_property_free );
581  }
582  g_hash_table_foreach ( table, rofi_theme_copy_property_int, widget->properties );
583 }
584 
589 static inline ThemeWidget *rofi_theme_find_single ( ThemeWidget *widget, const char *name )
590 {
591  for ( unsigned int j = 0; widget && j < widget->num_widgets; j++ ) {
592  if ( g_strcmp0 ( widget->widgets[j]->name, name ) == 0 ) {
593  return widget->widgets[j];
594  }
595  }
596  return widget;
597 }
598 
599 static ThemeWidget *rofi_theme_find ( ThemeWidget *widget, const char *name, const gboolean exact )
600 {
601  if ( widget == NULL || name == NULL ) {
602  return widget;
603  }
604  char *tname = g_strdup ( name );
605  char *saveptr = NULL;
606  int found = TRUE;
607  for ( const char *iter = strtok_r ( tname, ".", &saveptr ); iter != NULL; iter = strtok_r ( NULL, ".", &saveptr ) ) {
608  found = FALSE;
610  if ( f != widget ) {
611  widget = f;
612  found = TRUE;
613  }
614  else if ( exact ) {
615  break;
616  }
617  }
618  g_free ( tname );
619  if ( !exact || found ) {
620  return widget;
621  }
622  else {
623  return NULL;
624  }
625 }
626 
628 {
629  // Set name, remove '@' prefix.
630  const char *name = p->value.link.name;// + (*(p->value.link.name)== '@'?1:0;
631  g_info ( "Resolving link to %s", p->value.link.name );
632  if ( depth > 20 ) {
633  g_warning ( "Found more then 20 redirects for property. Stopping." );
634  p->value.link.ref = p;
635  return;
636  }
637 
638  if ( rofi_theme->properties && g_hash_table_contains ( rofi_theme->properties, name ) ) {
639  Property *pr = g_hash_table_lookup ( rofi_theme->properties, name );
640  g_info ( "Resolving link %s found: %s", p->value.link.name, pr->name );
641  if ( pr->type == P_LINK ) {
642  if ( pr->value.link.ref == NULL ) {
644  }
645  if ( pr->value.link.ref != pr ) {
646  p->value.link.ref = pr->value.link.ref;
647  return;
648  }
649  }
650  else {
651  p->value.link.ref = pr;
652  return;
653  }
654  }
655  // No found and we have default value.
656  if ( p->value.link.def_value ) {
657  p->value.link.ref = p->value.link.def_value;
658  return;
659  }
660 
661  // No found, set ref to self.
662  p->value.link.ref = p;
663 }
664 
665 Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, const char *property, gboolean exact )
666 {
667  while ( widget ) {
668  if ( widget->properties && g_hash_table_contains ( widget->properties, property ) ) {
669  Property *p = g_hash_table_lookup ( widget->properties, property );
670  if ( p->type == P_INHERIT ) {
671  return p;
672  }
673  if ( p->type == P_LINK ) {
674  if ( p->value.link.ref == NULL ) {
675  // Resolve link.
677  }
678  if ( p->value.link.ref != NULL && p->value.link.ref->type == type ) {
679  return p->value.link.ref;
680  }
681  }
682  if ( p->type == type ) {
683  return p;
684  }
685  // RofiPadding and integer can be converted.
686  if ( p->type == P_INTEGER && type == P_PADDING ) {
687  return p;
688  }
689  g_debug ( "Found property: '%s' on '%s', but type %s does not match expected type %s.",
690  property, widget->name,
692  PropertyTypeName[type]
693  );
694  }
695  if ( exact ) {
696  return NULL;
697  }
698  // Fall back to defaults.
699  widget = widget->parent;
700  }
701  return NULL;
702 }
703 ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state, gboolean exact )
704 {
705  // First find exact match based on name.
707  widget = rofi_theme_find ( widget, state, exact );
708 
709  return widget;
710 }
711 
712 int rofi_theme_get_position ( const widget *widget, const char *property, int def )
713 {
715  Property *p = rofi_theme_find_property ( wid, P_POSITION, property, FALSE );
716  if ( p ) {
717  if ( p->type == P_INHERIT ) {
718  if ( widget->parent ) {
719  return rofi_theme_get_position ( widget->parent, property, def );
720  }
721  return def;
722  }
723  return p->value.i;
724  }
725  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
726  return def;
727 }
728 
729 int rofi_theme_get_integer ( const widget *widget, const char *property, int def )
730 {
732  Property *p = rofi_theme_find_property ( wid, P_INTEGER, property, FALSE );
733  if ( p ) {
734  if ( p->type == P_INHERIT ) {
735  if ( widget->parent ) {
736  return rofi_theme_get_integer ( widget->parent, property, def );
737  }
738  return def;
739  }
740  return p->value.i;
741  }
742  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
743  return def;
744 }
745 RofiDistance rofi_theme_get_distance ( const widget *widget, const char *property, int def )
746 {
748  Property *p = rofi_theme_find_property ( wid, P_PADDING, property, FALSE );
749  if ( p ) {
750  if ( p->type == P_INHERIT ) {
751  if ( widget->parent ) {
752  return rofi_theme_get_distance ( widget->parent, property, def );
753  }
754  return (RofiDistance){ .base = { def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
755  }
756  if ( p->type == P_INTEGER ) {
757  return (RofiDistance){ .base = { p->value.i, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
758  }
759  else {
760  return p->value.padding.left;
761  }
762  }
763  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
764  return (RofiDistance){ .base = { def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
765 }
766 
767 int rofi_theme_get_boolean ( const widget *widget, const char *property, int def )
768 {
770  Property *p = rofi_theme_find_property ( wid, P_BOOLEAN, property, FALSE );
771  if ( p ) {
772  if ( p->type == P_INHERIT ) {
773  if ( widget->parent ) {
774  return rofi_theme_get_boolean ( widget->parent, property, def );
775  }
776  return def;
777  }
778  return p->value.b;
779  }
780  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
781  return def;
782 }
784 {
786  Property *p = rofi_theme_find_property ( wid, P_ORIENTATION, property, FALSE );
787  if ( p ) {
788  if ( p->type == P_INHERIT ) {
789  if ( widget->parent ) {
790  return rofi_theme_get_orientation ( widget->parent, property, def );
791  }
792  return def;
793  }
794  return p->value.b;
795  }
796  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
797  return def;
798 }
799 
800 const char *rofi_theme_get_string ( const widget *widget, const char *property, const char *def )
801 {
803  Property *p = rofi_theme_find_property ( wid, P_STRING, property, FALSE );
804  if ( p ) {
805  if ( p->type == P_INHERIT ) {
806  if ( widget->parent ) {
807  return rofi_theme_get_string ( widget->parent, property, def );
808  }
809  return def;
810  }
811  return p->value.s;
812  }
813  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
814  return def;
815 }
816 double rofi_theme_get_double ( const widget *widget, const char *property, double def )
817 {
819  Property *p = rofi_theme_find_property ( wid, P_DOUBLE, property, FALSE );
820  if ( p ) {
821  if ( p->type == P_INHERIT ) {
822  if ( widget->parent ) {
823  return rofi_theme_get_double ( widget->parent, property, def );
824  }
825  return def;
826  }
827  return p->value.f;
828  }
829  // Fallback to integer if double is not found.
830  p = rofi_theme_find_property ( wid, P_INTEGER, property, FALSE );
831  if ( p ) {
832  if ( p->type == P_INHERIT ) {
833  if ( widget->parent ) {
834  return rofi_theme_get_double ( widget->parent, property, def );
835  }
836  return def;
837  }
838  return (double) p->value.i;
839  }
840  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
841  return def;
842 }
843 void rofi_theme_get_color ( const widget *widget, const char *property, cairo_t *d )
844 {
846  Property *p = rofi_theme_find_property ( wid, P_COLOR, property, FALSE );
847  if ( p ) {
848  if ( p->type == P_INHERIT ) {
849  if ( widget->parent ) {
850  rofi_theme_get_color ( widget->parent, property, d );
851  }
852  return;
853  }
854  cairo_set_source_rgba ( d,
855  p->value.color.red,
856  p->value.color.green,
857  p->value.color.blue,
858  p->value.color.alpha
859  );
860  }
861  else {
862  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
863  }
864 }
865 RofiPadding rofi_theme_get_padding ( const widget *widget, const char *property, RofiPadding pad )
866 {
868  Property *p = rofi_theme_find_property ( wid, P_PADDING, property, FALSE );
869  if ( p ) {
870  if ( p->type == P_INHERIT ) {
871  if ( widget->parent ) {
872  return rofi_theme_get_padding ( widget->parent, property, pad );
873  }
874  return pad;
875  }
876  if ( p->type == P_PADDING ) {
877  pad = p->value.padding;
878  }
879  else {
880  RofiDistance d = (RofiDistance){ .base = { p->value.i, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL }, .style = ROFI_HL_SOLID };
881  return (RofiPadding){ d, d, d, d };
882  }
883  }
884  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
885  return pad;
886 }
887 
888 GList *rofi_theme_get_list ( const widget *widget, const char * property, const char *defaults )
889 {
891  Property *p = rofi_theme_find_property ( wid2, P_LIST, property, TRUE );
892  if ( p ) {
893  if ( p->type == P_INHERIT ) {
894  if ( widget->parent ) {
895  return rofi_theme_get_list ( widget->parent, property, defaults );
896  }
897  }
898  else if ( p->type == P_LIST ) {
899  return g_list_copy_deep ( p->value.list, rofi_g_list_strdup, NULL );
900  }
901  }
902  char **r = defaults ? g_strsplit ( defaults, ",", 0 ) : NULL;
903  if ( r ) {
904  GList *l = NULL;
905  for ( int i = 0; r[i] != NULL; i++ ) {
906  l = g_list_append ( l, r[i] );
907  }
908  g_free ( r );
909  return l;
910  }
911  return NULL;
912 }
913 
915 {
917  Property *p = rofi_theme_find_property ( wid, P_HIGHLIGHT, property, FALSE );
918  if ( p ) {
919  if ( p->type == P_INHERIT ) {
920  if ( widget->parent ) {
921  return rofi_theme_get_highlight ( widget->parent, property, th );
922  }
923  return th;
924  }
925  return p->value.highlight;
926  }
927  g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
928  return th;
929 }
930 
931 static int get_pixels ( RofiDistanceUnit *unit, RofiOrientation ori )
932 {
933  int val = unit->distance;
934 
935  if ( unit->type == ROFI_PU_EM ) {
937  }
938  else if ( unit->type == ROFI_PU_CH ) {
939  val = unit->distance * textbox_get_estimated_ch ();
940  }
941  else if ( unit->type == ROFI_PU_PERCENT ) {
942  if ( ori == ROFI_ORIENTATION_VERTICAL ) {
943  int height = 0;
944  rofi_view_get_current_monitor ( NULL, &height );
945  val = ( unit->distance * height ) / ( 100.0 );
946  }
947  else {
948  int width = 0;
949  rofi_view_get_current_monitor ( &width, NULL );
950  val = ( unit->distance * width ) / ( 100.0 );
951  }
952  }
953  else if ( unit->type == ROFI_PU_MM ) {
954  val = unit->distance * config.dpi / 25.4;
955  }
956  return val;
957 }
958 
960 {
961  switch ( unit->modtype )
962  {
964  return distance_unit_get_pixel ( unit->left, ori );
965  break;
967  return distance_unit_get_pixel ( unit->left, ori ) + distance_unit_get_pixel ( unit->right, ori );
969  return distance_unit_get_pixel ( unit->left, ori ) - distance_unit_get_pixel ( unit->right, ori );
971  return distance_unit_get_pixel ( unit->left, ori ) * distance_unit_get_pixel ( unit->right, ori );
973  {
974  int a = distance_unit_get_pixel ( unit->left, ori );
975  int b = distance_unit_get_pixel ( unit->right, ori );
976  if ( b != 0 ) {
977  return a / b;
978  }
979  return a;
980  }
982  {
983  int a = distance_unit_get_pixel ( unit->left, ori );
984  int b = distance_unit_get_pixel ( unit->right, ori );
985  if ( b != 0 ) {
986  return a % b;
987  }
988  return 0;
989  }
990  default:
991  break;
992  }
993  return get_pixels ( unit, ori );
994 }
995 
997 {
998  return distance_unit_get_pixel ( &( d.base ), ori );
999 }
1000 
1001 void distance_get_linestyle ( RofiDistance d, cairo_t *draw )
1002 {
1003  if ( d.style == ROFI_HL_DASH ) {
1004  const double dashes[1] = { 4 };
1005  cairo_set_dash ( draw, dashes, 1, 0.0 );
1006  }
1007  else {
1008  cairo_set_dash ( draw, NULL, 0, 0.0 );
1009  }
1010 }
1011 
1012 gboolean rofi_theme_is_empty ( void )
1013 {
1014  if ( rofi_theme == NULL ) {
1015  return TRUE;
1016  }
1017  if ( rofi_theme->properties == NULL && rofi_theme->num_widgets == 0 ) {
1018  return TRUE;
1019  }
1020  if ( rofi_theme->num_widgets == 3 ) {
1021  // HACK: check for default added elements.
1022  for ( unsigned int i = 0; i < rofi_theme->num_widgets; i++ ) {
1023  if ( strncmp ( rofi_theme->widgets[i]->name, "element", 7 ) != 0 ) {
1024  return FALSE;
1025  }
1026  }
1027  return TRUE;
1028  }
1029 
1030  return FALSE;
1031 }
1032 
1033 #ifdef THEME_CONVERTER
1034 
1035 static char * rofi_theme_convert_color ( char *col )
1036 {
1037  char *r = g_strstrip ( col );
1038  if ( *r == '#' && strlen ( r ) == 9 ) {
1039  char a1 = r[1];
1040  char a2 = r[2];
1041  r[1] = r[3];
1042  r[2] = r[4];
1043  r[3] = r[5];
1044  r[4] = r[6];
1045  r[5] = r[7];
1046  r[6] = r[8];
1047  r[7] = a1;
1048  r[8] = a2;
1049  }
1050 
1051  return r;
1052 }
1053 void rofi_theme_convert_old ( void )
1054 {
1055  {
1056  char *str = g_strdup_printf ( "#window { border: %d; padding: %d;}", config.menu_bw, config.padding );
1057  rofi_theme_parse_string ( str );
1058  g_free ( str );
1059  }
1060  if ( config.color_window ) {
1061  char **retv = g_strsplit ( config.color_window, ",", -1 );
1062  const char * const conf[] = {
1063  "* { background: %s; }",
1064  "* { border-color: %s; }",
1065  "* { separatorcolor: %s; }"
1066  };
1067  for ( int i = 0; retv && i < 3 && retv[i]; i++ ) {
1068  char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1069  rofi_theme_parse_string ( str );
1070  g_free ( str );
1071  }
1072  g_strfreev ( retv );
1073  }
1074  if ( config.color_normal ) {
1075  char **retv = g_strsplit ( config.color_normal, ",", -1 );
1076  const char * const conf[] = {
1077  "* { normal-background: %s; }",
1078  "* { foreground: %s; normal-foreground: @foreground; alternate-normal-foreground: @foreground; }",
1079  "* { alternate-normal-background: %s; }",
1080  "* { selected-normal-background: %s; }",
1081  "* { selected-normal-foreground: %s; }"
1082  };
1083  for ( int i = 0; retv && retv[i] && i < 5; i++ ) {
1084  char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1085  rofi_theme_parse_string ( str );
1086  g_free ( str );
1087  }
1088  g_strfreev ( retv );
1089  }
1090  if ( config.color_urgent ) {
1091  char **retv = g_strsplit ( config.color_urgent, ",", -1 );
1092  const char * const conf[] = {
1093  "* { urgent-background: %s; }",
1094  "* { urgent-foreground: %s; alternate-urgent-foreground: @urgent-foreground;}",
1095  "* { alternate-urgent-background: %s; }",
1096  "* { selected-urgent-background: %s; }",
1097  "* { selected-urgent-foreground: %s; }"
1098  };
1099  for ( int i = 0; retv && retv[i] && i < 5; i++ ) {
1100  char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1101  rofi_theme_parse_string ( str );
1102  g_free ( str );
1103  }
1104  g_strfreev ( retv );
1105  }
1106  if ( config.color_active ) {
1107  char **retv = g_strsplit ( config.color_active, ",", -1 );
1108  const char * const conf[] = {
1109  "* { active-background: %s; }",
1110  "* { active-foreground: %s; alternate-active-foreground: @active-foreground;}",
1111  "* { alternate-active-background: %s; }",
1112  "* { selected-active-background: %s; }",
1113  "* { selected-active-foreground: %s; }"
1114  };
1115  for ( int i = 0; retv && retv[i] && i < 5; i++ ) {
1116  char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1117  rofi_theme_parse_string ( str );
1118  g_free ( str );
1119  }
1120  g_strfreev ( retv );
1121  }
1122 
1123  if ( config.separator_style != NULL ) {
1124  if ( g_strcmp0 ( config.separator_style, "none" ) == 0 ) {
1125  const char *const str = "#listview { border: 0px; }";
1126  rofi_theme_parse_string ( str );
1127  const char *const str2 = "#mode-switcher { border: 0px; }";
1128  rofi_theme_parse_string ( str2 );
1129  const char *const str3 = "#message { border: 0px; }";
1130  rofi_theme_parse_string ( str3 );
1131  }
1132  else if ( g_strcmp0 ( config.separator_style, "solid" ) == 0 ) {
1133  const char *const str = "#listview { border: 2px solid 0px 0px 0px; }";
1134  rofi_theme_parse_string ( str );
1135  const char *const str2 = "#mode-switcher { border: 2px solid 0px 0px 0px; }";
1136  rofi_theme_parse_string ( str2 );
1137  const char *const str3 = "#message { border: 2px solid 0px 0px 0px; }";
1138  rofi_theme_parse_string ( str3 );
1139  } /* dash is default */
1140  }
1141  /* Line Margin */
1142  {
1143  char *str = g_strdup_printf ( "#listview { spacing: %dpx;}", config.line_margin );
1144  rofi_theme_parse_string ( str );
1145  g_free ( str );
1146  }
1147  /* Line Padding */
1148  {
1149  char *str = g_strdup_printf ( "#element, inputbar, message { padding: %dpx;}", config.line_padding );
1150  rofi_theme_parse_string ( str );
1151  g_free ( str );
1152  }
1153  if ( config.hide_scrollbar ) {
1154  const char *str = "#listview { scrollbar: false; }";
1155  rofi_theme_parse_string ( str );
1156  }
1157  else {
1158  const char *str = "#listview { scrollbar: true; }";
1159  rofi_theme_parse_string ( str );
1160  char *str2 = g_strdup_printf ( "#scrollbar { handle-width: %dpx; }", config.scrollbar_width );
1161  rofi_theme_parse_string ( str2 );
1162  g_free ( str2 );
1163  }
1164  if ( config.fake_transparency ) {
1165  char *str = g_strdup_printf ( "#window { transparency: \"%s\"; }", config.fake_background );
1166  rofi_theme_parse_string ( str );
1167  g_free ( str );
1168  }
1169 }
1170 #endif // THEME_CONVERTER
1171 
1172 char * rofi_theme_parse_prepare_file ( const char *file, const char *parent_file )
1173 {
1174  char *filename = rofi_expand_path ( file );
1175  // If no absolute path specified, expand it.
1176  if ( parent_file != NULL && !g_path_is_absolute ( filename ) ) {
1177  char *basedir = g_path_get_dirname ( parent_file );
1178  char *path = g_build_filename ( basedir, filename, NULL );
1179  g_free ( filename );
1180  filename = path;
1181  g_free ( basedir );
1182  }
1183  GFile *gf = g_file_new_for_path ( filename );
1184  g_free ( filename );
1185  filename = g_file_get_path ( gf );
1186  g_object_unref ( gf );
1187 
1188  return filename;
1189 }
1190 
1192 {
1193  g_assert ( parent != NULL );
1194  g_assert ( child != NULL );
1195 
1196  if ( parent == rofi_theme && g_strcmp0 ( child->name, "*" ) == 0 ) {
1197  rofi_theme_widget_add_properties ( parent, child->properties );
1198  return;
1199  }
1200 
1201  ThemeWidget *w = rofi_theme_find_or_create_name ( parent, child->name );
1203  for ( unsigned int i = 0; i < child->num_widgets; i++ ) {
1204  rofi_theme_parse_merge_widgets ( w, child->widgets[i] );
1205  }
1206 }
1207 
1209 {
1210  workarea mon;
1211  monitor_active ( &mon );
1212  if ( rofi_theme == NULL ) {
1213  return;
1214  }
1215  for ( unsigned int i = 0; i < rofi_theme->num_widgets; i++ ) {
1217  if ( widget->media != NULL ) {
1218  switch ( widget->media->type )
1219  {
1221  {
1222  int w = widget->media->value;
1223  if ( mon.w >= w ) {
1224  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1226  }
1227  }
1228  break;
1229  }
1231  {
1232  int w = widget->media->value;
1233  if ( mon.w < w ) {
1234  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1236  }
1237  }
1238  break;
1239  }
1241  {
1242  int h = widget->media->value;
1243  if ( mon.h >= h ) {
1244  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1246  }
1247  }
1248  break;
1249  }
1251  {
1252  int h = widget->media->value;
1253  if ( mon.h < h ) {
1254  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1256  }
1257  }
1258  break;
1259  }
1261  {
1262  if ( mon.monitor_id == widget->media->value ) {
1263  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1265  }
1266  }
1267  break;
1268  }
1270  {
1271  double r = widget->media->value;
1272  if ( ( mon.w / (double) mon.h ) >= r ) {
1273  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1275  }
1276  }
1277  break;
1278  }
1280  {
1281  double r = widget->media->value;
1282  if ( ( mon.w / (double) mon.h ) < r ) {
1283  for ( unsigned int x = 0; x < widget->num_widgets; x++ ) {
1285  }
1286  }
1287  break;
1288  }
1289  default:
1290  {
1291  break;
1292  }
1293  }
1294  }
1295  }
1296 }
1297 
1299 {
1300  if ( g_strcmp0 ( type, "monitor-id" ) == 0 ) {
1301  return THEME_MEDIA_TYPE_MON_ID;
1302  }
1303  else if ( g_strcmp0 ( type, "min-width" ) == 0 ) {
1305  }
1306  else if ( g_strcmp0 ( type, "min-height" ) == 0 ) {
1308  }
1309  else if ( g_strcmp0 ( type, "max-width" ) == 0 ) {
1311  }
1312  else if ( g_strcmp0 ( type, "max-height" ) == 0 ) {
1314  }
1315  else if ( g_strcmp0 ( type, "min-aspect-ratio" ) == 0 ) {
1317  }
1318  else if ( g_strcmp0 ( type, "max-aspect-ratio" ) == 0 ) {
1320  }
1321  return THEME_MEDIA_TYPE_INVALID;
1322 }
1323 
1324 gboolean rofi_theme_has_property ( const widget *widget, const char *property )
1325 {
1327  Property *p = rofi_theme_find_property ( wid, P_STRING, property, FALSE );
1328  if ( p ) {
1329  if ( p->type == P_INHERIT ) {
1330  if ( widget->parent ) {
1331  return rofi_theme_has_property ( widget->parent, property );
1332  }
1333  return FALSE;
1334  }
1335  return TRUE;
1336  }
1337  return FALSE;
1338 }
rofi_theme_get_position
int rofi_theme_get_position(const widget *widget, const char *property, int def)
Definition: theme.c:712
get_pixels
static int get_pixels(RofiDistanceUnit *unit, RofiOrientation ori)
Definition: theme.c:931
rofi_theme_get_color
void rofi_theme_get_color(const widget *widget, const char *property, cairo_t *d)
Definition: theme.c:843
rofi_theme_distance_unit_property_free
static void rofi_theme_distance_unit_property_free(RofiDistanceUnit *unit)
Definition: theme.c:144
distance_unit_get_pixel
static int distance_unit_get_pixel(RofiDistanceUnit *unit, RofiOrientation ori)
Definition: theme.c:959
rofi_theme_has_property
gboolean rofi_theme_has_property(const widget *widget, const char *property)
Definition: theme.c:1324
rofi_theme_widget_add_properties
void rofi_theme_widget_add_properties(ThemeWidget *widget, GHashTable *table)
Definition: theme.c:574
yyparse
int yyparse()
P_PADDING
@ P_PADDING
Definition: rofi-types.h:25
ROFI_HL_COLOR
@ ROFI_HL_COLOR
Definition: rofi-types.h:64
depth
xcb_depth_t * depth
Definition: xcb.c:92
PropertyType
PropertyType
Definition: rofi-types.h:11
ThemeColor::green
double green
Definition: rofi-types.h:149
Settings::menu_bw
unsigned int menu_bw
Definition: settings.h:64
rofi_theme_find_property
Property * rofi_theme_find_property(ThemeWidget *widget, PropertyType type, const char *property, gboolean exact)
Definition: theme.c:665
Settings::line_margin
unsigned int line_margin
Definition: settings.h:158
widget
struct _widget widget
Definition: widget.h:51
_PropertyValue::list
GList * list
Definition: rofi-types.h:238
settings.h
rofi_theme_find_or_create_name
ThemeWidget * rofi_theme_find_or_create_name(ThemeWidget *base, const char *name)
Definition: theme.c:59
rofi_theme_parse_prepare_file
char * rofi_theme_parse_prepare_file(const char *file, const char *parent_file)
Definition: theme.c:1172
ROFI_DISTANCE_MODIFIER_DIVIDE
@ ROFI_DISTANCE_MODIFIER_DIVIDE
Definition: rofi-types.h:101
Settings::color_window
char * color_window
Definition: settings.h:78
_PropertyValue::padding
RofiPadding padding
Definition: rofi-types.h:224
RofiDistanceUnit::right
struct RofiDistanceUnit * right
Definition: rofi-types.h:121
textbox_get_estimated_ch
double textbox_get_estimated_ch(void)
Definition: textbox.c:905
ROFI_ORIENTATION_VERTICAL
@ ROFI_ORIENTATION_VERTICAL
Definition: rofi-types.h:137
rofi_theme_distance_property_free
static void rofi_theme_distance_property_free(RofiDistance *distance)
Definition: theme.c:156
THEME_MEDIA_TYPE_MAX_ASPECT_RATIO
@ THEME_MEDIA_TYPE_MAX_ASPECT_RATIO
Definition: theme.h:53
rofi_theme_get_double
double rofi_theme_get_double(const widget *widget, const char *property, double def)
Definition: theme.c:816
RofiDistance::style
RofiLineStyle style
Definition: rofi-types.h:129
rofi_theme_property_copy_distance_unit
static RofiDistanceUnit * rofi_theme_property_copy_distance_unit(RofiDistanceUnit *unit)
Definition: theme.c:85
RofiHighlightColorStyle::color
ThemeColor color
Definition: rofi-types.h:175
_PropertyValue::highlight
RofiHighlightColorStyle highlight
Definition: rofi-types.h:236
P_INTEGER
@ P_INTEGER
Definition: rofi-types.h:13
rofi_theme
ThemeWidget * rofi_theme
ThemeColor::blue
double blue
Definition: rofi-types.h:151
distance_get_pixel
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
Definition: theme.c:996
Settings::color_normal
char * color_normal
Definition: settings.h:75
ThemeMediaType
ThemeMediaType
Definition: theme.h:39
mon
workarea mon
Definition: view.c:112
rofi_theme_get_distance
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
Definition: theme.c:745
THEME_MEDIA_TYPE_MIN_HEIGHT
@ THEME_MEDIA_TYPE_MIN_HEIGHT
Definition: theme.h:45
rofi_theme_get_boolean
int rofi_theme_get_boolean(const widget *widget, const char *property, int def)
Definition: theme.c:767
rofi-types.h
_workarea::monitor_id
int monitor_id
Definition: xcb.h:102
int_rofi_theme_print_property
static void int_rofi_theme_print_property(Property *p)
Definition: theme.c:356
rofi_theme_find
static ThemeWidget * rofi_theme_find(ThemeWidget *widget, const char *name, const gboolean exact)
Definition: theme.c:599
ThemeWidget::widgets
struct ThemeWidget ** widgets
Definition: theme.h:76
_PropertyValue::ref
struct Property * ref
Definition: rofi-types.h:231
rofi_theme_property_free
void rofi_theme_property_free(Property *p)
Definition: theme.c:168
_widget::state
const char * state
Definition: widget-internal.h:98
Settings::separator_style
char * separator_style
Definition: settings.h:163
ROFI_PU_EM
@ ROFI_PU_EM
Definition: rofi-types.h:86
rofi_theme_get_integer
int rofi_theme_get_integer(const widget *widget, const char *property, int def)
Definition: theme.c:729
ThemeColor::red
double red
Definition: rofi-types.h:147
P_HIGHLIGHT
@ P_HIGHLIGHT
Definition: rofi-types.h:31
ROFI_DISTANCE_MODIFIER_NONE
@ ROFI_DISTANCE_MODIFIER_NONE
Definition: rofi-types.h:98
rofi_view_get_current_monitor
void rofi_view_get_current_monitor(int *width, int *height)
Definition: view.c:135
rofi_theme_print_index
static void rofi_theme_print_index(ThemeWidget *widget)
Definition: theme.c:467
P_POSITION
@ P_POSITION
Definition: rofi-types.h:29
rofi_theme_get_orientation
RofiOrientation rofi_theme_get_orientation(const widget *widget, const char *property, RofiOrientation def)
Definition: theme.c:783
PropertyTypeName
const char *const PropertyTypeName[P_NUM_TYPES]
Definition: rofi-types.c:6
_workarea
Definition: xcb.h:100
ThemeMedia
Definition: theme.h:62
_widget::name
char * name
Definition: widget-internal.h:97
Settings::fake_transparency
unsigned int fake_transparency
Definition: settings.h:169
P_LIST
@ P_LIST
Definition: rofi-types.h:33
P_BOOLEAN
@ P_BOOLEAN
Definition: rofi-types.h:21
theme.h
RofiDistanceUnit::modtype
RofiDistanceModifier modtype
Definition: rofi-types.h:115
ROFI_HL_ITALIC
@ ROFI_HL_ITALIC
Definition: rofi-types.h:62
_workarea::h
int h
Definition: xcb.h:112
Settings::padding
unsigned int padding
Definition: settings.h:105
_PropertyValue::def_value
struct Property * def_value
Definition: rofi-types.h:233
ROFI_DISTANCE_MODIFIER_GROUP
@ ROFI_DISTANCE_MODIFIER_GROUP
Definition: rofi-types.h:104
rofi_theme_print
void rofi_theme_print(ThemeWidget *widget)
Definition: theme.c:518
RofiDistance
Definition: rofi-types.h:125
rofi_theme_get_list
GList * rofi_theme_get_list(const widget *widget, const char *property, const char *defaults)
Definition: theme.c:888
THEME_MEDIA_TYPE_MIN_ASPECT_RATIO
@ THEME_MEDIA_TYPE_MIN_ASPECT_RATIO
Definition: theme.h:51
ROFI_HL_UNDERLINE
@ ROFI_HL_UNDERLINE
Definition: rofi-types.h:56
Settings::color_active
char * color_active
Definition: settings.h:76
rofi_g_list_strdup
static gpointer rofi_g_list_strdup(gconstpointer data, G_GNUC_UNUSED gpointer user_data)
Definition: theme.c:54
ROFI_DISTANCE_MODIFIER_ADD
@ ROFI_DISTANCE_MODIFIER_ADD
Definition: rofi-types.h:99
Settings::color_urgent
char * color_urgent
Definition: settings.h:77
RofiDistanceUnit::distance
double distance
Definition: rofi-types.h:110
monitor_active
int monitor_active(workarea *mon)
Definition: xcb.c:751
ROFI_DISTANCE_MODIFIER_SUBTRACT
@ ROFI_DISTANCE_MODIFIER_SUBTRACT
Definition: rofi-types.h:100
rofi_theme_property_copy
Property * rofi_theme_property_copy(Property *p)
Definition: theme.c:109
RofiHighlightColorStyle::style
RofiHighlightStyle style
Definition: rofi-types.h:173
rofi_theme_free
void rofi_theme_free(ThemeWidget *widget)
Definition: theme.c:246
rofi_theme_find_single
static ThemeWidget * rofi_theme_find_single(ThemeWidget *widget, const char *name)
Definition: theme.c:589
rofi_theme_find_widget
ThemeWidget * rofi_theme_find_widget(const char *name, const char *state, gboolean exact)
Definition: theme.c:703
_PropertyValue::name
char * name
Definition: rofi-types.h:229
Property
Definition: rofi-types.h:245
ThemeWidget::parent
struct ThemeWidget * parent
Definition: theme.h:82
P_ORIENTATION
@ P_ORIENTATION
Definition: rofi-types.h:35
THEME_MEDIA_TYPE_MON_ID
@ THEME_MEDIA_TYPE_MON_ID
Definition: theme.h:49
ROFI_PU_MM
@ ROFI_PU_MM
Definition: rofi-types.h:84
RofiPadding
Definition: rofi-types.h:160
_PropertyValue::s
char * s
Definition: rofi-types.h:216
THEME_MEDIA_TYPE_MAX_HEIGHT
@ THEME_MEDIA_TYPE_MAX_HEIGHT
Definition: theme.h:47
yyerror
void yyerror(YYLTYPE *yylloc, const char *, const char *)
Definition: theme.c:548
ROFI_HL_STRIKETHROUGH
@ ROFI_HL_STRIKETHROUGH
Definition: rofi-types.h:58
rofi_theme_parse_string
gboolean rofi_theme_parse_string(const char *string)
_workarea::w
int w
Definition: xcb.h:110
ThemeWidget::num_widgets
unsigned int num_widgets
Definition: theme.h:75
rofi_theme_resolve_link_property
static void rofi_theme_resolve_link_property(Property *p, int depth)
Definition: theme.c:627
_widget::parent
struct _widget * parent
Definition: widget-internal.h:64
rofi_theme_get_padding
RofiPadding rofi_theme_get_padding(const widget *widget, const char *property, RofiPadding pad)
Definition: theme.c:865
rofi_expand_path
char * rofi_expand_path(const char *input)
Definition: helper.c:664
rofi_theme_get_string
const char * rofi_theme_get_string(const widget *widget, const char *property, const char *def)
Definition: theme.c:800
rofi_theme_parse_process_conditionals
void rofi_theme_parse_process_conditionals(void)
Definition: theme.c:1208
P_DOUBLE
@ P_DOUBLE
Definition: rofi-types.h:15
rofi_theme_property_copy_distance
RofiDistance rofi_theme_property_copy_distance(RofiDistance const distance)
Definition: theme.c:97
rofi.h
Property::type
PropertyType type
Definition: rofi-types.h:249
rofi_theme_is_empty
gboolean rofi_theme_is_empty(void)
Definition: theme.c:1012
P_STRING
@ P_STRING
Definition: rofi-types.h:17
rofi_theme_parse_merge_widgets
void rofi_theme_parse_merge_widgets(ThemeWidget *parent, ThemeWidget *child)
Definition: theme.c:1191
rofi_theme_print_property_index
static void rofi_theme_print_property_index(size_t pnl, int depth, Property *p)
Definition: theme.c:458
distance_compare
static gboolean distance_compare(RofiDistance d, RofiDistance e)
Definition: theme.c:48
Settings::hide_scrollbar
unsigned int hide_scrollbar
Definition: settings.h:165
_PropertyValue::i
int i
Definition: rofi-types.h:212
rofi_theme_copy_property_int
static void rofi_theme_copy_property_int(G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data)
Definition: theme.c:568
distance_get_linestyle
void distance_get_linestyle(RofiDistance d, cairo_t *draw)
Definition: theme.c:1001
rofi_add_error_message
void rofi_add_error_message(GString *str)
Definition: rofi.c:90
ROFI_HL_SOLID
@ ROFI_HL_SOLID
Definition: rofi-types.h:71
ThemeColor::alpha
double alpha
Definition: rofi-types.h:153
RofiPadding::right
RofiDistance right
Definition: rofi-types.h:162
rofi_theme_insert_listview_backwards_fix
static void rofi_theme_insert_listview_backwards_fix(void)
Definition: theme.c:195
rofi_theme_print_distance
static void rofi_theme_print_distance(RofiDistance d)
Definition: theme.c:330
printf_double
static void printf_double(double d)
Definition: theme.c:269
_PropertyValue::b
gboolean b
Definition: rofi-types.h:220
Settings::dpi
int dpi
Definition: settings.h:171
ROFI_PU_PERCENT
@ ROFI_PU_PERCENT
Definition: rofi-types.h:88
Settings::scrollbar_width
unsigned int scrollbar_width
Definition: settings.h:175
RofiPadding::left
RofiDistance left
Definition: rofi-types.h:164
Property::value
PropertyValue value
Definition: rofi-types.h:251
Property::name
char * name
Definition: rofi-types.h:247
_PropertyValue::link
struct _PropertyValue::@4 link
rofi_theme_parse_media_type
ThemeMediaType rofi_theme_parse_media_type(const char *type)
Definition: theme.c:1298
RofiPadding::top
RofiDistance top
Definition: rofi-types.h:161
rofi_theme_property_create
Property * rofi_theme_property_create(PropertyType type)
Definition: theme.c:78
yylex_destroy
void yylex_destroy(void)
yyin
FILE * yyin
THEME_MEDIA_TYPE_MIN_WIDTH
@ THEME_MEDIA_TYPE_MIN_WIDTH
Definition: theme.h:41
view.h
rofi_theme_get_highlight
RofiHighlightColorStyle rofi_theme_get_highlight(widget *widget, const char *property, RofiHighlightColorStyle th)
Definition: theme.c:914
P_INHERIT
@ P_INHERIT
Definition: rofi-types.h:37
Settings::line_padding
unsigned int line_padding
Definition: settings.h:159
textbox.h
Settings::fake_background
char * fake_background
Definition: settings.h:177
_PropertyValue::color
ThemeColor color
Definition: rofi-types.h:222
THEME_MEDIA_TYPE_MAX_WIDTH
@ THEME_MEDIA_TYPE_MAX_WIDTH
Definition: theme.h:43
ThemeWidget
Definition: theme.h:71
THEME_MEDIA_TYPE_INVALID
@ THEME_MEDIA_TYPE_INVALID
Definition: theme.h:55
helper.h
ROFI_HL_BOLD
@ ROFI_HL_BOLD
Definition: rofi-types.h:54
RofiPadding::bottom
RofiDistance bottom
Definition: rofi-types.h:163
ROFI_DISTANCE_MODIFIER_MODULO
@ ROFI_DISTANCE_MODIFIER_MODULO
Definition: rofi-types.h:103
config
Settings config
textbox_get_estimated_char_height
double textbox_get_estimated_char_height(void)
Definition: textbox.c:883
rofi_theme_reset
void rofi_theme_reset(void)
Definition: theme.c:237
P_LINK
@ P_LINK
Definition: rofi-types.h:27
RofiHighlightColorStyle
Definition: rofi-types.h:171
_PropertyValue::f
double f
Definition: rofi-types.h:214
ROFI_PU_PX
@ ROFI_PU_PX
Definition: rofi-types.h:82
RofiDistance::base
RofiDistanceUnit base
Definition: rofi-types.h:127
ROFI_ORIENTATION_HORIZONTAL
@ ROFI_ORIENTATION_HORIZONTAL
Definition: rofi-types.h:138
RofiOrientation
RofiOrientation
Definition: rofi-types.h:136
RofiDistanceUnit::type
RofiPixelUnit type
Definition: rofi-types.h:112
P_COLOR
@ P_COLOR
Definition: rofi-types.h:23
_widget
Definition: widget-internal.h:36
ROFI_HL_DASH
@ ROFI_HL_DASH
Definition: rofi-types.h:73
RofiDistanceUnit::left
struct RofiDistanceUnit * left
Definition: rofi-types.h:118
ThemeWidget::properties
GHashTable * properties
Definition: theme.h:80
_widget::type
WidgetType type
Definition: widget-internal.h:38
rofi_theme_print_distance_unit
static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit)
Definition: theme.c:276
WindowLocationStr
const char *const WindowLocationStr[9]
Definition: theme.c:344
RofiDistanceUnit
Definition: rofi-types.h:108
ThemeWidget::name
char * name
Definition: theme.h:73
ROFI_DISTANCE_MODIFIER_MULTIPLY
@ ROFI_DISTANCE_MODIFIER_MULTIPLY
Definition: rofi-types.h:102
ROFI_PU_CH
@ ROFI_PU_CH
Definition: rofi-types.h:90