Skip to content

Commit 06917f8

Browse files
authored
[CinnamonMagicLamp@klangman] Remove the need to change Effect settings (#721)
* Use _shouldAnimate() patching to prevent Cinnamon from animating the Minimize and Unminimize events. This means that users no longer need to disable the Effect settings in Cinnamon manually. Also means that the Cinnamon New Window animation can be enabled and active along with Magic Lamp effects (so you don't have to give up new window fade in effects in order to enable Magic Lamp). * This change introduces a class to manage patching _shouldAnimate(). My next extension will also need to patch _shouldAnimate() so I needed a way to coordinate the patching so that the two extensions can coexist. The ShouldAnimateManager class will be used in both extensions. This class will manage the patching of _shouldAnimate() and allow both extensions to intercept different calling contexts of _shouldAnimate(). * Some README changes.
1 parent 069e041 commit 06917f8

File tree

10 files changed

+209
-91
lines changed

10 files changed

+209
-91
lines changed
+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 1.0.2
4+
5+
* Removed the need to change the System-Settings->Effect settings to "none" for the Minimize/Unminimize options. This is now accomplished by intercepting a cinnamon API and forcing it to disable the Cinnamon Minimize/Unminimize effects while the MagicLamp extension is enabled.
6+
* Fixed some minor typos in the README.
7+
38
## 1.0.1
49

510
* Initial version committed to cinnamon spices

CinnamonMagicLamp@klangman/README.md

+3-8
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,13 @@ A compiz like magic lamp effect for the Cinnamon desktop based on hermes83's Gno
44

55
This Cinnamon extension will create a Magic Lamp minimize and unminimize effect
66

7-
## IMPORTANT
8-
9-
You must disable the Cinnamon Minimize and Unminimize effects as they will interfere with the operation of the Magic Lamp effect. Open the Menu->Preferences->Effects application and set the "New windows or unminimizing existing ones" and "Minimize windows" features to "None".
10-
117
## Requirements
128

139
Cinnamon 5.6.8 (Mint 21.1) or better.
1410

1511
To properly animate in relation to the window-list icon, you need to be using a window-list applet that sets the icon geometry. Otherwise the animation will animate from/to the middle of the monitor on the Cinnamon panel edge rather than an animation specific to the window. The pre-installed "Window list" and "Grouped window list" applets work fine as does "Cassia Window list" (version 2.3.2 or better). CobiWindowList does not currently set icon geometry.
1612

17-
This applet requires no other packages other than what is included in a default initialization of Mint 21.1 or better.
13+
This extension requires no other packages other than what is included in a default installation of Mint 21.1 or better.
1814

1915
## Known issues
2016

@@ -27,12 +23,11 @@ The Steam client for some reason does not support window cloning when minimized,
2723
3. Click the "Download" tab and then click the "Magic Lamp Effect" entry
2824
4. Click the "Install" button on the right and then return to the "Manage" tab
2925
6. Select the new "Magic Lamp Effect" entry and then click the "+" button at the bottom of the window
30-
7. **Important:** Open the Menu->Preferences->Effects application and change the Minimize and Unminimize effect options to "None"
31-
8. Use the "gears" icon next to the "Magic Lamp Effect" entry to open the setting window and setup the preferred behaviour
26+
7. Use the "gears" icon next to the "Magic Lamp Effect" entry to open the setting window and setup the preferred behaviour
3227

3328
## Feedback
3429

35-
Please leave a comment here on cinnamon-spices.linuxmint.com or you can create an issue on my "Cinnamon Magic Lap" development GitHub repository if you encounter any issues with this extension:
30+
Please leave a comment here on cinnamon-spices.linuxmint.com or you can create an issue on my "Cinnamon Magic Lamp" development GitHub repository if you encounter any issues with this extension:
3631

3732
https://github.com/klangman/CinnamonMagicLamp
3833

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* ShouldAnimateManager.js
3+
* Copyright (C) 2024 Kevin Langman <klangman@gmail.com>
4+
*
5+
* ShouldAnimateManager is free software: you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License as published by the
7+
* Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* ShouldAnimateManager is distributed in the hope that it will be useful, but
11+
* WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13+
* See the GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License along
16+
* with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*
18+
* The purpose of this module is to coordinate overriding the Main.wm._shouldAnimate()
19+
* function with more than one extension by "monkey-patching" the function. This class
20+
* will check if there is an existing override or not, install the override if needed
21+
* and track handlers.
22+
*
23+
* A new entry will need to provide an event to intercept, a handler function and
24+
* a extension name (uuid). If the event is already being handled by some other extension
25+
* then the extension name of the current handler will be returned to indicate an error.
26+
*
27+
* The handler function can return true or false which will then be returned to the caller
28+
* of _shouldAnimate(). If the handler would like to allow the original _shouldAnimate()
29+
* function to run, then the handler should return RUN_ORIGINAL_FUNCTION and the return
30+
* value from the original function will be returned to the caller.
31+
*
32+
*/
33+
34+
const Main = imports.ui.main;
35+
const Meta = imports.gi.Meta;
36+
37+
const Events = {
38+
Minimize: 1,
39+
Unminimize: 2,
40+
MapWindow: 4,
41+
DestroyWindow: 8
42+
}
43+
44+
const RUN_ORIGINAL_FUNCTION = 2
45+
46+
class ShouldAnimateManager {
47+
48+
constructor(uuid) {
49+
this._uuid = uuid;
50+
}
51+
52+
connect(event, handler) {
53+
if (Main.wm._shouldAnimateManager) {
54+
for (let i=0 ; i<Main.wm._shouldAnimateManager.length ; i++) {
55+
if ((Main.wm._shouldAnimateManager[i].event & event) != 0) {
56+
return Main.wm._shouldAnimateManager[i].owner;
57+
}
58+
}
59+
log( `Adding new ShouldAnimateManager handler for ${this._uuid} events ${event}` );
60+
Main.wm._shouldAnimateManager.push( {event: event, handler: handler, owner: this._uuid, override: this.handler} );
61+
} else {
62+
log( `Installed ShouldAnimateManager handler for ${this._uuid} events ${event}` );
63+
Main.wm._shouldAnimateManager = [ {event: event, handler: handler, owner: this._uuid, override: this.handler} ];
64+
Main.wm._shouldAnimateManager_Original_Function = Main.wm._shouldAnimate;
65+
Main.wm._shouldAnimate = this.handler;
66+
}
67+
return null;
68+
}
69+
70+
disconnect() {
71+
log( "in disconnect" );
72+
for (let i=0 ; i<Main.wm._shouldAnimateManager.length ; i++) {
73+
if (Main.wm._shouldAnimateManager[i].owner == this._uuid) {
74+
Main.wm._shouldAnimateManager.splice( i, 1 );
75+
// Setup a new _shouldAnimate override or restore the original if there are no manager entries left.
76+
if (Main.wm._shouldAnimateManager.length === 0) {
77+
log( `Removing the last ShouldAnimateManager entry (for ${this._uuid}), reinstalling the original handler function` );
78+
Main.wm._shouldAnimate = Main.wm._shouldAnimateManager_Original_Function;
79+
Main.wm._shouldAnimateManager_Original_Function = null;
80+
Main.wm._shouldAnimateManager = null;
81+
return;
82+
} else {
83+
log( `Removing the ShouldAnimateManager handler for ${this._uuid} and installing the override provided by ${Main.wm._shouldAnimateManager[0].owner}` );
84+
Main.wm._shouldAnimate = Main.wm._shouldAnimateManager[0].override;
85+
}
86+
}
87+
}
88+
}
89+
90+
handler(actor, types) {
91+
const isNormalWindow = actor.meta_window.window_type == Meta.WindowType.NORMAL;
92+
const isDialogWindow = actor.meta_window.window_type == Meta.WindowType.MODAL_DIALOG || actor.meta_window.window_type == Meta.WindowType.DIALOG;
93+
94+
if (isNormalWindow || isDialogWindow) {
95+
let stack = (new Error()).stack;
96+
let event = (stack.includes('_minimizeWindow@' )) ? Events.Minimize : 0;
97+
event += (stack.includes('_unminimizeWindow@')) ? Events.Unminimize : 0;
98+
event += (stack.includes('_mapWindow@' )) ? Events.MapWindow : 0;
99+
event += (stack.includes('_destroyWindow@' )) ? Events.DestroyWindow : 0;
100+
101+
for (let i=0 ; i<Main.wm._shouldAnimateManager.length ; i++) {
102+
if (event === (Main.wm._shouldAnimateManager[i].event & event)) {
103+
let ret = Main.wm._shouldAnimateManager[i].handler(actor, types, event);
104+
if (ret != RUN_ORIGINAL_FUNCTION) {
105+
return ret;
106+
}
107+
}
108+
}
109+
}
110+
return Main.wm._shouldAnimateManager_Original_Function.apply(this, [actor, types]);
111+
}
112+
113+
}

CinnamonMagicLamp@klangman/files/CinnamonMagicLamp@klangman/5.6/extension.js

+19-12
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ const Gettext = imports.gettext;
3636
const MessageTray = imports.ui.messageTray;
3737
const Panel = imports.ui.panel;
3838

39+
const ShouldAnimateManager = require("ShouldAnimateManager.js");
40+
3941
const MINIMIZE_EFFECT_NAME = "minimize-magic-lamp-effect";
4042
const UNMINIMIZE_EFFECT_NAME = "unminimize-magic-lamp-effect";
4143

@@ -64,30 +66,35 @@ class CinnamonMagicLamp {
6466

6567
enable() {
6668
this.settings = new Settings.ExtensionSettings(this, UUID);
67-
this.signalManager = new SignalManager.SignalManager(null);
68-
this.signalManager.connect(global.window_manager, "minimize", this._minimize, this);
69-
this.signalManager.connect(global.window_manager, "unminimize", this._unminimize, this);
7069

71-
// On first enable, show a notification telling the user that the extension was enabled,
72-
// and that they need to disable the default minimize/unminimize Cinnamon effects.
73-
if(this.settings.getValue("showNotification")) {
70+
// Register to intercept _shouldAnimate events
71+
this.shouldAnimateManager = new ShouldAnimateManager.ShouldAnimateManager( UUID );
72+
let error = this.shouldAnimateManager.connect(ShouldAnimateManager.Events.Minimize+ShouldAnimateManager.Events.Unminimize,
73+
function(actor, types, event) {
74+
// Override the cinnamon settings so Cinnamon will not attempt to animate the minimize/unminimize events
75+
return false;
76+
} );
77+
78+
if (error) {
7479
let source = new MessageTray.Source(this.meta.name);
75-
let notification = new MessageTray.Notification(source, this.meta.name + " " + _("has been enabled"),
76-
_("Please set the Cinnamon minimize and unminimize effects to None. These effects will interfere with the Cinnamon Magic Lap effects."),
80+
let notification = new MessageTray.Notification(source, _("ERROR") + ": " + this.meta.name + " " + _("was NOT enabled"),
81+
_("The existing extension") + " " + error + " " + _("conflicts with this extension."),
7782
{icon: new St.Icon({icon_name: "cinnamon-magic-lamp", icon_type: St.IconType.FULLCOLOR, icon_size: source.ICON_SIZE })}
7883
);
79-
notification.addButton("open-effects", _("Open Cinnamon Effects"));
80-
notification.connect("action-invoked", () => { Util.spawnCommandLineAsync("cinnamon-settings effects");});
8184
Main.messageTray.add(source);
8285
source.notify(notification);
83-
this.settings.setValue("showNotification", 0);
86+
} else {
87+
this.signalManager = new SignalManager.SignalManager(null);
88+
this.signalManager.connect(global.window_manager, "minimize", this._minimize, this);
89+
this.signalManager.connect(global.window_manager, "unminimize", this._unminimize, this);
8490
}
8591
}
8692

8793
disable() {
94+
// Disconnect for _shouldAnimate events
95+
this.shouldAnimateManager.disconnect();
8896
this.signalManager.disconnectAllSignals();
8997
global.get_window_actors().forEach((actor) => { this.destroyActorEffect(actor); });
90-
this.settings.setValue("showNotification", 1);
9198
}
9299

93100
_minimize(e, actor) {

CinnamonMagicLamp@klangman/files/CinnamonMagicLamp@klangman/5.6/settings-schema.json

-5
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,5 @@
4646
"step": 1,
4747
"description": "Y Tiles",
4848
"tooltip": "This effects the quality and the costs of the animation"
49-
},
50-
51-
"showNotification": {
52-
"type": "generic",
53-
"default": 1
5449
}
5550
}

CinnamonMagicLamp@klangman/files/CinnamonMagicLamp@klangman/metadata.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"uuid": "CinnamonMagicLamp@klangman",
33
"name": "Magic Lamp Effect",
4-
"version": "1.0.1",
4+
"version": "1.0.2",
55
"description": "A minimize/unminimize magic lamp effect based on hermes83's Gnome extension",
66
"url": "https://github.com/klangman/CinnamonMagicLamp",
77
"website": "https://github.com/klangman/CinnamonMagicLamp",

CinnamonMagicLamp@klangman/files/CinnamonMagicLamp@klangman/po/CinnamonMagicLamp@klangman.pot

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
1-
# SOME DESCRIPTIVE TITLE.
1+
# MAGIC LAMP EFFECT
22
# This file is put in the public domain.
3-
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
3+
# klangman, 2024
44
#
55
#, fuzzy
66
msgid ""
77
msgstr ""
8-
"Project-Id-Version: CinnamonMagicLamp@klangman 1.0.1\n"
8+
"Project-Id-Version: CinnamonMagicLamp@klangman 1.0.2\n"
99
"Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-"
1010
"extensions/issues\n"
11-
"POT-Creation-Date: 2024-08-18 10:47-0400\n"
12-
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13-
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14-
"Language-Team: LANGUAGE <LL@li.org>\n"
11+
"POT-Creation-Date: 2024-09-02 00:30-0400\n"
12+
"PO-Revision-Date: \n"
13+
"Last-Translator: \n"
14+
"Language-Team: \n"
1515
"Language: \n"
1616
"MIME-Version: 1.0\n"
1717
"Content-Type: text/plain; charset=UTF-8\n"
1818
"Content-Transfer-Encoding: 8bit\n"
1919

20-
#: 5.6/extension.js:75
21-
msgid "has been enabled"
20+
#. 5.6/extension.js:80
21+
msgid "ERROR"
2222
msgstr ""
2323

24-
#: 5.6/extension.js:76
25-
msgid ""
26-
"Please set the Cinnamon minimize and unminimize effects to None. These "
27-
"effects will interfere with the Cinnamon Magic Lap effects."
24+
#. 5.6/extension.js:80
25+
msgid "was NOT enabled"
26+
msgstr ""
27+
28+
#. 5.6/extension.js:81
29+
msgid "The existing extension"
2830
msgstr ""
2931

30-
#: 5.6/extension.js:79
31-
msgid "Open Cinnamon Effects"
32+
#. 5.6/extension.js:81
33+
msgid "conflicts with this extension."
3234
msgstr ""
3335

3436
#. metadata.json->name

CinnamonMagicLamp@klangman/files/CinnamonMagicLamp@klangman/po/ca.po

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
# SOME DESCRIPTIVE TITLE.
1+
# MAGIC LAMP EFFECT
22
# This file is put in the public domain.
3-
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
3+
# klangman, 2024
44
#
55
#, fuzzy
66
msgid ""
77
msgstr ""
88
"Project-Id-Version: CinnamonMagicLamp@klangman 1.0.1\n"
99
"Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-"
1010
"extensions/issues\n"
11-
"POT-Creation-Date: 2024-08-18 10:47-0400\n"
11+
"POT-Creation-Date: 2024-09-02 00:30-0400\n"
1212
"PO-Revision-Date: 2024-08-18 20:40+0200\n"
1313
"Last-Translator: Odyssey <odysseyhyd@gmail.com>\n"
1414
"Language-Team: \n"
@@ -18,22 +18,22 @@ msgstr ""
1818
"Content-Transfer-Encoding: 8bit\n"
1919
"X-Generator: Poedit 3.4.2\n"
2020

21-
#: 5.6/extension.js:75
22-
msgid "has been enabled"
21+
#. 5.6/extension.js:80
22+
msgid "ERROR"
23+
msgstr ""
24+
25+
#. 5.6/extension.js:80
26+
#, fuzzy
27+
msgid "was NOT enabled"
2328
msgstr "ha estat activat"
2429

25-
#: 5.6/extension.js:76
26-
msgid ""
27-
"Please set the Cinnamon minimize and unminimize effects to None. These "
28-
"effects will interfere with the Cinnamon Magic Lap effects."
30+
#. 5.6/extension.js:81
31+
msgid "The existing extension"
2932
msgstr ""
30-
"Si, us plau, establiu els efectes de Cinnamon de minimitzar i "
31-
"desminimitzar a 'Cap'. Aquests efectes interferirien amb els de la llàntia "
32-
"màgica de Cinnamon."
3333

34-
#: 5.6/extension.js:79
35-
msgid "Open Cinnamon Effects"
36-
msgstr "Obrir efectes de Cinnamon"
34+
#. 5.6/extension.js:81
35+
msgid "conflicts with this extension."
36+
msgstr ""
3737

3838
#. metadata.json->name
3939
msgid "Magic Lamp Effect"
@@ -43,8 +43,8 @@ msgstr "Efecte de Llàntia Màgica"
4343
msgid ""
4444
"A minimize/unminimize magic lamp effect based on hermes83's Gnome extension"
4545
msgstr ""
46-
"Un efecte de llàntia màgica en minimitzar/desminimitzar basat en "
47-
"l'extensió de Gnome d'hermes83"
46+
"Un efecte de llàntia màgica en minimitzar/desminimitzar basat en l'extensió "
47+
"de Gnome d'hermes83"
4848

4949
#. 5.6->settings-schema.json->keybinding-header->description
5050
msgid "Cinnamon Magic Lamp Settings"
@@ -67,8 +67,8 @@ msgid ""
6767
"Using 'default' will result in a curved effect where using 'sine' will "
6868
"result in a more wavy effect"
6969
msgstr ""
70-
"Utilitzar 'per defecte' crearà un efecte de corba, mentre que 'sinus' "
71-
"crearà un efecte més ondulat"
70+
"Utilitzar 'per defecte' crearà un efecte de corba, mentre que 'sinus' crearà "
71+
"un efecte més ondulat"
7272

7373
#. 5.6->settings-schema.json->duration->units
7474
msgid "ms"

0 commit comments

Comments
 (0)