Skip to content

Commit

Permalink
[CinnamonBurnMyWindows@klangman] App-specific setting & "none" option (
Browse files Browse the repository at this point in the history
…#731)

1. Added application-specific effect settings that override the default effects setting when a specific application window is opened/closed
2. Added a "none" options to the effect drop-down lists which will perform no effect and allow the Cinnamon default effect to apply
3. Added a button in the General configuration tab which will add an "Application-Specific Settings" table entry for the application of the window that last had the focus
  • Loading branch information
klangman authored Sep 9, 2024
1 parent cfb5820 commit 4a32aef
Show file tree
Hide file tree
Showing 9 changed files with 343 additions and 60 deletions.
6 changes: 6 additions & 0 deletions CinnamonBurnMyWindows@klangman/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 0.9.2

* Added application specific effect settings that override the default effects setting when a specific application window is opened/closed
* Added a "none" options to the effect drop-down lists which will perform no effect and allow the cinnamon default effect to apply
* Added a button in the General configuration tab which will add an "Application Specific Settings" table entry for the application of the window that last had the focused.

## 0.9.1

* Initial version committed to cinnamon spices
6 changes: 1 addition & 5 deletions CinnamonBurnMyWindows@klangman/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This extension needs the Cinnamon.GLSLEffect class which is only available in Ci

## Known issues

In the setting configure window under the "Effect Settings" tab, when changing the "Show setting for effect" drop-down to select a different effect, sometimes the contents under the "Effect Specific Settings" title will not properly update. Because of this only a subset of the available options are visible. I believe this is a Cinnamon bug. You can force Cinnamon to properly redraw the options by selecting the "General" tab then selecting the "Effect Settings" tab again. After that, the complete set of "Effect Specific Settings" should be visible.
In the setting configure window under the "Effect Settings" tab, when changing the "Show setting for effect" drop-down to select a different effect, sometimes the contents under the "Effect Specific Settings" title will not properly update. Because of this, only a subset of the available options are visible. I believe this is a Cinnamon bug. You can force Cinnamon to properly redraw the options by selecting the "General" tab then selecting the "Effect Settings" tab again. After that, the complete set of "Effect Specific Settings" should be visible.

When closing the Steam Client "setting" window the 'close window effect' does not show the windows contents, resulting in the closing effect to show where the window had existed but otherwise has no negative effect.

Expand Down Expand Up @@ -58,10 +58,6 @@ Because Cinnamon is missing a required API, the following effects are disabled.
- Snap Of Disintegration
- TRex Attack

## Possible future enhancements

- Specifying effects that apply to specific application windows. i.e Selecting which effect occurs when closing Firefox.

## Installation

1. Right click on the cinnamon panel and click "System Settings"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,21 +88,23 @@ class ShouldAnimateManager {
}

handler(actor, types) {
const isNormalWindow = actor.meta_window.window_type == Meta.WindowType.NORMAL;
const isDialogWindow = actor.meta_window.window_type == Meta.WindowType.MODAL_DIALOG || actor.meta_window.window_type == Meta.WindowType.DIALOG;
if (actor) {
const isNormalWindow = actor.meta_window.window_type == Meta.WindowType.NORMAL;
const isDialogWindow = actor.meta_window.window_type == Meta.WindowType.MODAL_DIALOG || actor.meta_window.window_type == Meta.WindowType.DIALOG;

if (isNormalWindow || isDialogWindow) {
let stack = (new Error()).stack;
let event = (stack.includes('_minimizeWindow@' )) ? Events.Minimize : 0;
event += (stack.includes('_unminimizeWindow@')) ? Events.Unminimize : 0;
event += (stack.includes('_mapWindow@' )) ? Events.MapWindow : 0;
event += (stack.includes('_destroyWindow@' )) ? Events.DestroyWindow : 0;
if (isNormalWindow || isDialogWindow) {
let stack = (new Error()).stack;
let event = (stack.includes('_minimizeWindow@' )) ? Events.Minimize : 0;
event += (stack.includes('_unminimizeWindow@')) ? Events.Unminimize : 0;
event += (stack.includes('_mapWindow@' )) ? Events.MapWindow : 0;
event += (stack.includes('_destroyWindow@' )) ? Events.DestroyWindow : 0;

for (let i=0 ; i<Main.wm._shouldAnimateManager.length ; i++) {
if (event === (Main.wm._shouldAnimateManager[i].event & event)) {
let ret = Main.wm._shouldAnimateManager[i].handler(actor, types, event);
if (ret != RUN_ORIGINAL_FUNCTION) {
return ret;
for (let i=0 ; i<Main.wm._shouldAnimateManager.length ; i++) {
if (event === (Main.wm._shouldAnimateManager[i].event & event)) {
let ret = Main.wm._shouldAnimateManager[i].handler(actor, types, event);
if (ret != RUN_ORIGINAL_FUNCTION) {
return ret;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ const GLib = imports.gi.GLib;
const Settings = imports.ui.settings;
const MessageTray = imports.ui.messageTray;
const St = imports.gi.St;

const RANDOMIZED = 999;
const Cinnamon = imports.gi.Cinnamon;
const SignalManager = imports.misc.signalManager;

const Effect = {
Apparition: 0,
Expand All @@ -65,7 +65,9 @@ const Effect = {
Portal: 15,
TVEffect: 18,
TVGlitch: 19,
Wisps: 20
Wisps: 20,
Randomized: 999,
None: 1000
}

const UUID = "CinnamonBurnMyWindows@klangman";
Expand Down Expand Up @@ -127,6 +129,13 @@ class BurnMyWindows {
// Store a reference to the settings object.
this._settings = new Settings.ExtensionSettings(this, this.meta.uuid);

// Keep track of the previously focused Application
this._signalManager = new SignalManager.SignalManager(null);
this._signalManager.connect(global.display, "notify::focus-window", this._onFocusChanged, this);

// WindowTracker so we can map windows to application
this._windowTracker = Cinnamon.WindowTracker.get_default();

// We will use extensionThis to refer to the extension inside the patched methods.
const extensionThis = this;

Expand Down Expand Up @@ -209,6 +218,8 @@ class BurnMyWindows {
// This function could be called after the extension is uninstalled, disabled in GNOME
// Tweaks, when you log out or when the screen locks.
disable() {
// Stop monitoring focus changes
this._signalManager.disconnectAllSignals();

// Free all effect resources.
this._ALL_EFFECTS = [];
Expand All @@ -224,12 +235,21 @@ class BurnMyWindows {
// Choose an effect based on the users preferences as defined in the setting for the current window action
_chooseEffect(actor, forOpening) {
let effectIdx;
let appRule = this.getAppRule(actor.meta_window);
if (forOpening) {
effectIdx = this._settings.getValue("open-window-effect");
if (appRule)
effectIdx = appRule.open;
else
effectIdx = this._settings.getValue("open-window-effect");
} else {
effectIdx = this._settings.getValue("close-window-effect");
if (appRule)
effectIdx = appRule.close;
else
effectIdx = this._settings.getValue("close-window-effect");
}
if (effectIdx != RANDOMIZED) {
if (effectIdx === Effect.None) {
return(null);
} else if (effectIdx != Effect.Randomized) {
// Return the effect that the setting reflects
return {effect: this._ALL_EFFECTS[effectIdx], profile: this._settings};
} else {
Expand Down Expand Up @@ -273,6 +293,24 @@ class BurnMyWindows {
}
}

// Get the application specific rules for the given metaWindow
getAppRule(metaWindow) {
let app = this._windowTracker.get_window_app(metaWindow);
if (!app) {
app = this._windowTracker.get_app_from_pid(metaWindow.get_pid());
}
if (app && !app.is_window_backed()) {
let appID = app.get_id();
let appRules = this._settings.getValue("app-rules");
for( let i=0 ; i < appRules.length ; i++ ) {
if (appRules[i].enabled && appRules[i].application == appID) {
return(appRules[i]);
}
}
}
return(null);
}

// This method adds the given effect using the settings from the given profile to the
// given actor.
_setupEffect(actor, forOpening, effect, profile) {
Expand Down Expand Up @@ -357,33 +395,55 @@ class BurnMyWindows {
shader.beginAnimation(profile, forOpening, testMode, duration, actor);
}

// This is required to enable window-close animations in the overview. See the comment
// for Workspace.prototype._windowRemoved above for an explanation.
_shouldDestroy(workspace, metaWindow) {
const index = workspace._lookupIndex(metaWindow);
if (index == -1) {
return true;
}

const actor = workspace._windows[index]._windowActor;
const shader = actor.get_effect('burn-my-windows-effect');
_onFocusChanged() {
this.prev_focused_window = this.last_focused_window;
this.last_focused_window = global.display.get_focus_window();
}

return shader == null;
on_config_button_pressed() {
if (this.prev_focused_window) {
let app = this._windowTracker.get_window_app(this.prev_focused_window);
if (!app) {
app = this._windowTracker.get_app_from_pid(this.prev_focused_window.get_pid());
}
if (app && !app.is_window_backed()) {
let appRules = this._settings.getValue("app-rules");
appRules.push( {enabled:false, open:0, close:0, application:app.get_id()} );
this._settings.setValue("app-rules", appRules);
} else {
let source = new MessageTray.Source(this.meta.name);
let notification = new MessageTray.Notification(source, _("Error") + ": " + this.meta.name,
_("The previously focused window is not backed by an application and therefore application specific effects can not be applied to that window"),
{icon: new St.Icon({icon_name: "cinnamon-burn-my-window", icon_type: St.IconType.FULLCOLOR, icon_size: source.ICON_SIZE })}
);
Main.messageTray.add(source);
source.notify(notification);
}
}
}

}

let extension = null;

function enable() {
extension.enable();
extension.enable();
return Callbacks
}

function disable() {
extension.disable();
extension = null;
extension.disable();
extension = null;
}

function init(metadata) {
if(!extension) {
extension = new BurnMyWindows(metadata);
}
}

const Callbacks = {
on_config_button_pressed: function() {
extension.on_config_button_pressed()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"general-page" : {
"type" : "page",
"title" : "General",
"sections" : ["general-settings"]
"sections" : ["general-settings", "app-specific-settings"]
},
"effects-page" : {
"type" : "page",
Expand All @@ -25,6 +25,12 @@
"keys" : ["open-window-effect", "close-window-effect"]
},

"app-specific-settings" : {
"type" : "section",
"title" : "Application Specific Settings",
"keys" : ["app-rules","app-rules-button"]
},

"effect-selector-section" : {
"type" : "section",
"title" : "Effect Selector",
Expand Down Expand Up @@ -56,6 +62,63 @@
}
},

"app-rules": {
"type" : "list",
"description" : "Application Specific Rules",
"columns" : [
{"id": "enabled", "title": "Enabled", "type": "boolean", "default": true},
{"id": "open", "title": "Open Effect", "type": "integer", "default": 0, "options": {
"Apparition": 0,
"Doom": 2,
"Energize A": 3,
"Energize B": 4,
"Glide": 6,
"Glitch": 7,
"Hexagon": 8,
"Incinerate": 9,
"Pixelate": 12,
"Pixel Wheel": 13,
"Pixel Wipe": 14,
"Portal": 15,
"TV Effect": 18,
"TV Glitch": 19,
"Wisps": 20,
"Randomized": 999,
"None": 1000
}
},
{"id": "close", "title": "Close Effect", "type": "integer", "default": 0, "options": {
"Apparition": 0,
"Doom": 2,
"Energize A": 3,
"Energize B": 4,
"Glide": 6,
"Glitch": 7,
"Hexagon": 8,
"Incinerate": 9,
"Pixelate": 12,
"Pixel Wheel": 13,
"Pixel Wipe": 14,
"Portal": 15,
"TV Effect": 18,
"TV Glitch": 19,
"Wisps": 20,
"Randomized": 999,
"None": 1000
}
},
{"id": "application", "title": "Application", "type": "string"}
],
"tooltip": "A list of application with special effect rules",
"default": []
},
"app-rules-button" : {
"type" : "button",
"description" : "Add entry for the application of the most recently focused window",
"callback" : "on_config_button_pressed",
"tooltip" : "Focus a window you want to enable application specific setting for then return here and press this button."
},

"random-title" : {
"type" : "custom",
"file" : "CustomWidgets.py",
Expand Down Expand Up @@ -260,7 +323,8 @@
"TV Effect": 18,
"TV Glitch": 19,
"Wisps": 20,
"Randomized": 999
"Randomized": 999,
"None": 1000
},
"description": "Open window effect"
},
Expand All @@ -284,7 +348,8 @@
"TV Effect": 18,
"TV Glitch": 19,
"Wisps": 20,
"Randomized": 999
"Randomized": 999,
"None": 1000
},
"description": "Close window effect"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"uuid": "CinnamonBurnMyWindows@klangman",
"name": "Burn My Windows",
"version": "0.9.1",
"version": "0.9.2",
"description": "Window open/close effects based on the Burn-My-Windows Gnome extension by Schneegans",
"url": "https://github.com/klangman/CinnamonBurnMyWindows",
"website": "https://github.com/klangman/CinnamonBurnMyWindows",
Expand Down
Loading

0 comments on commit 4a32aef

Please sign in to comment.