appearance.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Gnome imports
  2. import Adw from "gi://Adw";
  3. import GObject from "gi://GObject";
  4. import Gdk from "gi://Gdk";
  5. // Extension imports
  6. import { gettext as _ } from "resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js";
  7. // Shared state
  8. import { ConfigManager } from "../shared/settings.js";
  9. import { PrefsThemeManager } from "./prefs-theme-manager.js";
  10. // Prefs UI
  11. import { ColorRow, PreferencesPage, ResetButton, SpinButtonRow, SwitchRow } from "./widgets.js";
  12. import { Logger } from "../shared/logger.js";
  13. export class AppearancePage extends PreferencesPage {
  14. static {
  15. GObject.registerClass(this);
  16. }
  17. /**
  18. * @param {string} selector
  19. */
  20. static getCssSelectorAsMessage(selector) {
  21. switch (selector) {
  22. case ".window-tiled-border":
  23. return _("Tiled Focus Hint and Preview");
  24. case ".window-floated-border":
  25. return _("Floated Focus Hint");
  26. case ".window-split-border":
  27. return _("Split Direction Hint");
  28. case ".window-stacked-border":
  29. return _("Stacked Focus Hint and Preview");
  30. case ".window-tabbed-border":
  31. return _("Tabbed Focus Hint and Preview");
  32. }
  33. }
  34. constructor({ settings, dir }) {
  35. super({ title: _("Appearance"), icon_name: "brush-symbolic" });
  36. this.settings = settings;
  37. this.configMgr = new ConfigManager({ dir });
  38. this.themeMgr = new PrefsThemeManager(this);
  39. this.add_group({
  40. title: _("Gaps"),
  41. children: [
  42. // Gaps size
  43. new SpinButtonRow({
  44. title: _("Gaps Size"),
  45. range: [0, 32, 1],
  46. settings,
  47. bind: "window-gap-size",
  48. }),
  49. // Gaps size multiplier
  50. new SpinButtonRow({
  51. title: _("Gaps Size Multiplier"),
  52. range: [0, 8, 1],
  53. settings,
  54. bind: "window-gap-size-increment",
  55. }),
  56. // Gap Hidden when Single Window
  57. new SwitchRow({
  58. title: _("Gaps Hidden when Single"),
  59. settings,
  60. bind: "window-gap-hidden-on-single",
  61. }),
  62. ],
  63. });
  64. this.add_group({
  65. title: _("Color"),
  66. children: [
  67. "window-tiled-border",
  68. "window-tabbed-border",
  69. "window-stacked-border",
  70. "window-floated-border",
  71. "window-split-border",
  72. ].map((x) => this._createColorOptionWidget(x)),
  73. });
  74. }
  75. /**
  76. * @param {string} prefix
  77. */
  78. _createColorOptionWidget(prefix) {
  79. const selector = `.${prefix}`;
  80. const theme = this.themeMgr;
  81. const title = AppearancePage.getCssSelectorAsMessage(selector);
  82. const colorScheme = theme.getColorSchemeBySelector(selector);
  83. const row = new Adw.ExpanderRow({ title });
  84. const borderSizeRow = new SpinButtonRow({
  85. title: _("Border Size"),
  86. range: [1, 6, 1],
  87. // subtitle: 'Properties of the focus hint',
  88. max_width_chars: 1,
  89. max_length: 1,
  90. width_chars: 2,
  91. xalign: 1,
  92. init: theme.removePx(theme.getCssProperty(selector, "border-width").value),
  93. onChange: (value) => {
  94. const px = theme.addPx(value);
  95. Logger.debug(`Setting border width for selector: ${selector} ${px}`);
  96. theme.setCssProperty(selector, "border-width", px);
  97. },
  98. });
  99. borderSizeRow.add_suffix(
  100. new ResetButton({
  101. onReset: () => {
  102. const borderDefault = theme.defaultPalette[colorScheme]["border-width"];
  103. theme.setCssProperty(selector, "border-width", theme.addPx(borderDefault));
  104. borderSizeRow.activatable_widget.value = borderDefault;
  105. },
  106. })
  107. );
  108. const updateCssColors = (rgbaString) => {
  109. const rgba = new Gdk.RGBA();
  110. if (rgba.parse(rgbaString)) {
  111. Logger.debug(`Setting color for selector: ${selector} ${rgbaString}`);
  112. const previewBorderRgba = rgba.copy();
  113. const previewBackgroundRgba = rgba.copy();
  114. const overviewBackgroundRgba = rgba.copy();
  115. previewBorderRgba.alpha = 0.3;
  116. previewBackgroundRgba.alpha = 0.2;
  117. overviewBackgroundRgba.alpha = 0.5;
  118. // The primary color updates the focus hint:
  119. theme.setCssProperty(selector, "border-color", rgba.to_string());
  120. // Only apply below on the tabbed scheme
  121. if (colorScheme === "tabbed") {
  122. const tabBorderRgba = rgba.copy();
  123. const tabActiveBackgroundRgba = rgba.copy();
  124. tabBorderRgba.alpha = 0.6;
  125. theme.setCssProperty(
  126. `.window-${colorScheme}-tab`,
  127. "border-color",
  128. tabBorderRgba.to_string()
  129. );
  130. theme.setCssProperty(
  131. `.window-${colorScheme}-tab-active`,
  132. "background-color",
  133. tabActiveBackgroundRgba.to_string()
  134. );
  135. }
  136. // And then finally the preview when doing drag/drop tiling:
  137. theme.setCssProperty(
  138. `.window-tilepreview-${colorScheme}`,
  139. "border-color",
  140. previewBorderRgba.to_string()
  141. );
  142. theme.setCssProperty(
  143. `.window-tilepreview-${colorScheme}`,
  144. "background-color",
  145. previewBackgroundRgba.to_string()
  146. );
  147. }
  148. };
  149. const borderColorRow = new ColorRow({
  150. title: _("Border Color"),
  151. init: theme.getCssProperty(selector, "border-color").value,
  152. onChange: updateCssColors,
  153. });
  154. borderColorRow.add_suffix(
  155. new ResetButton({
  156. onReset: () => {
  157. const selectorColor = theme.defaultPalette[colorScheme].color;
  158. updateCssColors(selectorColor);
  159. const rgba = new Gdk.RGBA();
  160. if (rgba.parse(selectorColor)) {
  161. borderColorRow.colorButton.set_rgba(rgba);
  162. }
  163. },
  164. })
  165. );
  166. row.add_row(borderColorRow);
  167. row.add_row(borderSizeRow);
  168. return row;
  169. }
  170. }