jay_config/theme.rs
1//! Tools for configuring the look of the compositor.
2
3use crate::_private::WindowThemeKind;
4use crate::theme::colors::Colorable;
5use crate::theme::sized::Resizable;
6use crate::window::Window;
7use jay_proc::PrivateEnum;
8use serde::Deserialize;
9use serde::Serialize;
10use std::ops::Deref;
11
12/// A color.
13///
14/// When specifying RGBA values of a color, the RGB values can either be specified
15/// *straight* or *premultiplied*. Premultiplied means that the RGB values have already
16/// been multiplied by the alpha value.
17///
18/// Given a color, to reduce its opacity by half,
19///
20/// - if you're working with premultiplied values, you would multiply each component by `0.5`;
21/// - if you're working with straight values, you would multiply only the alpha component by `0.5`.
22///
23/// When using hexadecimal notation, `#RRGGBBAA`, the RGB values are usually straight.
24// values are stored premultiplied
25#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
26pub struct Color {
27 r: f32,
28 g: f32,
29 b: f32,
30 a: f32,
31}
32
33fn to_f32(c: u8) -> f32 {
34 c as f32 / 255f32
35}
36
37fn to_u8(c: f32) -> u8 {
38 (c * 255f32) as u8
39}
40
41fn validate_f32(f: f32) -> bool {
42 f >= 0.0 && f <= 1.0
43}
44
45fn validate_f32_all(f: [f32; 4]) -> bool {
46 if !f.into_iter().all(validate_f32) {
47 log::warn!(
48 "f32 values {:?} are not in the valid color range. Using solid black instead xyz",
49 f
50 );
51 return false;
52 }
53 true
54}
55
56impl Color {
57 /// Solid black.
58 pub const BLACK: Self = Self {
59 r: 0.0,
60 g: 0.0,
61 b: 0.0,
62 a: 1.0,
63 };
64
65 /// Creates a new color from `u8` RGB values.
66 pub fn new(r: u8, g: u8, b: u8) -> Self {
67 Self {
68 r: to_f32(r),
69 g: to_f32(g),
70 b: to_f32(b),
71 a: 1.0,
72 }
73 }
74
75 /// Creates a new color from straight `u8` RGBA values.
76 pub fn new_straight(r: u8, g: u8, b: u8, a: u8) -> Self {
77 Self::new_f32_straight(to_f32(r), to_f32(g), to_f32(b), to_f32(a))
78 }
79
80 /// Creates a new color from premultiplied `f32` RGBA values.
81 pub fn new_f32_premultiplied(r: f32, g: f32, b: f32, a: f32) -> Self {
82 if !validate_f32_all([r, g, b, a]) {
83 Self::BLACK
84 } else if r > a || g > a || b > a {
85 log::warn!(
86 "f32 values {:?} are not valid for a premultiplied color. Using solid black instead.",
87 [r, g, b, a]
88 );
89 Self::BLACK
90 } else {
91 Self { r, g, b, a }
92 }
93 }
94
95 /// Creates a new color from straight `f32` RGBA values.
96 pub fn new_f32_straight(r: f32, g: f32, b: f32, a: f32) -> Self {
97 if !validate_f32_all([r, g, b, a]) {
98 Self::BLACK
99 } else {
100 Self {
101 r: r * a,
102 g: g * a,
103 b: b * a,
104 a,
105 }
106 }
107 }
108
109 /// Creates a new color from `f32` RGB values.
110 pub fn new_f32(r: f32, g: f32, b: f32) -> Self {
111 Self { r, g, b, a: 1.0 }
112 }
113
114 /// Converts the color to its premultiplied `f32` RGBA values.
115 pub fn to_f32_premultiplied(&self) -> [f32; 4] {
116 [self.r, self.g, self.b, self.a]
117 }
118
119 /// Converts the color to its straight `f32` RGBA values.
120 pub fn to_f32_straight(&self) -> [f32; 4] {
121 if self.a == 0.0 {
122 [0.0, 0.0, 0.0, 0.0]
123 } else {
124 let a = self.a;
125 [self.r / a, self.g / a, self.b / a, a]
126 }
127 }
128
129 /// Converts the color to its straight `u8` RGBA values.
130 pub fn to_u8_straight(&self) -> [u8; 4] {
131 let [r, g, b, a] = self.to_f32_straight();
132 [to_u8(r), to_u8(g), to_u8(b), to_u8(a)]
133 }
134}
135
136/// Resets all sizes to their defaults.
137pub fn reset_sizes() {
138 get!().reset_sizes();
139}
140
141/// Resets all colors to their defaults.
142pub fn reset_colors() {
143 get!().reset_colors();
144}
145
146/// Returns the current font.
147pub fn get_font() -> String {
148 get!().get_font()
149}
150
151/// Sets the font.
152///
153/// Default: `monospace 8`.
154///
155/// See also [`set_bar_font`] and [`set_title_font`].
156///
157/// The font name should be specified in [pango][pango] syntax.
158///
159/// [pango]: https://docs.gtk.org/Pango/type_func.FontDescription.from_string.html
160pub fn set_font(font: &str) {
161 get!().set_font(font)
162}
163
164/// Sets the font used by the bar.
165///
166/// If this function is not called, the font set by [`set_font`] is used. See that
167/// function for more details.
168pub fn set_bar_font(font: &str) {
169 get!().set_bar_font(font)
170}
171
172/// Sets the font used by window titles.
173///
174/// If this function is not called, the font set by [`set_font`] is used. See that
175/// function for more details.
176pub fn set_title_font(font: &str) {
177 get!().set_title_font(font)
178}
179
180/// Resets the fonts to the defaults.
181///
182/// Currently the default is `monospace 8`.
183pub fn reset_font() {
184 get!().reset_font()
185}
186
187#[non_exhaustive]
188#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Default, PrivateEnum)]
189pub enum BarPosition {
190 #[default]
191 Top,
192 Bottom,
193}
194
195/// Sets the position of the bar.
196///
197/// Default: `Top`.
198pub fn set_bar_position(position: BarPosition) {
199 get!().set_bar_position(position.to_private());
200}
201
202/// Gets the position of the bar.
203pub fn get_bar_position() -> BarPosition {
204 get!(BarPosition::Top).get_bar_position().to_public()
205}
206
207#[non_exhaustive]
208#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Default, PrivateEnum)]
209pub enum ContainerBorders {
210 /// Only separators are drawn between children.
211 #[default]
212 Separators,
213 /// A border is drawn around the entire container.
214 Full,
215 /// A border is drawn around the entire container, in addition to the separators
216 /// between children, unless the container has only one child and is the root
217 /// container of the workspace.
218 FullSmart,
219}
220
221/// Sets the container border style.
222///
223/// Default: `Separators`.
224pub fn set_container_borders(borders: ContainerBorders) {
225 get!().set_container_borders(borders.to_private());
226}
227
228/// Gets the container border style.
229pub fn get_container_borders() -> ContainerBorders {
230 get!(ContainerBorders::Separators)
231 .get_container_borders()
232 .to_public()
233}
234
235/// Sets the proportional fonts used by egui windows.
236///
237/// The default is `["sans-serif", "Noto Sans", "Noto Color Emoji"]`.
238pub fn set_egui_proportional_fonts<'a>(fonts: impl IntoIterator<Item = &'a str>) {
239 get!().set_egui_fonts(Some(fonts.into_iter().collect()), None);
240}
241
242/// Sets the monospace fonts used by egui windows.
243///
244/// The default is `["monospace", "Noto Sans Mono", "Noto Color Emoji"]`.
245pub fn set_egui_monospace_fonts<'a>(fonts: impl IntoIterator<Item = &'a str>) {
246 get!().set_egui_fonts(None, Some(fonts.into_iter().collect()));
247}
248
249/// Sets whether window icons set by the client are shown.
250///
251/// The default is `true`.
252pub fn set_show_window_icons(show: bool) {
253 get!().set_show_window_icons(show);
254}
255
256/// Sets whether window icons set by the client are rendered as grayscale.
257///
258/// This is only supported on the Vulkan renderer.
259///
260/// The default is `false`.
261pub fn set_window_icons_grayscale(grayscale: bool) {
262 get!().set_window_icons_grayscale(grayscale);
263}
264
265/// Theme overrides of a window or container.
266///
267/// This type implements the functionality shared by [`WindowTheme`] and
268/// [`ContainerTheme`]. Both dereference to this type. See their documentation for the
269/// supported settings.
270#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
271pub struct ThemeOverrides {
272 pub(crate) window: Window,
273 pub(crate) kind: WindowThemeKind,
274}
275
276impl ThemeOverrides {
277 /// Returns the window that the overrides belong to.
278 pub fn window(&self) -> Window {
279 self.window
280 }
281
282 /// Removes all overrides.
283 pub fn reset(&self) {
284 get!().reset_window_theme(self.window, self.kind);
285 }
286
287 /// Sets the color of a GUI element.
288 pub fn set_color(&self, element: Colorable, color: Color) {
289 get!().set_window_theme_color(self.window, self.kind, element, Some(color));
290 }
291
292 /// Removes the color override of a GUI element.
293 ///
294 /// See also [`set_color`](Self::set_color).
295 pub fn unset_color(&self, element: Colorable) {
296 get!().set_window_theme_color(self.window, self.kind, element, None);
297 }
298
299 /// Gets the color override of a GUI element.
300 pub fn get_color(&self, element: Colorable) -> Option<Color> {
301 get!().get_window_theme_color(self.window, self.kind, element)
302 }
303
304 /// Sets the size of a GUI element.
305 pub fn set_size(&self, element: Resizable, size: i32) {
306 get!().set_window_theme_size(self.window, self.kind, element, Some(size));
307 }
308
309 /// Removes the size override of a GUI element.
310 ///
311 /// See also [`set_size`](Self::set_size).
312 pub fn unset_size(&self, element: Resizable) {
313 get!().set_window_theme_size(self.window, self.kind, element, None);
314 }
315
316 /// Gets the size override of a GUI element.
317 pub fn get_size(&self, element: Resizable) -> Option<i32> {
318 get!().get_window_theme_size(self.window, self.kind, element)
319 }
320
321 /// Sets whether titles are shown.
322 ///
323 /// See also [`set_show_titles`](crate::set_show_titles).
324 pub fn set_show_titles(&self, show: bool) {
325 get!().set_window_theme_show_titles(self.window, self.kind, Some(show));
326 }
327
328 /// Removes the override of whether titles are shown.
329 ///
330 /// See also [`set_show_titles`](Self::set_show_titles).
331 pub fn unset_show_titles(&self) {
332 get!().set_window_theme_show_titles(self.window, self.kind, None);
333 }
334
335 /// Gets the override of whether titles are shown.
336 pub fn get_show_titles(&self) -> Option<bool> {
337 get!().get_window_theme_show_titles(self.window, self.kind)
338 }
339
340 /// Sets whether window icons set by the client are shown.
341 ///
342 /// See also [`set_show_window_icons`].
343 pub fn set_show_window_icons(&self, show: bool) {
344 get!().set_window_theme_show_window_icons(self.window, self.kind, Some(show));
345 }
346
347 /// Removes the override of whether window icons set by the client are shown.
348 ///
349 /// See also [`set_show_window_icons`](Self::set_show_window_icons).
350 pub fn unset_show_window_icons(&self) {
351 get!().set_window_theme_show_window_icons(self.window, self.kind, None);
352 }
353
354 /// Sets whether window icons set by the client are rendered as grayscale.
355 ///
356 /// See also [`set_window_icons_grayscale`].
357 pub fn set_window_icons_grayscale(&self, grayscale: bool) {
358 get!().set_window_theme_window_icons_grayscale(self.window, self.kind, Some(grayscale));
359 }
360
361 /// Removes the override of whether window icons set by the client are rendered as
362 /// grayscale.
363 ///
364 /// See also [`set_window_icons_grayscale`](Self::set_window_icons_grayscale).
365 pub fn unset_window_icons_grayscale(&self) {
366 get!().set_window_theme_window_icons_grayscale(self.window, self.kind, None);
367 }
368
369 /// Sets the font used by window titles.
370 ///
371 /// See also [`set_title_font`].
372 pub fn set_title_font(&self, font: &str) {
373 get!().set_window_theme_title_font(self.window, self.kind, Some(font));
374 }
375
376 /// Removes the override of the font used by window titles.
377 ///
378 /// See also [`set_title_font`](Self::set_title_font).
379 pub fn unset_title_font(&self) {
380 get!().set_window_theme_title_font(self.window, self.kind, None);
381 }
382}
383
384/// Theme overrides of a window.
385///
386/// This object is returned by [`Window::theme`]. It contains the theme of the window
387/// itself. How a container decorates its children is configured with
388/// [`ContainerTheme`].
389///
390/// Settings that are not set fall back to the theme of the parent container, if any, and
391/// then to the global theme. Not every setting has an effect on every window.
392#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
393pub struct WindowTheme(pub(crate) ThemeOverrides);
394
395impl Deref for WindowTheme {
396 type Target = ThemeOverrides;
397
398 fn deref(&self) -> &Self::Target {
399 &self.0
400 }
401}
402
403const _: () = {
404 use colors::*;
405 use sized::*;
406
407 impl WindowTheme {
408 /// Sets the color of a GUI element.
409 ///
410 /// Floating windows use the following elements. This theme takes priority over the
411 /// global theme.
412 ///
413 /// - [`BORDER_COLOR`]
414 /// - [`FOCUSED_BORDER_COLOR`]
415 /// - [`SEPARATOR_COLOR`]
416 /// - [`UNFOCUSED_TITLE_BACKGROUND_COLOR`]
417 /// - [`FOCUSED_TITLE_BACKGROUND_COLOR`]
418 /// - [`ATTENTION_REQUESTED_BACKGROUND_COLOR`]
419 /// - [`UNFOCUSED_TITLE_TEXT_COLOR`]
420 /// - [`FOCUSED_TITLE_TEXT_COLOR`]
421 ///
422 /// Tiled windows use the following elements. This theme takes priority over the
423 /// [`ContainerTheme`] of the parent container, which takes priority over the global
424 /// theme.
425 ///
426 /// - [`FOCUSED_BORDER_COLOR`]
427 /// - [`BORDER_COLOR`]: only used as the default of `FOCUSED_BORDER_COLOR`. The
428 /// other borders use the border color of the container.
429 /// - [`UNFOCUSED_TITLE_BACKGROUND_COLOR`]
430 /// - [`FOCUSED_TITLE_BACKGROUND_COLOR`]
431 /// - [`FOCUSED_INACTIVE_TITLE_BACKGROUND_COLOR`]
432 /// - [`ATTENTION_REQUESTED_BACKGROUND_COLOR`]
433 /// - [`UNFOCUSED_TITLE_TEXT_COLOR`]
434 /// - [`FOCUSED_TITLE_TEXT_COLOR`]
435 /// - [`FOCUSED_INACTIVE_TITLE_TEXT_COLOR`]
436 ///
437 /// For tiled windows, the separator color is a property of the container and is set
438 /// with [`ContainerTheme::set_color`].
439 pub fn set_color(&self, element: Colorable, color: Color) {
440 self.0.set_color(element, color)
441 }
442
443 /// Sets the size of a GUI element.
444 ///
445 /// The following elements are supported:
446 ///
447 /// - [`TITLE_HEIGHT`]
448 /// - [`BORDER_WIDTH`]
449 ///
450 /// They are only used for floating windows. This theme takes priority over the
451 /// global theme. For tiled windows, these sizes are properties of the container and
452 /// are set with [`ContainerTheme::set_size`].
453 pub fn set_size(&self, element: Resizable, size: i32) {
454 self.0.set_size(element, size)
455 }
456
457 /// Sets whether titles are shown.
458 ///
459 /// This is only used for floating windows. This theme takes priority over the global
460 /// theme. For tiled windows, this is a property of the container and is set with
461 /// [`ContainerTheme::set_show_titles`].
462 ///
463 /// See also [`set_show_titles`](crate::set_show_titles).
464 pub fn set_show_titles(&self, show: bool) {
465 self.0.set_show_titles(show)
466 }
467
468 /// Sets whether window icons set by the client are shown.
469 ///
470 /// For floating windows, this theme takes priority over the global theme. For tiled
471 /// windows, this theme takes priority over the [`ContainerTheme`] of the parent
472 /// container, which takes priority over the global theme.
473 ///
474 /// See also [`set_show_window_icons`].
475 pub fn set_show_window_icons(&self, show: bool) {
476 self.0.set_show_window_icons(show)
477 }
478
479 /// Sets whether window icons set by the client are rendered as grayscale.
480 ///
481 /// For floating windows, this theme takes priority over the global theme. For tiled
482 /// windows, this theme takes priority over the [`ContainerTheme`] of the parent
483 /// container, which takes priority over the global theme.
484 ///
485 /// See also [`set_window_icons_grayscale`].
486 pub fn set_window_icons_grayscale(&self, grayscale: bool) {
487 self.0.set_window_icons_grayscale(grayscale)
488 }
489
490 /// Sets the font used by window titles.
491 ///
492 /// For floating windows, this theme takes priority over the global theme. For tiled
493 /// windows, this theme takes priority over the [`ContainerTheme`] of the parent
494 /// container, which takes priority over the global theme.
495 ///
496 /// See also [`set_title_font`].
497 pub fn set_title_font(&self, font: &str) {
498 self.0.set_title_font(font)
499 }
500 }
501};
502
503/// Theme overrides of how a container decorates its children.
504///
505/// This object is returned by [`Window::container_theme`]. It has no effect if the
506/// window is not a container.
507///
508/// Settings that are not set fall back to the global theme. Not every setting has an
509/// effect on every container.
510#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
511pub struct ContainerTheme(pub(crate) ThemeOverrides);
512
513impl Deref for ContainerTheme {
514 type Target = ThemeOverrides;
515
516 fn deref(&self) -> &Self::Target {
517 &self.0
518 }
519}
520
521const _: () = {
522 use colors::*;
523 use sized::*;
524
525 impl ContainerTheme {
526 /// Sets the color of a GUI element.
527 ///
528 /// The following elements apply to the container as a whole. This theme takes
529 /// priority over the global theme.
530 ///
531 /// - [`BORDER_COLOR`]
532 /// - [`SEPARATOR_COLOR`]
533 ///
534 /// The following elements apply to the decorations of each child. The
535 /// [`WindowTheme`] of the child takes priority over this theme, which takes priority
536 /// over the global theme.
537 ///
538 /// - [`FOCUSED_BORDER_COLOR`]
539 /// - [`BORDER_COLOR`]: only used as the default of `FOCUSED_BORDER_COLOR`.
540 /// - [`UNFOCUSED_TITLE_BACKGROUND_COLOR`]
541 /// - [`FOCUSED_TITLE_BACKGROUND_COLOR`]
542 /// - [`FOCUSED_INACTIVE_TITLE_BACKGROUND_COLOR`]
543 /// - [`ATTENTION_REQUESTED_BACKGROUND_COLOR`]
544 /// - [`UNFOCUSED_TITLE_TEXT_COLOR`]
545 /// - [`FOCUSED_TITLE_TEXT_COLOR`]
546 /// - [`FOCUSED_INACTIVE_TITLE_TEXT_COLOR`]
547 pub fn set_color(&self, element: Colorable, color: Color) {
548 self.0.set_color(element, color)
549 }
550
551 /// Sets the size of a GUI element.
552 ///
553 /// The following elements are supported:
554 ///
555 /// - [`TITLE_HEIGHT`]
556 /// - [`BORDER_WIDTH`]
557 ///
558 /// They apply to the container as a whole. This theme takes priority over the global
559 /// theme.
560 pub fn set_size(&self, element: Resizable, size: i32) {
561 self.0.set_size(element, size)
562 }
563
564 /// Sets whether titles are shown.
565 ///
566 /// This applies to the container as a whole. This theme takes priority over the
567 /// global theme.
568 ///
569 /// See also [`set_show_titles`](crate::set_show_titles).
570 pub fn set_show_titles(&self, show: bool) {
571 self.0.set_show_titles(show)
572 }
573
574 /// Sets whether window icons set by the client are shown.
575 ///
576 /// This applies to the decorations of each child. The [`WindowTheme`] of the child
577 /// takes priority over this theme, which takes priority over the global theme.
578 ///
579 /// See also [`set_show_window_icons`].
580 pub fn set_show_window_icons(&self, show: bool) {
581 self.0.set_show_window_icons(show)
582 }
583
584 /// Sets whether window icons set by the client are rendered as grayscale.
585 ///
586 /// This applies to the decorations of each child. The [`WindowTheme`] of the child
587 /// takes priority over this theme, which takes priority over the global theme.
588 ///
589 /// See also [`set_window_icons_grayscale`].
590 pub fn set_window_icons_grayscale(&self, grayscale: bool) {
591 self.0.set_window_icons_grayscale(grayscale)
592 }
593
594 /// Sets the font used by window titles.
595 ///
596 /// This applies to the decorations of each child. The [`WindowTheme`] of the child
597 /// takes priority over this theme, which takes priority over the global theme.
598 ///
599 /// See also [`set_title_font`].
600 pub fn set_title_font(&self, font: &str) {
601 self.0.set_title_font(font)
602 }
603
604 /// Sets the container border style.
605 ///
606 /// This theme takes priority over the global theme.
607 ///
608 /// See also [`set_container_borders`].
609 pub fn set_container_borders(&self, borders: ContainerBorders) {
610 get!().set_window_theme_container_borders(
611 self.0.window,
612 self.0.kind,
613 Some(borders.to_private()),
614 );
615 }
616
617 /// Removes the override of the container border style.
618 ///
619 /// See also [`set_container_borders`](Self::set_container_borders).
620 pub fn unset_container_borders(&self) {
621 get!().set_window_theme_container_borders(self.0.window, self.0.kind, None);
622 }
623
624 /// Gets the override of the container border style.
625 pub fn get_container_borders(&self) -> Option<ContainerBorders> {
626 get!(None)
627 .get_window_theme_container_borders(self.0.window, self.0.kind)
628 .map(|v| v.to_public())
629 }
630 }
631};
632
633/// Elements of the compositor whose color can be changed.
634pub mod colors {
635 #![allow(unused_imports)]
636 use crate::theme::Color;
637 use crate::theme::ContainerBorders;
638 use serde::Deserialize;
639 use serde::Serialize;
640
641 /// An element of the GUI whose color can be changed.
642 #[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
643 pub struct Colorable(#[doc(hidden)] pub u32);
644
645 impl Colorable {
646 /// Sets the color to an RGB value.
647 pub fn set(self, r: u8, g: u8, b: u8) {
648 let color = Color::new(r, g, b);
649 get!().set_color(self, color);
650 }
651
652 /// Sets the color to a `Color` that might contain an alpha component.
653 pub fn set_color(self, color: Color) {
654 get!().set_color(self, color);
655 }
656
657 /// Gets the current color.
658 pub fn get(self) -> Color {
659 get!(Color::BLACK).get_color(self)
660 }
661 }
662
663 macro_rules! colors {
664 ($($(#[$attr:meta])* const $n:expr => $name:ident,)*) => {
665 $(
666 $(#[$attr])*
667 pub const $name: Colorable = Colorable($n);
668 )*
669 }
670 }
671
672 colors! {
673 /// The title background color of an unfocused window.
674 ///
675 /// Default: `#222222`.
676 const 01 => UNFOCUSED_TITLE_BACKGROUND_COLOR,
677 /// The title background color of a focused window.
678 ///
679 /// Default: `#285577`.
680 const 02 => FOCUSED_TITLE_BACKGROUND_COLOR,
681 /// The title background color of an unfocused window that was the last focused
682 /// window in its container.
683 ///
684 /// Default: `#5f676a`.
685 const 03 => FOCUSED_INACTIVE_TITLE_BACKGROUND_COLOR,
686 /// The background color of the desktop.
687 ///
688 /// Default: `#001019`.
689 ///
690 /// You can use an application such as [swaybg][swaybg] to further customize the background.
691 ///
692 /// [swaybg]: https://github.com/swaywm/swaybg
693 const 04 => BACKGROUND_COLOR,
694 /// The background color of the bar.
695 ///
696 /// Default: `#000000`.
697 const 05 => BAR_BACKGROUND_COLOR,
698 /// The color of the 1px separator below window titles.
699 ///
700 /// Default: `#333333`.
701 const 06 => SEPARATOR_COLOR,
702 /// The color of the border between windows.
703 ///
704 /// Default: `#3f474a`.
705 const 07 => BORDER_COLOR,
706 /// The title text color of an unfocused window.
707 ///
708 /// Default: `#888888`.
709 const 08 => UNFOCUSED_TITLE_TEXT_COLOR,
710 /// The title text color of a focused window.
711 ///
712 /// Default: `#ffffff`.
713 const 09 => FOCUSED_TITLE_TEXT_COLOR,
714 /// The title text color of an unfocused window that was the last focused
715 /// window in its container.
716 ///
717 /// Default: `#ffffff`.
718 const 10 => FOCUSED_INACTIVE_TITLE_TEXT_COLOR,
719 /// The color of the status text in the bar.
720 ///
721 /// Default: `#ffffff`.
722 const 11 => BAR_STATUS_TEXT_COLOR,
723 /// The title background color of an unfocused window that might be captured.
724 ///
725 /// Default: `#220303`.
726 const 12 => CAPTURED_UNFOCUSED_TITLE_BACKGROUND_COLOR,
727 /// The title background color of a focused window that might be captured.
728 ///
729 /// Default: `#772831`.
730 const 13 => CAPTURED_FOCUSED_TITLE_BACKGROUND_COLOR,
731 /// The title background color of a window that has requested attention.
732 ///
733 /// Default: `#23092c`.
734 const 14 => ATTENTION_REQUESTED_BACKGROUND_COLOR,
735 /// Color used to highlight parts of the UI.
736 ///
737 /// Default: `#9d28c67f`.
738 const 15 => HIGHLIGHT_COLOR,
739 /// The color of the border between windows where at least one of the windows is
740 /// focused.
741 ///
742 /// For containers, this requires `Full` [`ContainerBorders`].
743 ///
744 /// Default: The `BORDER` color.
745 const 16 => FOCUSED_BORDER_COLOR,
746 }
747
748 /// Sets the color of GUI element.
749 pub fn set_color(element: Colorable, color: Color) {
750 get!().set_color(element, color);
751 }
752
753 /// Gets the color of GUI element.
754 pub fn get_color(element: Colorable) -> Color {
755 get!(Color::BLACK).get_color(element)
756 }
757}
758
759/// Elements of the compositor whose size can be changed.
760pub mod sized {
761 use serde::Deserialize;
762 use serde::Serialize;
763
764 /// An element of the GUI whose size can be changed.
765 #[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
766 pub struct Resizable(#[doc(hidden)] pub u32);
767
768 impl Resizable {
769 /// Gets the current size.
770 pub fn get(self) -> i32 {
771 get!(0).get_size(self)
772 }
773
774 /// Sets the size.
775 pub fn set(self, size: i32) {
776 get!().set_size(self, size)
777 }
778 }
779
780 macro_rules! sizes {
781 ($($(#[$attr:meta])* const $n:expr => $name:ident,)*) => {
782 $(
783 $(#[$attr])*
784 pub const $name: Resizable = Resizable($n);
785 )*
786 }
787 }
788
789 sizes! {
790 /// The height of window titles.
791 ///
792 /// Default: 17
793 const 01 => TITLE_HEIGHT,
794 /// The width of borders between windows.
795 ///
796 /// Default: 4
797 const 02 => BORDER_WIDTH,
798 /// The height of the bar.
799 ///
800 /// Defaults to the TITLE_HEIGHT if not set explicitly.
801 ///
802 /// Default: 17
803 const 03 => BAR_HEIGHT,
804 /// The width of the bar's separator.
805 ///
806 /// Default: 1
807 const 04 => BAR_SEPARATOR_WIDTH,
808 }
809}