From 6c6bf6c4a37b8f9b0b0366e33fd5948946f48069 Mon Sep 17 00:00:00 2001 From: Aleksandr Mezin Date: Tue, 2 Feb 2021 07:05:08 +0600 Subject: [PATCH] wayland: unmaximize window before resizing 1. Don't auto-unmaximize window on show if target height is 100%. 2. Unmaximize the window before resizing. For resizing with mouse - request unmaximization through d-bus (there's no Gtk API to unmaximize vertically only) Fixes #21 on Wayland. --- Makefile | 2 +- appwindow.js | 13 +++++++ com.github.amezin.ddterm.Extension.xml | 8 +++++ extension.js | 47 +++++++++++++++++++++++--- 4 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 com.github.amezin.ddterm.Extension.xml diff --git a/Makefile b/Makefile index 9d6f16f3..ed2c42c6 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ prefs enable disable reset info show: .PHONY: prefs enable disable reset info show EXTENSION_PACK := $(EXTENSION_UUID).shell-extension.zip -EXTRA_SOURCES := $(filter-out extension.js prefs.js handlebars.js,$(wildcard *.ui *.js *.css)) com.github.amezin.ddterm handlebars.js +EXTRA_SOURCES := $(filter-out extension.js prefs.js handlebars.js,$(wildcard *.ui *.js *.css)) com.github.amezin.ddterm handlebars.js com.github.amezin.ddterm.Extension.xml $(EXTENSION_PACK): $(SCHEMAS) $(EXTRA_SOURCES) extension.js prefs.js metadata.json gnome-extensions pack -f $(addprefix --schema=,$(SCHEMAS)) $(addprefix --extra-source=,$(EXTRA_SOURCES)) . diff --git a/appwindow.js b/appwindow.js index b5dfbb2a..fc105852 100644 --- a/appwindow.js +++ b/appwindow.js @@ -4,6 +4,13 @@ const { GLib, GObject, Gio, Gdk, Gtk } = imports.gi; const { util } = imports; +const ByteArray = imports.byteArray; + +const EXTENSION_DBUS_XML = ByteArray.toString( + util.APP_DATA_DIR.get_child('com.github.amezin.ddterm.Extension.xml').load_contents(null)[1] +); + +var ExtensionDBusProxy = Gio.DBusProxy.makeProxyWrapper(EXTENSION_DBUS_XML); var AppWindow = GObject.registerClass( { @@ -25,6 +32,10 @@ var AppWindow = GObject.registerClass( _init(params) { super._init(params); + this.extension_dbus = new ExtensionDBusProxy( + Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell/Extensions/ddterm' + ); + this.method_handler(this, 'realize', this.set_wm_functions); this.method_handler(this, 'screen-changed', this.setup_rgba_visual); @@ -181,6 +192,8 @@ var AppWindow = GObject.registerClass( if (!button_ok || button !== Gdk.BUTTON_PRIMARY) return; + this.extension_dbus.BeginResizeSync(); + const [coords_ok, x_root, y_root] = event.get_root_coords(); if (!coords_ok) return; diff --git a/com.github.amezin.ddterm.Extension.xml b/com.github.amezin.ddterm.Extension.xml new file mode 100644 index 00000000..a4f8c154 --- /dev/null +++ b/com.github.amezin.ddterm.Extension.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/extension.js b/extension.js index 07028a8c..c83ced61 100644 --- a/extension.js +++ b/extension.js @@ -3,6 +3,7 @@ /* exported init enable disable */ const { GObject, Gio, Meta, Shell } = imports.gi; +const ByteArray = imports.byteArray; const Main = imports.ui.main; const Me = imports.misc.extensionUtils.getCurrentExtension(); @@ -26,6 +27,27 @@ const IS_WAYLAND_COMPOSITOR = Meta.is_wayland_compositor(); const USE_WAYLAND_CLIENT = Meta.WaylandClient && IS_WAYLAND_COMPOSITOR; const SIGINT = 2; +class ExtensionDBusInterface { + constructor() { + let [_, xml] = Me.dir.get_child('com.github.amezin.ddterm.Extension.xml').load_contents(null); + this.dbus = Gio.DBusExportedObject.wrapJSObject(ByteArray.toString(xml), this); + } + + BeginResize() { + if (!current_window || !current_window.maximized_vertically) + return; + + const workarea = workarea_for_window(current_window); + const target_rect = target_rect_for_workarea(workarea); + + Main.wm.skipNextEffect(current_window.get_compositor_private()); + current_window.unmaximize(Meta.MaximizeFlags.VERTICAL); + move_resize_window(current_window, target_rect); + } +} + +const DBUS_INTERFACE = new ExtensionDBusInterface().dbus; + class WaylandClientStub { constructor(subprocess_launcher) { this.subprocess_launcher = subprocess_launcher; @@ -80,9 +102,13 @@ function enable() { settings.connect('changed::window-stick', set_window_stick); settings.connect('changed::window-height', update_window_height); settings.connect('changed::window-skip-taskbar', set_skip_taskbar); + + DBUS_INTERFACE.export(Gio.DBus.session, '/org/gnome/Shell/Extensions/ddterm'); } function disable() { + DBUS_INTERFACE.unexport(); + if (Main.sessionMode.allowExtensions) { // Stop the app only if the extension isn't being disabled because of // lock screen/switch to other mode where extensions aren't allowed. @@ -247,8 +273,6 @@ function track_window(win) { const workarea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.currentMonitor.index); const target_rect = target_rect_for_workarea(workarea); - const max_height = workarea.height - (win.get_client_type() === Meta.WindowClientType.X11 ? 0 : 1); - target_rect.height = Math.min(target_rect.height, max_height); move_resize_window(win, target_rect); @@ -282,7 +306,13 @@ function unmaximize_window(win) { if (!win || win !== current_window) return; - if (win.maximized_vertically) + if (!win.maximized_vertically) + return; + + const workarea = workarea_for_window(current_window); + const target_rect = target_rect_for_workarea(workarea); + + if (target_rect.height < workarea.height) win.unmaximize(Meta.MaximizeFlags.VERTICAL); } @@ -321,8 +351,15 @@ function update_window_height() { return; const target_rect = target_rect_for_workarea(workarea); - if (!target_rect.equal(current_window.get_frame_rect())) - move_resize_window(current_window, target_rect); + if (target_rect.equal(current_window.get_frame_rect())) + return; + + if (current_window.maximized_vertically && target_rect.height < workarea.height) { + Main.wm.skipNextEffect(current_window.get_compositor_private()); + current_window.unmaximize(Meta.MaximizeFlags.VERTICAL); + } + + move_resize_window(current_window, target_rect); } function untrack_window(win) {