Skip to content

Commit

Permalink
mouse-click-effects@anaximeno: Version 0.5.0 (#747)
Browse files Browse the repository at this point in the history
* Update pause handling
* Comment log to avoid flood
  • Loading branch information
anaximeno authored Sep 20, 2024
1 parent db33442 commit a9fbee2
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ var BlinkClickAnimationMode = class BlinkClickAnimationMode extends ClickAnimati
}
}

var ClickAnimationModes = Object.freeze({
BOUNCE: "bounce",
RETRACT: "retract",
EXPAND: "expand",
BLINK: "blink",
});

var ClickAnimationFactory = class ClickAnimationFactory {
/**
* Returns an click animation mode depending on the given name
Expand All @@ -192,13 +199,13 @@ var ClickAnimationFactory = class ClickAnimationFactory {
*/
static createForMode(mode) {
switch (mode) {
case "bounce":
case ClickAnimationModes.BOUNCE:
return new BounceBackClickAnimationMode(mode);
case "retract":
case ClickAnimationModes.RETRACT:
return new RetractionClickAnimationMode(mode);
case "expand":
case ClickAnimationModes.EXPAND:
return new ExpansionClickAnimationMode(mode);
case "blink":
case ClickAnimationModes.BLINK:
default:
return new BlinkClickAnimationMode(mode);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const Settings = imports.ui.settings;
const Gettext = imports.gettext;
const ByteArray = imports.byteArray;
const { Atspi, GLib, Gio } = imports.gi;
const { ClickAnimationFactory } = require("./clickAnimations.js");
const { ClickAnimationFactory, ClickAnimationModes } = require("./clickAnimations.js");
const { Debouncer } = require("./helpers.js");
const { UUID, PAUSE_EFFECTS_KEY } = require("./constants.js");

Expand All @@ -36,28 +36,34 @@ function _(text) {
}


const ClickType = {
const ClickType = Object.freeze({
LEFT: "left_click",
MIDDLE: "middle_click",
RIGHT: "right_click",
PAUSE: "pause_bind",
};
PAUSE_ON: "pause_on",
PAUSE_OFF: "pause_off",
});

const PAUSE_OFF_COLOR = "#E5E4E2";
const PAUSE_ON_COLOR = "#71797E";

class MouseClickEffects {
constructor(metadata) {
this.metadata = metadata;
this.app_icons_dir = `${metadata.path}/../icons`;
this.pause_icon_path = `${this.app_icons_dir}/extra/pause.svg`;
this.settings = this._setup_settings(this.metadata.uuid);
this.data_dir = this._init_data_dir(this.metadata.uuid);

Atspi.init();
this.clickAnimator = ClickAnimationFactory.createForMode(this.animation_mode);

this.display_click = (new Debouncer()).debounce((...args) => {
if (this.deactivate_in_fullscreen && global.display.focus_window && global.display.focus_window.is_fullscreen()) {
// global.log(UUID, "Click effects not displayed due to being disabled for fullscreen focused windows");
return;
}
this.animate_click(...args);
}, 10);

this.listener = Atspi.EventListener.new(this.on_mouse_click.bind(this));
this.click_animator = ClickAnimationFactory.createForMode(this.animation_mode);
this.display_click = (new Debouncer()).debounce(this.animate_click.bind(this), 2);

this.colored_icon_store = {};
this.enabled = false;
Expand Down Expand Up @@ -148,13 +154,13 @@ class MouseClickEffects {
value: "deactivate_in_fullscreen",
cb: null,
},
]
];

bindings.forEach(
b => settings.bind(
b.key, b.value, b.cb ? (...args) => b.cb.call(this, ...args) : null,
)
);
bindings.forEach(b => settings.bind(
b.key,
b.value,
b.cb ? (...args) => b.cb.call(this, ...args) : null,
));

return settings;
}
Expand All @@ -180,29 +186,30 @@ class MouseClickEffects {

on_pause_toggled() {
this.set_active(!this.enabled);

if (this.pause_animation_effects_enabled) {
let color = this.enabled ? PAUSE_OFF_COLOR : PAUSE_ON_COLOR;
this.display_click(ClickType.PAUSE, color);
this.display_click(this.enabled ? ClickType.PAUSE_OFF : ClickType.PAUSE_ON);
}
}

update_animation_mode() {
if (!this.click_animator || this.click_animator.mode != this.animation_mode)
this.click_animator = ClickAnimationFactory.createForMode(this.animation_mode);
if (!this.clickAnimator || this.clickAnimator.mode != this.animation_mode) {
this.clickAnimator = ClickAnimationFactory.createForMode(this.animation_mode);
}
}

get_colored_icon(mode, click_type, color) {
const name = `${mode}_${click_type}_${color}`;

if (this.colored_icon_store[name])
return this.colored_icon_store[name];
get_click_icon(mode, click_type, color) {
let name = `${mode}_${click_type}_${color}`;
let path = `${this.data_dir}/icons/${name}.svg`;
return this.get_icon_cached(path);
}

const path = `${this.data_dir}/icons/${name}.svg`;
get_icon_cached(path) {
if (this.colored_icon_store[path])
return this.colored_icon_store[path];

if (GLib.file_test(path, GLib.FileTest.IS_REGULAR)) {
this.colored_icon_store[name] = Gio.icon_new_for_string(path);
return this.colored_icon_store[name];
this.colored_icon_store[path] = Gio.icon_new_for_string(path);
return this.colored_icon_store[path];
}

return null;
Expand All @@ -218,59 +225,69 @@ class MouseClickEffects {
this.settings.finalize();
this.colored_icon_store = null;
this.display_click = null;
this.click_animator = null;
this.clickAnimator = null;
}

update_colored_icons() {
this.create_icon_data(ClickType.PAUSE, PAUSE_ON_COLOR);
this.create_icon_data(ClickType.PAUSE, PAUSE_OFF_COLOR);
this.create_icon_data(ClickType.LEFT, this.left_click_color);
this.create_icon_data(ClickType.MIDDLE, this.middle_click_color);
this.create_icon_data(ClickType.RIGHT, this.right_click_color);
}

set_active(enabled) {
this.enabled = enabled;

this.listener.deregister('mouse');
if (enabled) this.listener.register('mouse');

global.log(UUID, `Click effects ${enabled ? "activated" : "deactivated"}!`);
if (enabled) {
this.listener.register('mouse');
global.log(UUID, "Click effects activated");
} else {
global.log(UUID, "Click effects deactivated");
}
}

create_icon_data(click_type, color) {
if (this.get_colored_icon(this.icon_mode, click_type, color))
if (this.get_click_icon(this.icon_mode, click_type, color))
return true;

let source = Gio.File.new_for_path(`${this.app_icons_dir}/${this.icon_mode}.svg`);
let [l_success, contents] = source.load_contents(null);

contents = ByteArray.toString(contents);
// Replace to new color
contents = contents.replace('fill="#000000"', `fill="${color}"`);

// Save content to cache dir
const name = `${this.icon_mode}_${click_type}_${color}`;
let name = `${this.icon_mode}_${click_type}_${color}`;
let dest = Gio.File.new_for_path(`${this.data_dir}/icons/${name}.svg`);

if (!dest.query_exists(null)) dest.create(Gio.FileCreateFlags.NONE, null);
if (!dest.query_exists(null))
dest.create(Gio.FileCreateFlags.NONE, null);

let [r_success, tag] = dest.replace_contents(contents, null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, null);
return r_success;
}

animate_click(click_type, color) {
if (global.display.focus_window.is_fullscreen() && this.deactivate_in_fullscreen) {
// global.log(UUID, "Click effects not displayed due to being disabled for fullscreen focused windows");
return;
}

this.update_animation_mode();
let icon = this.get_colored_icon(this.icon_mode, click_type, color);

let icon = null;
let animator = this.clickAnimator;

if (click_type === ClickType.PAUSE_ON) {
icon = this.get_icon_cached(this.pause_icon_path);
animator = ClickAnimationFactory.createForMode(ClickAnimationModes.BLINK);
} else if (click_type === ClickType.PAUSE_OFF) {
icon = this.get_click_icon(this.icon_mode, ClickType.LEFT, this.left_click_color);
animator = ClickAnimationFactory.createForMode(ClickAnimationModes.BLINK);
} else if (color != null) {
icon = this.get_click_icon(this.icon_mode, click_type, color);
}

if (icon) {
let options = { opacity: this.general_opacity, icon_size: this.size, timeout: this.animation_time };
this.click_animator.animateClick(icon, options);
animator.animateClick(icon, {
opacity: this.general_opacity,
icon_size: this.size,
timeout: this.animation_time,
});
} else {
global.logError(`${UUID}: Couldn't get Click Icon (mode = ${this.icon_mode}, type = ${click_type}, color = ${color})`)
}
Expand Down Expand Up @@ -307,5 +324,8 @@ function disable() {
}

function init(metadata) {
if (!extension) extension = new MouseClickEffects(metadata);
if (!extension) {
Atspi.init();
extension = new MouseClickEffects(metadata);
};
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a9fbee2

Please sign in to comment.