From 51be08c21f4e7048bf61008b4964b7ae17d75caa Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Tue, 9 Jul 2019 17:09:08 +0200 Subject: [PATCH] Add ratio layout. Also refactor Gio.Settings call --- assets/icons/view-quilt-ratio-symbolic.svg | 4 ++ gschemas.compiled | Bin 1029 -> 1133 bytes layouts.gschema.xml | 10 +++ module/hotKeysModule.js | 13 ++-- module/requiredSettingsModule.js | 10 +-- prefs.js | 47 ++++++++----- tilingManager/tilingLayouts/layoutByKey.js | 5 +- tilingManager/tilingLayouts/ratioGrid.js | 76 +++++++++++++++++++++ tilingManager/tilingManager.js | 11 +-- utils/settings.js | 12 ++++ 10 files changed, 145 insertions(+), 43 deletions(-) create mode 100644 assets/icons/view-quilt-ratio-symbolic.svg create mode 100644 tilingManager/tilingLayouts/ratioGrid.js create mode 100644 utils/settings.js diff --git a/assets/icons/view-quilt-ratio-symbolic.svg b/assets/icons/view-quilt-ratio-symbolic.svg new file mode 100644 index 0000000..3866065 --- /dev/null +++ b/assets/icons/view-quilt-ratio-symbolic.svg @@ -0,0 +1,4 @@ + + + φ + diff --git a/gschemas.compiled b/gschemas.compiled index 6529343de01abeaca2d50a2ea575dc117868a96a..8423d786840b237765709681e6f726135ee55a82 100644 GIT binary patch delta 402 zcmZqWc*`-NfN{pgLT9FW4h9Hd1X9dE%nHP8P|OabLHIyz9ru4Am;qG4%239z07zd2 z;>`I9aUiuIHV07r0g!$Q#2Y(=zJtU;Y)+u~2O#|wh?Ux6=YzySY<{3P2Ma?z11}2$ z!=;&RH$f60HZM>@0Z6L?F|&^tJ4hVF766J{0BIK>W))>%067T6W?=9Ei^Txh*LlLu zfYgK7TtM|1KspzQ^$HS8GJxXx`93R9NsrtnksX00NsgrjxE6e02R%GU8R;2<} zFfwQ)X(pDI_j2~nvFW&%b1U+SB` hKla$3K_f+z3CIU}6=*0V96@0VbPWSS8;}Ds2LRopQzifa delta 277 zcmaFM(aJHQfH7fXp)*rG8v_I|0Vx<}2C`Xz_|nX_n;<#?D8S25#!vvHOMzIaEp|Rg z9K_}aigy6%ULek#uMh_k2eCPT;xmBsTp&JBTgUw$2taIBp!f1at$jGm!%e!WF{x(=%yECrhv3e{>UsNk(*eNnVVUa q3gj~~Xe4Rs6(p8qfF$QKTWA1jRVertical Grid layout Tile windows vertically + + false + Ratio based Grid layout + Tile windows in both way according to the ratio of the remaining space + + + 0.6180339887498948 + Ratio of the ratio layout + Determines the ratio of the tiling + diff --git a/module/hotKeysModule.js b/module/hotKeysModule.js index 44cd94a..141edc5 100644 --- a/module/hotKeysModule.js +++ b/module/hotKeysModule.js @@ -1,6 +1,7 @@ -const { Meta, Shell, Gio } = imports.gi; +const { Meta, Shell } = imports.gi; const Main = imports.ui.main; const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { getSettings } = Me.imports.utils.settings; /* exported HotKeysModule */ var HotKeysModule = class HotKeysModule { @@ -9,14 +10,8 @@ var HotKeysModule = class HotKeysModule { } enable() { - const SchemaSource = Gio.SettingsSchemaSource.new_from_directory( - Me.dir.get_path(), - Gio.SettingsSchemaSource.get_default(), - false - ); - const settings = new Gio.Settings({ - settings_schema: SchemaSource.lookup(Me.metadata['bindings'], true) - }); + const settings = getSettings('bindings'); + Main.wm.addKeybinding( 'previous-window', settings, diff --git a/module/requiredSettingsModule.js b/module/requiredSettingsModule.js index 86cb2a5..5282856 100644 --- a/module/requiredSettingsModule.js +++ b/module/requiredSettingsModule.js @@ -1,6 +1,7 @@ const { Gio } = imports.gi; const Main = imports.ui.main; const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { getSettings } = Me.imports.utils.settings; /* exported RequiredSettingsModule */ var RequiredSettingsModule = class RequiredSettingsModule { @@ -56,14 +57,7 @@ var RequiredSettingsModule = class RequiredSettingsModule { }); }); - const SchemaSource = Gio.SettingsSchemaSource.new_from_directory( - Me.dir.get_path(), - Gio.SettingsSchemaSource.get_default(), - false - ); - const bindingSettings = new Gio.Settings({ - settings_schema: SchemaSource.lookup(Me.metadata['bindings'], true) - }); + const bindingSettings = getSettings('bindings'); this.hotkeysToRemove = bindingSettings.list_keys().map(key => { return bindingSettings.get_strv(key)[0]; }); diff --git a/prefs.js b/prefs.js index 4331e67..93f98f4 100644 --- a/prefs.js +++ b/prefs.js @@ -5,6 +5,7 @@ const Lang = imports.lang; // Extension imports const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { getSettings } = Me.imports.utils.settings; function init() {} @@ -40,14 +41,7 @@ function buildPrefsWidget() { } function accel_tab(notebook) { - const SchemaSource = Gio.SettingsSchemaSource.new_from_directory( - Me.dir.get_path(), - Gio.SettingsSchemaSource.get_default(), - false - ); - const settings = new Gio.Settings({ - settings_schema: SchemaSource.lookup(Me.metadata['bindings'], true) - }); + const settings = getSettings('bindings'); let ks_grid = new Gtk.Grid({ column_spacing: 10, @@ -161,16 +155,11 @@ function layouts_tab(notebook) { maximize: 'Maximize all windows', 'auto-grid': 'Tile windows according to screen ratio', 'vertical-grid': 'Tile windows vertically', - 'horizontal-grid': 'Tile windows horizontally' + 'horizontal-grid': 'Tile windows horizontally', + 'ratio-grid': + 'Tile windows in both way according to the ratio of the remaining space' }; - const SchemaSource = Gio.SettingsSchemaSource.new_from_directory( - Me.dir.get_path(), - Gio.SettingsSchemaSource.get_default(), - false - ); - const settings = new Gio.Settings({ - settings_schema: SchemaSource.lookup(Me.metadata['layouts'], true) - }); + const settings = getSettings('layouts'); let ks_window = new Gtk.ScrolledWindow({ vexpand: true }); const ks_lbox = new Gtk.ListBox({ @@ -198,10 +187,34 @@ function layouts_tab(notebook) { vbox.pack_start(desc, false, false, 0); hbox.pack_start(vbox, true, true, 10); hbox.pack_start(item, false, false, 0); + row.add(hbox); ks_lbox.add(row); + settings.bind(layout, item, 'active', Gio.SettingsBindFlags.DEFAULT); + if (layout === 'ratio-grid') { + const row = new Gtk.ListBoxRow(); + const ratio = Gtk.Scale.new_with_range( + Gtk.Orientation.HORIZONTAL, + 0, + 1, + 0.01 + ); + ratio.add_mark( + 0.6180339887498948, + Gtk.PositionType.BOTTOM, + 'Golden Ratio' + ); + settings.bind( + 'ratio-grid-ratio', + ratio.get_adjustment(), + 'value', + Gio.SettingsBindFlags.DEFAULT + ); + row.add(ratio); + ks_lbox.add(row); + } }); notebook.append_page(ks_window, ks_label); } diff --git a/tilingManager/tilingLayouts/layoutByKey.js b/tilingManager/tilingLayouts/layoutByKey.js index 34688f2..59d5c99 100644 --- a/tilingManager/tilingLayouts/layoutByKey.js +++ b/tilingManager/tilingLayouts/layoutByKey.js @@ -9,10 +9,13 @@ const { const { HorizontalGridLayout } = Me.imports.tilingManager.tilingLayouts.horizontalGrid; +const { RatioGridLayout } = Me.imports.tilingManager.tilingLayouts.ratioGrid; + /* exported TilingLayoutByKey */ var TilingLayoutByKey = { 'auto-grid': AutoGridLayout, 'vertical-grid': VerticalGridLayout, 'horizontal-grid': HorizontalGridLayout, - maximize: MaximizeLayout + maximize: MaximizeLayout, + 'ratio-grid': RatioGridLayout }; diff --git a/tilingManager/tilingLayouts/ratioGrid.js b/tilingManager/tilingLayouts/ratioGrid.js new file mode 100644 index 0000000..e5185cb --- /dev/null +++ b/tilingManager/tilingLayouts/ratioGrid.js @@ -0,0 +1,76 @@ +const Main = imports.ui.main; +const { Meta, Gio } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const { AutoGridLayout } = Me.imports.tilingManager.tilingLayouts.autoGrid; +const { getSettings } = Me.imports.utils.settings; + +/* exported RatioGridLayout */ +var RatioGridLayout = class RatioGridLayout extends AutoGridLayout { + constructor(superWorkspace) { + super(superWorkspace); + this.key = 'ratio-grid'; + this.icon = Gio.icon_new_for_string( + `${Me.path}/assets/icons/view-quilt-ratio-symbolic.svg` + ); + this.settings = getSettings('layouts'); + this.settings.connect('changed::ratio-grid-ratio', (schema, key) => { + log('changed'); + this.onTile(); + }); + } + + onTileRegulars(windows) { + if (!windows.length) return; + + const ratio = this.settings.get_double('ratio-grid-ratio'); + log('tile', ratio); + + const workArea = Main.layoutManager.getWorkAreaForMonitor( + this.monitor.index + ); + const freeArea = { + x: workArea.x, + y: workArea.y, + width: workArea.width, + height: workArea.height + }; + + windows.forEach((window, index) => { + if (window.grabbed) return; + + if (window.get_maximized()) + window.unmaximize(Meta.MaximizeFlags.BOTH); + + let windowArea = { + x: freeArea.x, + y: freeArea.y + }; + + if (index === windows.length - 1) { + windowArea = freeArea; + } else { + if (freeArea.width > freeArea.height) { + windowArea.width = freeArea.width * ratio; + windowArea.height = freeArea.height; + freeArea.x += windowArea.width; + freeArea.width -= windowArea.width; + } else { + windowArea.width = freeArea.width; + windowArea.height = freeArea.height * ratio; + freeArea.y += windowArea.height; + freeArea.height -= windowArea.height; + } + } + + this.moveAndResizeMetaWindow( + window, + windowArea.x, + windowArea.y, + windowArea.width, + windowArea.height + ); + }); + } +}; diff --git a/tilingManager/tilingManager.js b/tilingManager/tilingManager.js index 0480b02..beae9d2 100644 --- a/tilingManager/tilingManager.js +++ b/tilingManager/tilingManager.js @@ -3,6 +3,8 @@ const Main = imports.ui.main; const GLib = imports.gi.GLib; const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { getSettings } = Me.imports.utils.settings; + const { TilingLayoutByKey } = Me.imports.tilingManager.tilingLayouts.layoutByKey; @@ -14,14 +16,7 @@ var TilingManager = class TilingManager { this.grabInProgress = false; this.signals = []; this.windows = []; - const SchemaSource = Gio.SettingsSchemaSource.new_from_directory( - Me.dir.get_path(), - Gio.SettingsSchemaSource.get_default(), - false - ); - this.layoutsSettings = new Gio.Settings({ - settings_schema: SchemaSource.lookup(Me.metadata['layouts'], true) - }); + this.layoutsSettings = getSettings('layouts'); this.allLayouts = Object.keys(TilingLayoutByKey); // On layout settings change diff --git a/utils/settings.js b/utils/settings.js new file mode 100644 index 0000000..27c9bc0 --- /dev/null +++ b/utils/settings.js @@ -0,0 +1,12 @@ +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { Gio } = imports.gi; + +/* exported getSettings */ +var getSettings = key => + new Gio.Settings({ + settings_schema: Gio.SettingsSchemaSource.new_from_directory( + Me.dir.get_path(), + Gio.SettingsSchemaSource.get_default(), + false + ).lookup(Me.metadata[key], true) + });