diff --git a/window-controls-applet@sapphirus.org/applet.js b/window-controls-applet@sapphirus.org/applet.js index 2c45465..b3733df 100644 --- a/window-controls-applet@sapphirus.org/applet.js +++ b/window-controls-applet@sapphirus.org/applet.js @@ -1,10 +1,9 @@ /* Window Controls Applet for the Cinnamon Desktop Environment - * Copyright (C) 2017-2022 Xavier (sapphirus@azorium.net) + * Copyright (C) 2017-2023 Xavier (sapphirus@azorium.net) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * the Free Software Foundation, with only version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -25,6 +24,7 @@ const Settings = imports.ui.settings; const Main = imports.ui.main; const Meta = imports.gi.Meta; const WindowTracker = imports.gi.Cinnamon.WindowTracker; +const GLib = imports.gi.GLib; const _WindowTracker = WindowTracker.get_default(); const WorkspaceManager = global.display.get_workspace_manager(); @@ -34,8 +34,11 @@ const VERBOSE = 1; const ERROR = 2; const ALL = 3; -class Logger { +const MAXIMIZE = 'maximize'; +const MINIMIZE = 'minimize'; +const CLOSE = 'close'; +class Logger { constructor(omittanceLevel, loggerName) { this.omittanceLevel = omittanceLevel; this.loggerName = loggerName; @@ -55,23 +58,73 @@ class Logger { } } - setLoggingLevel(level) { + getOmittance() { + return this.omittanceLevel; + } + + setOmittance(level) { this.omittanceLevel = level; } +} + + +class ButtonEvent { + constructor(wca, buttonType) { + this.wca = wca; + this.logger = wca.logger; + this.buttonType = buttonType; + } + + eventHandler(actor, event) { + let button = event.get_button(); + this.wca.logger.log(VERBOSE, "Button event triggered for "+button+" "+this.buttonType); + if (button == 1) { + return this._buttonPress(); + } else if(button == 3) { + this._applet_context_menu.toggle(); + return true; + } + return false; + } + + _buttonPress() { + let activeWindow = this.wca.getActiveWindow(); + let app = _WindowTracker.get_window_app(activeWindow); + if(!activeWindow || !app) + return false; + switch(this.buttonType) { + case MINIMIZE: + activeWindow.minimize(); + this.loggger.log(VERBOSE, "Minimised Window: "+ activeWindow.get_title()); + return true; + case MAXIMIZE: + if (activeWindow.get_maximized()) activeWindow.unmaximize(3); else activeWindow.maximize(3); + this.logger.log(VERBOSE, "Maximize Window toggle: "+ activeWindow.get_title()); + return true; + case CLOSE: + activeWindow.delete(global.get_current_time()); + this.logger.log(VERBOSE, "Closed Window: "+activeWindow.get_title()); + return true; + } + return false; + } } class WindowControlApplet extends Applet.Applet { - constructor(metadata, orientation, panelHeight, instance_id) { - super(orientation, panelHeight, instance_id); + constructor(metadata, orientation, panelHeight, instanceId) { + super(orientation, panelHeight, instanceId); this.logger = new Logger(INFO, UUID); this.appletPath=metadata.path; - this.instance_id = instance_id; + this.instanceId = instanceId; + this.monitorId = this.panel.monitorIndex; + this.themePath = ""; try { this._initialize_settings(); this.logger.log(VERBOSE, "Intialised Settings!"); this._initialize_events(); this.logger.log(VERBOSE, "Intialised Events!"); + this._loadTheme(); this._initialize_buttons(); this.logger.log(VERBOSE, "Intialised Buttons!"); this._on_panel_edit_mode_changed(); @@ -93,180 +146,103 @@ class WindowControlApplet extends Applet.Applet { global.display.connect('showing-desktop-changed', Lang.bind(this, this._windowChange)); } _initialize_buttons() { + this.button = []; let buttons=this.button_layout.split(':'); - if(this._checkButton(buttons,'maximize') || this._checkButton(buttons,'minimize') || this._checkButton(buttons,'close')){ - this._loadTheme(); - } - this.button = []; - this._createButtons(this.button_layout); - } + for (let i = 0; i < buttons.length; i++) { + if(!this._checkButton(buttons[i])) + continue; + this._createButton(buttons[i]); + } + } _initialize_settings() { - this.settings = new Settings.AppletSettings(this, UUID, this.instance_id); + this.settings = new Settings.AppletSettings(this, UUID, this.instanceId); this.settings.bindProperty(Settings.BindingDirection.IN,"button-layout","button_layout",this._bind_settings,null); this.settings.bindProperty(Settings.BindingDirection.IN,"button-theme","button_theme", this._bind_settings,null); this.settings.bindProperty(Settings.BindingDirection.IN,"only-maximized", "onlyMaximized", this._bind_settings,null); - this.settings.bindProperty(Settings.BindingDirection.IN,"verbose-log", "verbose_logging", this._set_logging,null); - this._set_logging(); + this.settings.bindProperty(Settings.BindingDirection.IN,"verbose-log", "verbose_logging", this._bind_logging,null); + this._bind_logging(); } - _set_logging() { - let loggingLevel = (this.verbose_logging ? ALL : INFO); - this.logger.log(VERBOSE, "Set logging level to "+loggingLevel); - this.logger.setLoggingLevel(loggingLevel); + _bind_logging() { + let omittance = (this.verbose_logging ? ALL : INFO); + this.logger.setOmittance(omittance); + this.logger.log(VERBOSE, "Debugging enabled."); } _bind_settings() { - this.actor.destroy_all_children(); + this.actor.destroy_all_children(); this._initialize_buttons(); + this._windowChange(); } _on_panel_edit_mode_changed() { let reactive = !global.settings.get_boolean('panel-edit-mode'); let b=this.button_layout.split(':'); - for (let i=0; i < b.length; ++i ){ + for (let i = 0; i < b.length; i++){ this.button[b[i]].reactive=reactive; } } _getCssPath(theme) { - let cssPath = this.appletPath + '/themes/'+theme+'/style.css'; - return cssPath; + return this.appletPath + '/themes/'+theme+'/style.css'; } _loadTheme(){ this.actor.set_style_class_name("window-buttons"); let theme = St.ThemeContext.get_for_stage(global.stage).get_theme(); - let theme_path = this._getCssPath(this.button_theme); - theme.load_stylesheet(theme_path); - } - - _createButtons(buttonLayout) { - buttonLayout=buttonLayout.split(':'); - for (let i=0; i < buttonLayout.length; ++i ){ - let buttonName="_"+buttonLayout[i]+"Button"; - this[buttonName](); - } - - } - - _minimizeButton() { - this.button['minimize'] = new St.Button({ name: 'windowButton', style_class: 'minimize window-button', reactive: true }); - this.actor.add(this.button['minimize']); - this.button['minimize'].connect('button-press-event', Lang.bind(this,function(actor,event){ - let button = event.get_button(); - if (button == 1) { - this._minimizeWindow(); - return true; - } else if(button == 3) { - this._applet_context_menu.toggle(); - return true; - } - return false; - })); - } - - _minimizeWindow() { - let activeWindow = this._getActiveWindow(); - let app = _WindowTracker.get_window_app(activeWindow); - if(!activeWindow || !app) - return; - activeWindow.minimize(); - } - - _maximizeButton() { - this.button['maximize'] = new St.Button({ name: 'windowButton'+this.instance_id, style_class: 'maximize window-button', reactive: true }); - this.actor.add(this.button['maximize']); - - this.button['maximize'].connect('button-press-event', Lang.bind(this,function(actor,event){ - let button = event.get_button(); - if (button == 1) { - this._maximizeWindow(); - return true; - } else if(button == 3){ - this._applet_context_menu.toggle(); - return true; - } - return false; - })); - } - - _maximizeWindow() { - let activeWindow = this._getActiveWindow(); - let app = _WindowTracker.get_window_app(activeWindow); - if(!activeWindow || !app) - return; - - if (activeWindow.get_maximized()) { - activeWindow.unmaximize(3); - } else { - activeWindow.maximize(3); - } - } - - _closeButton() { - this.button['close'] = new St.Button({ name: 'windowButton', style_class: 'close window-button', reactive: true }); - this.actor.add(this.button['close']); - this.button['close'].connect('button-press-event', Lang.bind(this,function(actor,event){ - let button = event.get_button(); - if (button == 1) { - this._closeWindow(); - return true; - } else if(button == 3){ - this._applet_context_menu.toggle(); - return true; - } - return false; - })); - } - - _closeWindow() { - let activeWindow = this._getActiveWindow(); - let app = _WindowTracker.get_window_app(activeWindow); - if(!activeWindow || !app) - return; - this.logger.log(INFO, "Closed!"); - activeWindow.delete(global.get_current_time()); - } - - _getActiveWindow() { - let workspace = WorkspaceManager.get_active_workspace(); - let windows = workspace.list_windows(); - for (var i = 0; i < windows.length; i++) { - let w = windows[i]; - let thisMonitor = (w.get_monitor() == this.panel.monitorIndex); - if(!thisMonitor) - continue; - if(((w.get_maximized() === Meta.MaximizeFlags.BOTH) && (w.get_window_type() != Meta.WindowType.DESKTOP) && !w.minimized && thisMonitor)) - return w; + let themePath = this._getCssPath(this.button_theme); + if(!GLib.file_test(themePath, GLib.FileTest.EXISTS)) { + this.logger.log(INFO, "Theme at "+themePath+" does not exist."); + themePath = this._getCssPath("default"); } + theme.load_stylesheet(themePath); + this.themePath = themePath; + } + + _createButton(type) { + this.button[type] = new St.Button({ name: 'windowButton', style_class: type + ' window-button', reactive: true }); + this.actor.add(this.button[type]); + let buttonEvent = new ButtonEvent(this, type); + this.button[type].connect('button-press-event', Lang.bind(buttonEvent, buttonEvent.eventHandler)); + this.logger.log(VERBOSE, "Created "+type+" button!"); + } + + getActiveWindow() { + this.logger.log(VERBOSE, "Event signal triggered"); + let workspace = WorkspaceManager.get_active_workspace(); + let windows = workspace.get_display().sort_windows_by_stacking(workspace.list_windows()); + for (var i = windows.length - 1; i >= 0; i--) { + let w = windows[i]; + if(((!(w.get_maximized() === Meta.MaximizeFlags.BOTH) + || (w.get_window_type() == Meta.WindowType.DESKTOP) + || w.minimized) && this.onlyMaximized) + || w.get_monitor() != this.monitorId) + continue; + return w; + + } + this.logger.log(VERBOSE, "Active window not found."); return false; } - _windowChange(destroy) { + _windowChange() { if(!this.onlyMaximized) return; - if(!this._getActiveWindow()) this._toggleButtons(false); else this._toggleButtons(true); - + this._toggleButtons(this.getActiveWindow() != false); } - _checkButton(arr, obj) { - for(var i=0; i