diff --git a/ddterm/app/application.js b/ddterm/app/application.js
index 0c9fbd2d2..9f6c33a06 100644
--- a/ddterm/app/application.js
+++ b/ddterm/app/application.js
@@ -347,6 +347,17 @@ export class Application extends Gtk.Application {
if (!this.#settings.get_boolean('window-maximize'))
this.#adjust_double_setting('window-size', SIZE_STEP);
},
+ 'window-size-secondary-dec': () => {
+ if (this.#settings.get_boolean('window-maximize'))
+ this.#settings.set_double('window-size-secondary', 1.0 - SIZE_STEP);
+ else
+ this.#adjust_double_setting('window-size-secondary', -SIZE_STEP);
+ },
+
+ 'window-size-secondary-inc': () => {
+ if (!this.#settings.get_boolean('window-maximize'))
+ this.#adjust_double_setting('window-size-secondary', SIZE_STEP);
+ },
'background-opacity-dec': () => {
this.#adjust_double_setting('background-opacity', -OPACITY_STEP);
},
@@ -416,6 +427,8 @@ export class Application extends Gtk.Application {
'shortcut-window-hide': 'win.hide',
'shortcut-window-size-inc': 'app.window-size-inc',
'shortcut-window-size-dec': 'app.window-size-dec',
+ 'shortcut-window-size-secondary-inc': 'app.window-size-secondary-inc',
+ 'shortcut-window-size-secondary-dec': 'app.window-size-secondary-dec',
'shortcut-background-opacity-inc': 'app.background-opacity-inc',
'shortcut-background-opacity-dec': 'app.background-opacity-dec',
'shortcut-toggle-maximize': 'app.window-maximize',
diff --git a/ddterm/pref/positionsize.js b/ddterm/pref/positionsize.js
index 5446ce548..efd4ea279 100644
--- a/ddterm/pref/positionsize.js
+++ b/ddterm/pref/positionsize.js
@@ -7,7 +7,7 @@ import GObject from 'gi://GObject';
import Gio from 'gi://Gio';
import Gtk from 'gi://Gtk';
-import { PreferencesGroup, ComboRow, ScaleRow } from './util.js';
+import { PreferencesGroup, ComboRow } from './util.js';
import { Monitor } from '../util/displayconfig.js';
class SpecialMonitor extends Monitor {
@@ -280,38 +280,24 @@ export class PositionSizeGroup extends PreferencesGroup {
},
});
- const window_size_adjustment = new Gtk.Adjustment({
- upper: 1,
- step_increment: 0.01,
- page_increment: 0.10,
- });
-
- this.settings.bind(
- 'window-size',
- window_size_adjustment,
- 'value',
- Gio.SettingsBindFlags.DEFAULT
- );
-
- const window_size_row = new ScaleRow({
- adjustment: window_size_adjustment,
- digits: 2,
- round_digits: 2,
- visible: true,
- use_underline: true,
+ this.add_scale_row({
+ key: 'window-size',
+ adjustment: new Gtk.Adjustment({
+ upper: 1,
+ step_increment: 0.01,
+ page_increment: 0.10,
+ }),
title: this.gettext('Window _Size'),
});
- const percent_format = new Intl.NumberFormat(undefined, { style: 'percent' });
- window_size_row.set_format_value_func((_, v) => percent_format.format(v));
-
- this.settings.bind_writable(
- 'window-size',
- window_size_row,
- 'sensitive',
- false
- );
-
- this.add(window_size_row);
+ this.add_scale_row({
+ key: 'window-size-secondary',
+ adjustment: new Gtk.Adjustment({
+ upper: 1,
+ step_increment: 0.01,
+ page_increment: 0.10,
+ }),
+ title: this.gettext('Window Size Secondary'),
+ });
}
}
diff --git a/ddterm/pref/shortcuts.js b/ddterm/pref/shortcuts.js
index 47831d5f1..38ed8e867 100644
--- a/ddterm/pref/shortcuts.js
+++ b/ddterm/pref/shortcuts.js
@@ -533,6 +533,16 @@ export class ApplicationShortcutGroup extends ShortcutGroup {
title: this.gettext('Decrease Window Size'),
});
+ this.add_shortcut_row({
+ key: 'shortcut-window-size-secondary-inc',
+ title: this.gettext('Increase Secondary Window Size'),
+ });
+
+ this.add_shortcut_row({
+ key: 'shortcut-window-size-secondary-dec',
+ title: this.gettext('Decrease Secondary Window Size'),
+ });
+
this.add_shortcut_row({
key: 'shortcut-background-opacity-inc',
title: this.gettext('Increase Background Opacity'),
diff --git a/ddterm/pref/util.js b/ddterm/pref/util.js
index 81c816a15..c8c4a0479 100644
--- a/ddterm/pref/util.js
+++ b/ddterm/pref/util.js
@@ -558,6 +558,38 @@ export class ScaleRow extends ActionRow {
}
}
+function create_scale_row({
+ settings,
+ key,
+ adjustment,
+ flags = Gio.SettingsBindFlags.DEFAULT,
+ percent = true,
+ ...params
+}) {
+ const row = new ScaleRow({
+ visible: true,
+ use_underline: true,
+ adjustment,
+ ...params,
+ });
+
+ settings.bind(key, adjustment, 'value', flags);
+
+ settings.bind_writable(
+ key,
+ row,
+ 'sensitive',
+ false
+ );
+
+ if (percent) {
+ const percent_format = new Intl.NumberFormat(undefined, { style: 'percent' });
+ row.set_format_value_func((_, v) => percent_format.format(v));
+ }
+
+ return row;
+}
+
export class ExpanderRow extends AdwOrHdy.ExpanderRow {
static [GObject.GTypeName] = 'DDTermExpanderRow';
@@ -676,6 +708,14 @@ export class PreferencesGroup extends AdwOrHdy.PreferencesGroup {
return row;
}
+
+ add_scale_row(params) {
+ const row = create_scale_row({ settings: this.settings, ...params });
+
+ this.add(row);
+
+ return row;
+ }
}
export class PreferencesPage extends AdwOrHdy.PreferencesPage {
diff --git a/ddterm/shell/geometry.js b/ddterm/shell/geometry.js
index a81bd9531..d3d679d9e 100644
--- a/ddterm/shell/geometry.js
+++ b/ddterm/shell/geometry.js
@@ -78,6 +78,15 @@ export const WindowGeometry = GObject.registerClass({
1,
0.6
),
+ 'window-size-secondary': GObject.ParamSpec.double(
+ 'window-size-secondary',
+ null,
+ null,
+ GObject.ParamFlags.READWRITE | GObject.ParamFlags.EXPLICIT_NOTIFY,
+ 0,
+ 1,
+ 1
+ ),
'window-position': GObject.ParamSpec.enum(
'window-position',
null,
@@ -124,6 +133,7 @@ export const WindowGeometry = GObject.registerClass({
);
this.connect('notify::window-size', this.#update_target_rect.bind(this));
+ this.connect('notify::window-size-secondary', this.#update_target_rect.bind(this));
this.connect('notify::window-position', this.#update_window_position.bind(this));
this.connect('notify::window-monitor', this.update_monitor.bind(this));
this.connect('notify::window-monitor-connector', this.update_monitor.bind(this));
@@ -139,24 +149,35 @@ export const WindowGeometry = GObject.registerClass({
}
}
- static get_target_rect(workarea, monitor_scale, size, window_pos) {
+ static get_target_rect(workarea, monitor_scale, size, size_secondary, window_pos) {
const target_rect = workarea.copy();
- if (size === 1)
- return target_rect;
-
if (window_pos === Meta.Side.LEFT || window_pos === Meta.Side.RIGHT) {
- target_rect.width *= size;
- target_rect.width -= target_rect.width % monitor_scale;
+ if (size !== 1) {
+ target_rect.width *= size;
+ target_rect.width -= target_rect.width % monitor_scale;
- if (window_pos === Meta.Side.RIGHT)
- target_rect.x += workarea.width - target_rect.width;
- } else {
- target_rect.height *= size;
+ if (window_pos === Meta.Side.RIGHT)
+ target_rect.x += workarea.width - target_rect.width;
+ }
+ target_rect.height *= size_secondary;
target_rect.height -= target_rect.height % monitor_scale;
+ target_rect.height = Math.floor(target_rect.height);
+
+ target_rect.y += Math.floor((workarea.height - target_rect.height) / 2);
+ } else {
+ if (size !== 1) {
+ target_rect.height *= size;
+ target_rect.height -= target_rect.height % monitor_scale;
+
+ if (window_pos === Meta.Side.BOTTOM)
+ target_rect.y += workarea.height - target_rect.height;
+ }
+ target_rect.width *= size_secondary;
+ target_rect.width -= target_rect.width % monitor_scale;
+ target_rect.width = Math.floor(target_rect.width);
- if (window_pos === Meta.Side.BOTTOM)
- target_rect.y += workarea.height - target_rect.height;
+ target_rect.x += Math.floor((workarea.width - target_rect.width) / 2);
}
return target_rect;
@@ -165,6 +186,7 @@ export const WindowGeometry = GObject.registerClass({
bind_settings(settings) {
[
'window-size',
+ 'window-size-secondary',
'window-position',
'window-monitor',
'window-monitor-connector',
@@ -356,6 +378,7 @@ export const WindowGeometry = GObject.registerClass({
this.#workarea,
Math.floor(this.#monitor_scale),
this.window_size,
+ this.window_size_secondary,
this.window_position
);
diff --git a/ddterm/shell/wm.js b/ddterm/shell/wm.js
index e1859118e..c8a2f24e6 100644
--- a/ddterm/shell/wm.js
+++ b/ddterm/shell/wm.js
@@ -115,6 +115,7 @@ export const WindowManager = GObject.registerClass({
'changed::window-above': this.#set_window_above.bind(this),
'changed::window-stick': this.#set_window_stick.bind(this),
'changed::window-size': this.#disable_window_maximize_setting.bind(this),
+ 'changed::window-size-secondary': this.#disable_window_maximize_setting.bind(this),
'changed::window-maximize': this.#set_window_maximized.bind(this),
'changed::hide-when-focus-lost': this.#setup_hide_when_focus_lost.bind(this),
}).map(
@@ -578,11 +579,17 @@ export const WindowManager = GObject.registerClass({
this.logger?.log('Updating size setting on grab end');
const frame_rect = win.get_frame_rect();
- const size = this.geometry.orientation === Clutter.Orientation.HORIZONTAL
+
+ const primary = this.geometry.orientation === Clutter.Orientation.HORIZONTAL
? frame_rect.width / this.geometry.workarea.width
: frame_rect.height / this.geometry.workarea.height;
- this.settings.set_double('window-size', Math.min(1.0, size));
+ const secondary = this.geometry.orientation === Clutter.Orientation.HORIZONTAL
+ ? frame_rect.height / this.geometry.workarea.height
+ : frame_rect.width / this.geometry.workarea.width;
+
+ this.settings.set_double('window-size', Math.min(1.0, primary));
+ this.settings.set_double('window-size-secondary', Math.min(1.0, secondary));
}
#unmaximize_for_resize(flags) {
@@ -596,6 +603,7 @@ export const WindowManager = GObject.registerClass({
// There is a _update_window_geometry() call after successful unmaximize.
// It must set window size to 100%.
this.settings.set_double('window-size', 1.0);
+ this.settings.set_double('window-size-secondary', 1.0);
Main.wm.skipNextEffect(this.#actor);
this.#set_unmaximize_flags(flags);
diff --git a/schemas/com.github.amezin.ddterm.gschema.xml b/schemas/com.github.amezin.ddterm.gschema.xml
index 5e8f01149..e47b01099 100644
--- a/schemas/com.github.amezin.ddterm.gschema.xml
+++ b/schemas/com.github.amezin.ddterm.gschema.xml
@@ -138,6 +138,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
0.6
+
+ 1.0
+
+
false
@@ -385,6 +389,13 @@ SPDX-License-Identifier: GPL-3.0-or-later
Up']]]>
+
+ Down']]]>
+
+
+
+ Up']]]>
+