diff --git a/extension.js b/extension.js index 199f95e..11bf945 100644 --- a/extension.js +++ b/extension.js @@ -6,7 +6,7 @@ var modules = [ Extension.imports.liveAltTab, Extension.imports.utils, Extension.imports.stackoverlay, Extension.imports.app, Extension.imports.kludges, Extension.imports.topbar, - Extension.imports.navigator + Extension.imports.navigator, Extension.imports.prefs ]; var [ Tiling, Scratch, LiveAltTab, utils, StackOverlay, diff --git a/minimap.js b/minimap.js index 2f2a5b4..5633105 100644 --- a/minimap.js +++ b/minimap.js @@ -9,6 +9,8 @@ var Tiling = Extension.imports.tiling; var utils = Extension.imports.utils; var debug = utils.debug; +var prefs = Extension.imports.prefs.prefs; + var MINIMAP_SCALE = 0.15; function calcOffset(metaWindow) { @@ -96,7 +98,7 @@ class Minimap { actor.add_actor(label); actor.add_actor(clip); clip.add_actor(container); - clip.set_position(12 + Tiling.window_gap, 15 + 10); + clip.set_position(12 + prefs.window_gap, 15 + 10); highlight.y = clip.y - 10; } @@ -150,7 +152,7 @@ class Minimap { propagate_forward(i+1, Math.round(x + w + gap), gap); } - propagate_forward(0, 0, Tiling.window_gap); + propagate_forward(0, 0, prefs.window_gap); this.clip.width = Math.min(this.container.width, this.space.width - this.clip.x*2); this.actor.width = this.clip.width + this.clip.x*2; @@ -209,7 +211,7 @@ class Minimap { if (container.x > 0) container.x = 0; - let gap = Tiling.window_gap; + let gap = prefs.window_gap; highlight.x = clip.x + container.x + Math.round(selected.destinationX) - Math.round(gap/2); highlight.set_size(selected.width + gap, clip.height + 20); diff --git a/navigator.js b/navigator.js index d6a5a61..bbc18cd 100644 --- a/navigator.js +++ b/navigator.js @@ -18,6 +18,8 @@ var Tiling = Extension.imports.tiling; var utils = Extension.imports.utils; var debug = utils.debug; +var prefs = Extension.imports.prefs.prefs; + var scale = 0.9; var navigating = false; var workspaceMru = false; @@ -167,7 +169,7 @@ var PreviewedWindowNavigator = new Lang.Class({ let selected = space.selectedWindow; if (selected && selected.fullscreen) { - selected.clone.y = Main.panel.actor.height + Tiling.margin_tb; + selected.clone.y = Main.panel.actor.height + prefs.vertical_margin; } }); this.space.actor.scale_y = 1; @@ -182,7 +184,7 @@ var PreviewedWindowNavigator = new Lang.Class({ let selected = this.space.selectedWindow; if (selected && selected.fullscreen) { Tweener.addTween(selected.clone, { - y: Main.panel.actor.height + Tiling.margin_tb, + y: Main.panel.actor.height + prefs.vertical_margin, time: 0.25 }); } diff --git a/prefs.js b/prefs.js new file mode 100644 index 0000000..28fe76d --- /dev/null +++ b/prefs.js @@ -0,0 +1,28 @@ +var Extension = imports.misc.extensionUtils.extensions['paperwm@hedning:matrix.org']; +var settings = Extension.imports.convenience.getSettings(); +var utils = Extension.imports.utils; +var debug = utils.debug; + +var prefs = { + window_gap: settings.get_int('window-gap'), + vertical_margin: settings.get_int('vertical-margin'), + horizontal_margin: settings.get_int('horizontal-margin'), + workspace_colors: settings.get_strv('workspace-colors') +}; + +function setState(_, key) { + let value = settings.get_value(key); + let name = key.replace('-', '_'); + switch (value.get_type_string()) { + case 'i': + prefs[name] = settings.get_int(key); + break; + case 'as': + prefs[name] = settings.get_strv(key); + break; + } +} + +function init() { + settings.connect('changed', setState); +} diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled index dbc76b1..f1e6d92 100644 Binary files a/schemas/gschemas.compiled and b/schemas/gschemas.compiled differ diff --git a/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml b/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml index 3b3edc4..83980c4 100644 --- a/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml +++ b/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml @@ -22,6 +22,14 @@ Minimum gap between windows + + + Minimum gap between windows + + n']]]> diff --git a/stackoverlay.js b/stackoverlay.js index a15ed38..fea1291 100644 --- a/stackoverlay.js +++ b/stackoverlay.js @@ -10,6 +10,8 @@ var utils = Extension.imports.utils; var debug = utils.debug; var Minimap = Extension.imports.minimap; +var prefs = Extension.imports.prefs.prefs; + /* The stack overlay decorates the top stacked window with its icon and captures mouse input such that a mouse click only _activates_ the @@ -126,8 +128,8 @@ var StackOverlay = new Lang.Class({ let panelBox = Main.layoutManager.panelBox; - overlay.y = monitor.y + panelBox.height + Tiling.margin_tb; - overlay.height = this.monitor.height - panelBox.height - Tiling.margin_tb; + overlay.y = monitor.y + panelBox.height + Tiling.vertical_margin; + overlay.height = this.monitor.height - panelBox.height - Tiling.vertical_margin; overlay.width = Tiling.stack_margin; overlay.hide(); @@ -153,7 +155,7 @@ var StackOverlay = new Lang.Class({ } let iconMarginX = 2; - let iconSize = margin_lr; + let iconSize = horizontal_margin; let icon = createAppIcon(this.target, iconSize); this.icon = icon; @@ -188,7 +190,7 @@ var StackOverlay = new Lang.Class({ let actor = metaWindow.get_compositor_private(); let space = Tiling.spaces.spaceOfWindow(metaWindow); - overlay.y = this.monitor.y + Main.layoutManager.panelBox.height + Tiling.margin_tb; + overlay.y = this.monitor.y + Main.layoutManager.panelBox.height + Tiling.vertical_margin; // Note: Atm. this can be called when the windows are moving. Therefore // we must use destinationX and we might occationally get wrong y @@ -201,14 +203,14 @@ var StackOverlay = new Lang.Class({ let frame = neighbour.get_frame_rect(); overlay.x = this.monitor.x; - overlay.width = Math.max(0, frame.x - Tiling.window_gap); + overlay.width = Math.max(0, frame.x - prefs.window_gap); } else { let neighbour = space[space.indexOf(metaWindow) - 1]; if (!neighbour) return bail(); // Should normally have a neighbour. Bail! let frame = neighbour.get_frame_rect(); - overlay.x = frame.x + frame.width + Tiling.window_gap; + overlay.x = frame.x + frame.width + prefs.window_gap; overlay.width = Math.max(0, this.monitor.width - overlay.x); } diff --git a/tiling.js b/tiling.js index 62eee54..80196d0 100644 --- a/tiling.js +++ b/tiling.js @@ -25,13 +25,8 @@ var Navigator = Extension.imports.navigator; var ClickOverlay = Extension.imports.stackoverlay.ClickOverlay; var Me = Extension.imports.tiling; -var preferences = Extension.imports.convenience.getSettings(); -// Gap between windows -var window_gap = preferences.get_int('window-gap'); -// Top/bottom margin -var margin_tb = preferences.get_int('vertical-margin'); -// left/right margin -var margin_lr = preferences.get_int('horizontal-margin'); +var prefs = Extension.imports.prefs.prefs; + // How much the stack should protrude from the side var stack_margin = 75; // Minimum margin @@ -39,19 +34,6 @@ var minimumMargin = 15; var panelBox = Main.layoutManager.panelBox; -// From https://developer.gnome.org/hig-book/unstable/design-color.html.en -var colors = [ - '#9DB8D2', '#7590AE', '#4B6983', '#314E6C', - '#EAE8E3', '#BAB5AB', '#807D74', '#565248', - '#C5D2C8', '#83A67F', '#5D7555', '#445632', - '#E0B6AF', '#C1665A', '#884631', '#663822', - '#ADA7C8', '#887FA3', '#625B81', '#494066', - '#EFE0CD', '#E0C39E', '#B39169', '#826647', - '#DF421E', '#990000', '#EED680', '#D1940C', - '#46A046', '#267726', '#ffffff', '#000000' -]; -var color; - /** Scrolled and tiled per monitor workspace. @@ -121,13 +103,13 @@ class Space extends Array { actor.set_pivot_point(0.5, 0); - background.set_position(-8 - Math.round(window_gap/2), -4); + background.set_position(-8 - Math.round(prefs.window_gap/2), -4); + let color = prefs.workspace_colors[workspace.index() % prefs.workspace_colors.length]; background.set_style( - `background: ${colors[color]}; + `background: ${color}; box-shadow: 0px -10px 4px 2px black; box-shadow: 0px -4px 8px 0 rgba(0, 0, 0, .5); border-radius: 4px 4px 0 0;`); - color = (color + 4) % colors.length; this.selectedWindow = null; this.moving = false; @@ -176,10 +158,10 @@ class Space extends Array { monitor.width, monitor.height); - background.set_size(monitor.width + 8*2 + window_gap, monitor.height + 4); + background.set_size(monitor.width + 8*2 + prefs.window_gap, monitor.height + 4); cloneContainer.set_size(monitor.width, monitor.height); - cloneContainer.set_clip(-Math.round(window_gap/2), 0, monitor.width + window_gap, monitor.height); + cloneContainer.set_clip(-Math.round(prefs.window_gap/2), 0, monitor.width + prefs.window_gap, monitor.height); } /** @@ -620,8 +602,6 @@ function init() { function enable() { debug('#enable'); - color = 3; - global.window_manager[signals] = [ global.window_manager.connect( 'switch-workspace', @@ -865,11 +845,11 @@ function insertWindow(metaWindow, {existing}) { let frame = metaWindow.get_frame_rect(); position = {x: monitor.x + (monitor.width - frame.width)/2, - y: monitor.y + panelBox.height + margin_tb}; + y: monitor.y + panelBox.height + prefs.vertical_margin}; } else { let frame = space[index - 1].get_frame_rect(); - position = {x: monitor.x + frame.x + frame.width + window_gap, - y: monitor.y + panelBox.height + margin_tb}; + position = {x: monitor.x + frame.x + frame.width + prefs.window_gap, + y: monitor.y + panelBox.height + prefs.vertical_margin}; } debug("setting initial position", position) @@ -935,23 +915,23 @@ function ensureViewport(meta_window, space, force) { let frame = meta_window.get_frame_rect(); let width = Math.min(space.monitor.width - 2*minimumMargin, frame.width); meta_window.move_resize_frame(true, frame.x, frame.y, width, - space.height - panelBox.height - margin_tb); + space.height - panelBox.height - prefs.vertical_margin); // Use monitor relative coordinates. frame.x -= monitor.x; frame.y -= monitor.y; - space.selection.set_position(frame.x - Math.round(window_gap/2), + space.selection.set_position(frame.x - Math.round(prefs.window_gap/2), panelBox.height); - space.selection.set_size(frame.width + window_gap, space.height - panelBox.height); + space.selection.set_size(frame.width + prefs.window_gap, space.height - panelBox.height); let x = frame.x; - let y = panelBox.height + margin_tb; - let gap = window_gap; + let y = panelBox.height + prefs.vertical_margin; + let gap = prefs.window_gap; let required_width = space.reduce((length, meta_window) => { let frame = meta_window.get_frame_rect(); - return length + frame.width + window_gap; - }, -window_gap); + return length + frame.width + prefs.window_gap; + }, -prefs.window_gap); if (!Navigator.workspaceMru && (meta_window.fullscreen || meta_window.get_maximized() === Meta.MaximizeFlags.BOTH)) { x = frame.x; y = frame.y; @@ -968,16 +948,16 @@ function ensureViewport(meta_window, space, force) { } else if (index == space.length-1) { // Always align the first window to the display's right edge x = space.width - frame.width; - } else if (frame.width > space.width*0.9 - 2*(margin_lr + window_gap)) { + } else if (frame.width > space.width*0.9 - 2*(prefs.horizontal_margin + prefs.window_gap)) { // Consider the window to be wide and center it x = Math.round((space.width - frame.width)/2); } else if (frame.x + frame.width > space.width) { - // Align to the right margin_lr - x = space.width - margin_lr - frame.width; + // Align to the right prefs.horizontal_margin + x = space.width - prefs.horizontal_margin - frame.width; } else if (frame.x < 0) { - // Align to the left margin_lr - x = margin_lr; + // Align to the left prefs.horizontal_margin + x = prefs.horizontal_margin; } else if (frame.x + frame.width === space.width) { // When opening new windows at the end, in the background, we want to // show some minimup margin @@ -1006,9 +986,9 @@ function ensureViewport(meta_window, space, force) { let selectedFrame = space.selectedWindow.get_frame_rect(); Navigator.navigating && space.selection.show(); Tweener.addTween(space.selection, - {x: selectedFrame.x - Math.round(window_gap/2), + {x: selectedFrame.x - Math.round(prefs.window_gap/2), y: panelBox.height, - width: selectedFrame.width + window_gap, + width: selectedFrame.width + prefs.window_gap, height: space.height - panelBox.height, time: 0.25, transition: 'easeInOutQuad'}); @@ -1094,7 +1074,7 @@ function move_to(space, meta_window, { x, y, delay, transition, space.monitor.clickOverlay.reset(); - gap = gap || window_gap; + gap = gap || prefs.window_gap; propagateForward(space, index + 1, x + frame.width + gap, gap); propagateBackward(space, index - 1, x - gap, gap); } @@ -1106,7 +1086,7 @@ function propagateForward(space, n, x, gap) { } let meta_window = space[n]; let frame = meta_window.get_frame_rect(); - gap = gap || window_gap; + gap = gap || prefs.window_gap; let visible = true; // Check if we should start stacking windows @@ -1122,7 +1102,7 @@ function propagateForward(space, n, x, gap) { // Anchor scaling/animation on the left edge for windows positioned to the right, move(meta_window, space, - { x, y: panelBox.height + margin_tb, visible }); + { x, y: panelBox.height + prefs.vertical_margin, visible }); if (!visible && x < space.width) { space.monitor.clickOverlay.right.setTarget(meta_window); } @@ -1140,7 +1120,7 @@ function propagateBackward(space, n, x, gap) { } let meta_window = space[n]; let frame = meta_window.get_frame_rect(); - gap = gap || window_gap; + gap = gap || prefs.window_gap; // Check if the window is fully visible let visible = true; @@ -1156,7 +1136,7 @@ function propagateBackward(space, n, x, gap) { if (actor) { // Anchor on the right edge for windows positioned to the left. move(meta_window, space, - { x: x - frame.width, y: panelBox.height + margin_tb, visible }); + { x: x - frame.width, y: panelBox.height + prefs.vertical_margin, visible }); if (!visible && x > 0) { space.monitor.clickOverlay.left.setTarget(meta_window); } @@ -1179,8 +1159,8 @@ function sizeHandler(metaWindow) { move_to(space, metaWindow, {x: frame.x - monitor.x, y: frame.y - monitor.y, onComplete: () => space.emit('move-done')}); Tweener.removeTweens(space.selection); - space.selection.width = frame.width + window_gap; - space.selection.x = frame.x - Math.round(window_gap/2); + space.selection.width = frame.width + prefs.window_gap; + space.selection.x = frame.x - Math.round(prefs.window_gap/2); } // `MetaWindow::focus` handling @@ -1362,7 +1342,7 @@ function tileVisible(metaWindow) { let active = space.filter(isUnStacked); let requiredWidth = utils.sum(active.map(mw => mw.get_frame_rect().width)) - + (active.length-1)*window_gap + minimumMargin*2; + + (active.length-1)*prefs.window_gap + minimumMargin*2; let deficit = requiredWidth - primary.width; if (deficit > 0) { let perWindowReduction = Math.ceil(deficit/active.length);