const AppSystem = imports.gi.Shell.AppSystem; const WindowTracker = imports.gi.Shell.WindowTracker; const getSettings = imports.misc.extensionUtils.getSettings; const GLib = imports.gi.GLib; const Me = imports.misc.extensionUtils.getCurrentExtension(); var leftClick = function (icon, event) { let trayApp = getTrayApp(icon); if (trayApp) { let focusedApp = WindowTracker.get_default().focusApp; let windows = trayApp.get_windows(); if (windows == "") { return openApplication(trayApp, icon, event); } if (focusedApp != null && focusedApp.id == trayApp.id) { return minimizeWindows(focusedApp.get_windows(), icon, event); } return activateWindows(windows, trayApp, event); } icon.click(event); // On Windows double-click restore app if (isWine(icon)) { icon.click(event); } }; var middleClick = function (icon, event) { // When holding SHIFT if (event.get_state_full()[1] === 1) { let trayApp = getTrayApp(icon); if (trayApp) { const pid = getPid(icon); // Kill app if (isUsingQt(pid)) { return GLib.spawn_command_line_sync(`/bin/kill ${pid}`); } let windows = trayApp.get_windows(); windows.forEach((window) => { window.kill(); }); trayApp.request_quit(); } } else { icon.click(event); } }; var getAppSetting = function (icon, setting) { const iconApp = getTrayApp(icon); const appsSettings = JSON.parse(getSettings().get_string("applications")); const appSettings = appsSettings.find((app) => app.id == iconApp.get_id()); return appSettings?.[setting]; }; function getTrayApp(icon) { if (isWine(icon)) { const wineApps = AppSystem.get_default() .get_running() .filter((app) => { return app.get_windows()[0].wm_class.includes(".exe"); }); return wineApps[0]; } const searchedApps = AppSystem.search(getWmClass(icon.wm_class)); if (searchedApps[0] && searchedApps[0][0]) { var i = 1; for (let lookup of searchedApps[0]) { let app = AppSystem.get_default().lookup_app(lookup); if (app.get_windows() != "" || i == searchedApps[0].length) { return app; } i++; } } return false; } function openApplication(trayApp, icon, event) { const isFlatpak = trayApp.app_info.has_key("X-Flatpak"); const onBlacklist = Me.metadata["open-blacklist"].includes(icon.wm_class); // Caprine if (isUsingQt(getPid(icon)) || isFlatpak || onBlacklist) { return icon.click(event); } return trayApp.open_new_window(0); } function minimizeWindows(windows, icon, event) { if (isUsingQt(getPid(icon))) { return icon.click(event); } windows.forEach((window) => { window.minimize(); }); } function activateWindows(windows, trayApp, event) { windows.forEach((window) => { if (getSettings().get_boolean("invoke-to-workspace")) { window.change_workspace(global.workspace_manager.get_active_workspace()); } trayApp.activate_window(window, event.get_time()); window.unminimize(); }); } function isWine(icon) { if ( (icon.wm_class == "Wine" || icon.wm_class == "explorer.exe") && getSettings().get_boolean("wine-behavior") ) { return true; } } function isUsingQt(pid) { let [ok, out, err, exit] = GLib.spawn_command_line_sync( `/bin/bash -c 'pmap -p ${pid} | grep Qt'` ); if (out.length) { return true; } } function getWmClass(wmclass) { wmclass = wmclass.replace(/[0-9]/g, ""); // skype discord wmclass = wmclass.replace("Desktop", ""); // telegram return wmclass; } function getPid(icon) { const wmclass = getWmClass(icon.wm_class); if (icon.title != "snixembed") { return icon.pid; } let [ok, out, err, exit] = GLib.spawn_command_line_sync( `/bin/bash -c "pidof -s ${wmclass}"` ); if (out.length) { return Number(out); } }