2019-03-05 08:36:59 -03:00
|
|
|
/* jslint esversion: 6 */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Copyright 2019 Abakkk
|
|
|
|
|
*
|
2019-12-28 09:25:41 -03:00
|
|
|
* This file is part of DrawOnYourScreen, a drawing extension for GNOME Shell.
|
2019-03-05 08:36:59 -03:00
|
|
|
* https://framagit.org/abakkk/DrawOnYourScreen
|
|
|
|
|
*
|
|
|
|
|
* 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 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
const Gio = imports.gi.Gio;
|
2020-01-06 17:24:29 -03:00
|
|
|
const GLib = imports.gi.GLib;
|
2019-03-05 08:36:59 -03:00
|
|
|
const Lang = imports.lang;
|
|
|
|
|
const Meta = imports.gi.Meta;
|
|
|
|
|
const Shell = imports.gi.Shell;
|
|
|
|
|
const St = imports.gi.St;
|
2019-03-28 18:01:39 -03:00
|
|
|
|
2019-10-11 04:22:37 -03:00
|
|
|
const Config = imports.misc.config;
|
2019-03-05 08:36:59 -03:00
|
|
|
const Main = imports.ui.main;
|
|
|
|
|
const OsdWindow = imports.ui.osdWindow;
|
2019-03-28 18:01:39 -03:00
|
|
|
const PanelMenu = imports.ui.panelMenu;
|
|
|
|
|
|
2020-01-05 11:44:51 -03:00
|
|
|
const ExtensionUtils = imports.misc.extensionUtils;
|
|
|
|
|
const Me = ExtensionUtils.getCurrentExtension();
|
|
|
|
|
const Convenience = ExtensionUtils.getSettings && ExtensionUtils.initTranslations ? ExtensionUtils : Me.imports.convenience;
|
2020-07-04 03:42:45 -03:00
|
|
|
const Area = Me.imports.area;
|
2020-07-04 03:35:59 -03:00
|
|
|
const Helper = Me.imports.helper;
|
2020-01-06 11:29:01 -03:00
|
|
|
const _ = imports.gettext.domain(Me.metadata['gettext-domain']).gettext;
|
2019-03-05 08:36:59 -03:00
|
|
|
|
2019-10-11 04:22:37 -03:00
|
|
|
const GS_VERSION = Config.PACKAGE_VERSION;
|
2020-06-20 07:59:46 -03:00
|
|
|
const HIDE_TIMEOUT_LONG = 2500; // ms, default is 1500 ms
|
2019-10-11 04:22:37 -03:00
|
|
|
|
2020-06-25 06:41:15 -03:00
|
|
|
// custom Shell.ActionMode, assuming that they are unused
|
|
|
|
|
const DRAWING_ACTION_MODE = Math.pow(2,14);
|
|
|
|
|
const WRITING_ACTION_MODE = Math.pow(2,15);
|
2019-10-11 08:26:08 -03:00
|
|
|
// use 'login-dialog-message-warning' class in order to get GS theme warning color (default: #f57900)
|
|
|
|
|
var WARNING_COLOR_STYLE_CLASS_NAME = 'login-dialog-message-warning';
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2019-11-29 14:43:42 -03:00
|
|
|
var manager;
|
2019-03-05 08:36:59 -03:00
|
|
|
|
|
|
|
|
function init() {
|
|
|
|
|
Convenience.initTranslations();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function enable() {
|
|
|
|
|
manager = new AreaManager();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function disable() {
|
|
|
|
|
manager.disable();
|
|
|
|
|
manager = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AreaManager assigns one DrawingArea per monitor (updateAreas()),
|
|
|
|
|
// distributes keybinding callbacks to the active area
|
|
|
|
|
// and handles stylesheet and monitor changes.
|
|
|
|
|
var AreaManager = new Lang.Class({
|
2019-03-08 07:37:59 -03:00
|
|
|
Name: 'DrawOnYourScreenAreaManager',
|
2019-03-05 08:36:59 -03:00
|
|
|
|
|
|
|
|
_init: function() {
|
2019-03-10 18:16:11 -03:00
|
|
|
this.settings = Convenience.getSettings();
|
2019-03-05 08:36:59 -03:00
|
|
|
this.areas = [];
|
|
|
|
|
this.activeArea = null;
|
|
|
|
|
this.enterGicon = new Gio.ThemedIcon({ name: 'applications-graphics-symbolic' });
|
|
|
|
|
this.leaveGicon = new Gio.ThemedIcon({ name: 'application-exit-symbolic' });
|
|
|
|
|
|
|
|
|
|
Main.wm.addKeybinding('toggle-drawing',
|
2019-03-10 18:16:11 -03:00
|
|
|
this.settings,
|
2019-03-05 08:36:59 -03:00
|
|
|
Meta.KeyBindingFlags.NONE,
|
|
|
|
|
Shell.ActionMode.ALL,
|
|
|
|
|
this.toggleDrawing.bind(this));
|
|
|
|
|
|
2020-06-28 08:10:31 -03:00
|
|
|
Main.wm.addKeybinding('toggle-modal',
|
2019-03-10 18:16:11 -03:00
|
|
|
this.settings,
|
2019-03-05 08:36:59 -03:00
|
|
|
Meta.KeyBindingFlags.NONE,
|
|
|
|
|
Shell.ActionMode.ALL,
|
2020-06-28 08:10:31 -03:00
|
|
|
this.toggleModal.bind(this));
|
2019-03-05 08:36:59 -03:00
|
|
|
|
2020-06-28 08:10:31 -03:00
|
|
|
Main.wm.addKeybinding('erase-drawing',
|
2020-06-20 20:08:45 -03:00
|
|
|
this.settings,
|
|
|
|
|
Meta.KeyBindingFlags.NONE,
|
|
|
|
|
Shell.ActionMode.ALL,
|
2020-06-28 08:10:31 -03:00
|
|
|
this.eraseDrawing.bind(this));
|
2020-06-20 20:08:45 -03:00
|
|
|
|
2019-03-05 08:36:59 -03:00
|
|
|
this.updateAreas();
|
|
|
|
|
this.monitorChangedHandler = Main.layoutManager.connect('monitors-changed', this.updateAreas.bind(this));
|
|
|
|
|
|
2019-03-28 18:01:39 -03:00
|
|
|
this.updateIndicator();
|
|
|
|
|
this.indicatorSettingHandler = this.settings.connect('changed::indicator-disabled', this.updateIndicator.bind(this));
|
|
|
|
|
|
2019-03-11 20:29:14 -03:00
|
|
|
this.desktopSettingHandler = this.settings.connect('changed::drawing-on-desktop', this.onDesktopSettingChanged.bind(this));
|
|
|
|
|
this.persistentSettingHandler = this.settings.connect('changed::persistent-drawing', this.onPersistentSettingChanged.bind(this));
|
|
|
|
|
|
2020-01-06 17:24:29 -03:00
|
|
|
this.userStyleFile = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir'], 'user.css']));
|
|
|
|
|
|
|
|
|
|
if (this.userStyleFile.query_exists(null)) {
|
|
|
|
|
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
|
|
|
|
|
theme.load_stylesheet(this.userStyleFile);
|
2019-03-05 08:36:59 -03:00
|
|
|
}
|
2020-01-06 17:24:29 -03:00
|
|
|
|
|
|
|
|
this.userStyleMonitor = this.userStyleFile.monitor_file(Gio.FileMonitorFlags.WATCH_MOVES, null);
|
|
|
|
|
this.userStyleHandler = this.userStyleMonitor.connect('changed', (monitor, file, otherFile, eventType) => {
|
|
|
|
|
// 'CHANGED' events are followed by a 'CHANGES_DONE_HINT' event
|
|
|
|
|
if (eventType == Gio.FileMonitorEvent.CHANGED || eventType == Gio.FileMonitorEvent.ATTRIBUTE_CHANGED)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
|
|
|
|
|
if (theme.get_custom_stylesheets().indexOf(this.userStyleFile) != -1)
|
|
|
|
|
theme.unload_stylesheet(this.userStyleFile);
|
|
|
|
|
if (this.userStyleFile.query_exists(null))
|
|
|
|
|
theme.load_stylesheet(this.userStyleFile);
|
|
|
|
|
});
|
2019-03-05 08:36:59 -03:00
|
|
|
},
|
|
|
|
|
|
2019-03-11 20:29:14 -03:00
|
|
|
onDesktopSettingChanged: function() {
|
|
|
|
|
if (this.settings.get_boolean("drawing-on-desktop"))
|
|
|
|
|
this.areas.forEach(area => area.get_parent().show());
|
|
|
|
|
else
|
|
|
|
|
this.areas.forEach(area => area.get_parent().hide());
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
onPersistentSettingChanged: function() {
|
|
|
|
|
if (this.settings.get_boolean('persistent-drawing'))
|
2020-01-10 09:01:26 -03:00
|
|
|
this.areas[Main.layoutManager.primaryIndex].syncPersistent();
|
2019-03-11 20:29:14 -03:00
|
|
|
},
|
|
|
|
|
|
2019-03-28 18:01:39 -03:00
|
|
|
updateIndicator: function() {
|
|
|
|
|
if (this.indicator) {
|
|
|
|
|
this.indicator.disable();
|
|
|
|
|
this.indicator = null;
|
|
|
|
|
}
|
|
|
|
|
if (!this.settings.get_boolean('indicator-disabled'))
|
|
|
|
|
this.indicator = new DrawingIndicator();
|
|
|
|
|
},
|
|
|
|
|
|
2019-03-05 08:36:59 -03:00
|
|
|
updateAreas: function() {
|
|
|
|
|
if (this.activeArea)
|
|
|
|
|
this.toggleDrawing();
|
|
|
|
|
this.removeAreas();
|
|
|
|
|
|
|
|
|
|
this.monitors = Main.layoutManager.monitors;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < this.monitors.length; i++) {
|
|
|
|
|
let monitor = this.monitors[i];
|
2019-03-10 09:05:38 -03:00
|
|
|
let container = new St.Widget({ name: 'drawOnYourSreenContainer' + i });
|
2020-07-04 03:35:59 -03:00
|
|
|
let helper = new Helper.DrawingHelper({ name: 'drawOnYourSreenHelper' + i }, monitor);
|
2020-01-03 20:16:20 -03:00
|
|
|
let loadPersistent = i == Main.layoutManager.primaryIndex && this.settings.get_boolean('persistent-drawing');
|
2020-07-04 03:42:45 -03:00
|
|
|
let area = new Area.DrawingArea({ name: 'drawOnYourSreenArea' + i }, monitor, helper, loadPersistent);
|
2019-03-10 09:05:38 -03:00
|
|
|
container.add_child(area);
|
|
|
|
|
container.add_child(helper);
|
2019-03-10 18:16:11 -03:00
|
|
|
|
2019-03-11 20:29:14 -03:00
|
|
|
Main.layoutManager._backgroundGroup.insert_child_above(container, Main.layoutManager._bgManagers[i].backgroundActor);
|
|
|
|
|
if (!this.settings.get_boolean("drawing-on-desktop"))
|
|
|
|
|
container.hide();
|
2019-03-10 18:16:11 -03:00
|
|
|
|
2019-03-10 09:05:38 -03:00
|
|
|
container.set_position(monitor.x, monitor.y);
|
|
|
|
|
container.set_size(monitor.width, monitor.height);
|
2019-03-05 08:36:59 -03:00
|
|
|
area.set_size(monitor.width, monitor.height);
|
2020-06-22 06:56:34 -03:00
|
|
|
area.leaveDrawingHandler = area.connect('leave-drawing-mode', this.toggleDrawing.bind(this));
|
2020-06-25 06:41:15 -03:00
|
|
|
area.updateActionModeHandler = area.connect('update-action-mode', this.updateActionMode.bind(this));
|
2019-11-27 15:01:07 -03:00
|
|
|
area.showOsdHandler = area.connect('show-osd', this.showOsd.bind(this));
|
2020-07-30 06:13:23 -03:00
|
|
|
area.showOsdGiconHandler = area.connect('show-osd-gicon', this.showOsd.bind(this));
|
2019-03-05 08:36:59 -03:00
|
|
|
this.areas.push(area);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
addInternalKeybindings: function() {
|
2020-06-25 06:41:15 -03:00
|
|
|
// unavailable when writing
|
|
|
|
|
this.internalKeybindings1 = {
|
2019-03-05 08:36:59 -03:00
|
|
|
'undo': this.activeArea.undo.bind(this.activeArea),
|
|
|
|
|
'redo': this.activeArea.redo.bind(this.activeArea),
|
|
|
|
|
'delete-last-element': this.activeArea.deleteLastElement.bind(this.activeArea),
|
2019-03-05 17:08:43 -03:00
|
|
|
'smooth-last-element': this.activeArea.smoothLastElement.bind(this.activeArea),
|
2019-03-05 08:36:59 -03:00
|
|
|
'increment-line-width': () => this.activeArea.incrementLineWidth(1),
|
|
|
|
|
'decrement-line-width': () => this.activeArea.incrementLineWidth(-1),
|
|
|
|
|
'increment-line-width-more': () => this.activeArea.incrementLineWidth(5),
|
|
|
|
|
'decrement-line-width-more': () => this.activeArea.incrementLineWidth(-5),
|
2020-08-05 19:04:12 -03:00
|
|
|
'switch-linejoin': this.activeArea.switchLineJoin.bind(this.activeArea),
|
|
|
|
|
'switch-linecap': this.activeArea.switchLineCap.bind(this.activeArea),
|
|
|
|
|
'switch-fill-rule': this.activeArea.switchFillRule.bind(this.activeArea),
|
|
|
|
|
'switch-dash' : this.activeArea.switchDash.bind(this.activeArea),
|
|
|
|
|
'switch-fill' : this.activeArea.switchFill.bind(this.activeArea),
|
|
|
|
|
'switch-image-file' : this.activeArea.switchImageFile.bind(this.activeArea),
|
2020-07-04 03:42:45 -03:00
|
|
|
'select-none-shape': () => this.activeArea.selectTool(Area.Tools.NONE),
|
|
|
|
|
'select-line-shape': () => this.activeArea.selectTool(Area.Tools.LINE),
|
|
|
|
|
'select-ellipse-shape': () => this.activeArea.selectTool(Area.Tools.ELLIPSE),
|
|
|
|
|
'select-rectangle-shape': () => this.activeArea.selectTool(Area.Tools.RECTANGLE),
|
|
|
|
|
'select-text-shape': () => this.activeArea.selectTool(Area.Tools.TEXT),
|
2020-07-30 06:13:23 -03:00
|
|
|
'select-image-shape': () => this.activeArea.selectTool(Area.Tools.IMAGE),
|
2020-07-04 03:42:45 -03:00
|
|
|
'select-polygon-shape': () => this.activeArea.selectTool(Area.Tools.POLYGON),
|
|
|
|
|
'select-polyline-shape': () => this.activeArea.selectTool(Area.Tools.POLYLINE),
|
|
|
|
|
'select-move-tool': () => this.activeArea.selectTool(Area.Tools.MOVE),
|
|
|
|
|
'select-resize-tool': () => this.activeArea.selectTool(Area.Tools.RESIZE),
|
|
|
|
|
'select-mirror-tool': () => this.activeArea.selectTool(Area.Tools.MIRROR)
|
2020-06-25 06:41:15 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// available when writing
|
|
|
|
|
this.internalKeybindings2 = {
|
|
|
|
|
'save-as-svg': this.activeArea.saveAsSvg.bind(this.activeArea),
|
|
|
|
|
'save-as-json': this.activeArea.saveAsJson.bind(this.activeArea),
|
|
|
|
|
'open-previous-json': this.activeArea.loadPreviousJson.bind(this.activeArea),
|
|
|
|
|
'open-next-json': this.activeArea.loadNextJson.bind(this.activeArea),
|
|
|
|
|
'toggle-background': this.activeArea.toggleBackground.bind(this.activeArea),
|
|
|
|
|
'toggle-grid': this.activeArea.toggleGrid.bind(this.activeArea),
|
|
|
|
|
'toggle-square-area': this.activeArea.toggleSquareArea.bind(this.activeArea),
|
2020-08-05 19:26:10 -03:00
|
|
|
'reverse-switch-font-family': this.activeArea.switchFontFamily.bind(this.activeArea, true),
|
|
|
|
|
'switch-font-family': this.activeArea.switchFontFamily.bind(this.activeArea, false),
|
2020-08-05 19:04:12 -03:00
|
|
|
'switch-font-weight': this.activeArea.switchFontWeight.bind(this.activeArea),
|
|
|
|
|
'switch-font-style': this.activeArea.switchFontStyle.bind(this.activeArea),
|
|
|
|
|
'switch-text-alignment': this.activeArea.switchTextAlignment.bind(this.activeArea),
|
2019-03-05 08:36:59 -03:00
|
|
|
'toggle-panel-and-dock-visibility': this.togglePanelAndDockOpacity.bind(this),
|
|
|
|
|
'toggle-help': this.activeArea.toggleHelp.bind(this.activeArea),
|
2020-06-08 10:26:55 -03:00
|
|
|
'open-user-stylesheet': this.openUserStyleFile.bind(this),
|
|
|
|
|
'open-preferences': this.openPreferences.bind(this)
|
2019-03-05 08:36:59 -03:00
|
|
|
};
|
|
|
|
|
|
2020-06-25 06:41:15 -03:00
|
|
|
for (let key in this.internalKeybindings1) {
|
2019-03-05 08:36:59 -03:00
|
|
|
Main.wm.addKeybinding(key,
|
2019-03-10 18:16:11 -03:00
|
|
|
this.settings,
|
2019-03-05 08:36:59 -03:00
|
|
|
Meta.KeyBindingFlags.NONE,
|
2019-03-26 18:28:24 -03:00
|
|
|
DRAWING_ACTION_MODE,
|
2020-06-25 06:41:15 -03:00
|
|
|
this.internalKeybindings1[key]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let key in this.internalKeybindings2) {
|
|
|
|
|
Main.wm.addKeybinding(key,
|
|
|
|
|
this.settings,
|
|
|
|
|
Meta.KeyBindingFlags.NONE,
|
|
|
|
|
DRAWING_ACTION_MODE | WRITING_ACTION_MODE,
|
|
|
|
|
this.internalKeybindings2[key]);
|
2019-03-05 08:36:59 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let i = 1; i < 10; i++) {
|
2019-11-29 14:43:42 -03:00
|
|
|
let iCaptured = i;
|
2019-03-05 08:36:59 -03:00
|
|
|
Main.wm.addKeybinding('select-color' + i,
|
2019-03-10 18:16:11 -03:00
|
|
|
this.settings,
|
2019-03-05 08:36:59 -03:00
|
|
|
Meta.KeyBindingFlags.NONE,
|
2020-06-25 06:41:15 -03:00
|
|
|
DRAWING_ACTION_MODE | WRITING_ACTION_MODE,
|
2019-11-29 14:43:42 -03:00
|
|
|
() => this.activeArea.selectColor(iCaptured));
|
2019-03-05 08:36:59 -03:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
removeInternalKeybindings: function() {
|
2020-06-25 06:41:15 -03:00
|
|
|
for (let key in this.internalKeybindings1)
|
2019-03-05 08:36:59 -03:00
|
|
|
Main.wm.removeKeybinding(key);
|
|
|
|
|
|
2020-06-25 06:41:15 -03:00
|
|
|
for (let key in this.internalKeybindings2)
|
|
|
|
|
Main.wm.removeKeybinding(key);
|
|
|
|
|
|
|
|
|
|
for (let i = 1; i < 10; i++)
|
2019-03-05 08:36:59 -03:00
|
|
|
Main.wm.removeKeybinding('select-color' + i);
|
|
|
|
|
},
|
|
|
|
|
|
2020-06-08 10:26:55 -03:00
|
|
|
openPreferences: function() {
|
|
|
|
|
// since GS 3.36
|
|
|
|
|
if (ExtensionUtils.openPrefs) {
|
|
|
|
|
if (this.activeArea)
|
|
|
|
|
this.toggleDrawing();
|
|
|
|
|
ExtensionUtils.openPrefs();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2020-01-06 17:24:29 -03:00
|
|
|
openUserStyleFile: function() {
|
|
|
|
|
if (!this.userStyleFile.query_exists(null)) {
|
|
|
|
|
if (!this.userStyleFile.get_parent().query_exists(null))
|
|
|
|
|
this.userStyleFile.get_parent().make_directory_with_parents(null);
|
|
|
|
|
let defaultStyleFile = Me.dir.get_child('data').get_child('default.css');
|
|
|
|
|
if (!defaultStyleFile.query_exists(null))
|
|
|
|
|
return;
|
|
|
|
|
let success = defaultStyleFile.copy(this.userStyleFile, Gio.FileCopyFlags.NONE, null, null);
|
|
|
|
|
if (!success)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Gio.AppInfo.launch_default_for_uri(this.userStyleFile.get_uri(), global.create_app_launch_context(0, -1));
|
2019-03-05 08:36:59 -03:00
|
|
|
if (this.activeArea)
|
|
|
|
|
this.toggleDrawing();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
eraseDrawing: function() {
|
2019-03-11 20:29:14 -03:00
|
|
|
for (let i = 0; i < this.areas.length; i++)
|
2019-03-05 08:36:59 -03:00
|
|
|
this.areas[i].erase();
|
2019-03-15 08:45:20 -03:00
|
|
|
if (this.settings.get_boolean('persistent-drawing'))
|
2020-01-03 20:16:20 -03:00
|
|
|
this.areas[Main.layoutManager.primaryIndex].savePersistent();
|
2019-03-05 08:36:59 -03:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
togglePanelAndDockOpacity: function() {
|
|
|
|
|
if (this.hiddenList) {
|
|
|
|
|
for (let i = 0; i < this.hiddenList.length; i++) {
|
|
|
|
|
this.hiddenList[i].actor.set_opacity(this.hiddenList[i].oldOpacity);
|
|
|
|
|
}
|
|
|
|
|
this.hiddenList = null;
|
|
|
|
|
} else {
|
|
|
|
|
let activeIndex = this.areas.indexOf(this.activeArea);
|
|
|
|
|
|
|
|
|
|
// dash-to-dock
|
|
|
|
|
let dtdContainers = Main.uiGroup.get_children().filter((actor) => {
|
|
|
|
|
return actor.name && actor.name == 'dashtodockContainer' &&
|
2020-06-01 15:28:26 -03:00
|
|
|
((actor._delegate &&
|
2019-03-05 08:36:59 -03:00
|
|
|
actor._delegate._monitorIndex !== undefined &&
|
2020-06-01 15:28:26 -03:00
|
|
|
actor._delegate._monitorIndex == activeIndex) ||
|
|
|
|
|
// dtd v68+
|
|
|
|
|
(actor._monitorIndex !== undefined &&
|
|
|
|
|
actor._monitorIndex == activeIndex));
|
2019-03-05 08:36:59 -03:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// for simplicity, we assume that main dash-to-panel panel is displayed on primary monitor
|
|
|
|
|
// and we hide all secondary panels together if the active area is not on the primary
|
|
|
|
|
let name = activeIndex == Main.layoutManager.primaryIndex ? 'panelBox' : 'dashtopanelSecondaryPanelBox';
|
|
|
|
|
let panelBoxes = Main.uiGroup.get_children().filter((actor) => {
|
2020-06-01 15:28:26 -03:00
|
|
|
return actor.name && actor.name == name ||
|
|
|
|
|
// dtp v37+
|
|
|
|
|
actor.get_children().length && actor.get_children()[0].name && actor.get_children()[0].name == name;
|
2019-03-05 08:36:59 -03:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let actorToHide = dtdContainers.concat(panelBoxes);
|
|
|
|
|
this.hiddenList = [];
|
|
|
|
|
for (let i = 0; i < actorToHide.length; i++) {
|
|
|
|
|
this.hiddenList.push({ actor: actorToHide[i], oldOpacity: actorToHide[i].get_opacity() });
|
|
|
|
|
actorToHide[i].set_opacity(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2020-06-20 20:08:45 -03:00
|
|
|
toggleContainer: function() {
|
|
|
|
|
if (!this.activeArea)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
let activeContainer = this.activeArea.get_parent();
|
|
|
|
|
let activeIndex = this.areas.indexOf(this.activeArea);
|
|
|
|
|
|
|
|
|
|
if (activeContainer.get_parent() == Main.uiGroup) {
|
2020-06-25 06:41:15 -03:00
|
|
|
Main.uiGroup.set_child_at_index(Main.layoutManager.keyboardBox, this.oldKeyboardIndex);
|
2020-06-20 20:08:45 -03:00
|
|
|
Main.uiGroup.remove_actor(activeContainer);
|
|
|
|
|
Main.layoutManager._backgroundGroup.insert_child_above(activeContainer, Main.layoutManager._bgManagers[activeIndex].backgroundActor);
|
|
|
|
|
if (!this.settings.get_boolean("drawing-on-desktop"))
|
|
|
|
|
activeContainer.hide();
|
|
|
|
|
} else {
|
|
|
|
|
Main.layoutManager._backgroundGroup.remove_actor(activeContainer);
|
|
|
|
|
Main.uiGroup.add_child(activeContainer);
|
2020-06-25 06:41:15 -03:00
|
|
|
// move the keyboard above the area to make it available with text entries
|
|
|
|
|
this.oldKeyboardIndex = Main.uiGroup.get_children().indexOf(Main.layoutManager.keyboardBox);
|
|
|
|
|
Main.uiGroup.set_child_above_sibling(Main.layoutManager.keyboardBox, activeContainer);
|
2020-06-20 20:08:45 -03:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2020-06-29 07:21:21 -03:00
|
|
|
toggleModal: function(source) {
|
2020-06-20 20:08:45 -03:00
|
|
|
if (!this.activeArea)
|
|
|
|
|
return;
|
|
|
|
|
|
2020-06-22 06:56:34 -03:00
|
|
|
this.activeArea.closeMenu();
|
|
|
|
|
|
2020-06-24 18:16:22 -03:00
|
|
|
if (Main._findModal(this.activeArea) != -1) {
|
2020-06-20 20:08:45 -03:00
|
|
|
Main.popModal(this.activeArea);
|
2020-06-29 07:21:21 -03:00
|
|
|
if (source && source == global.display)
|
|
|
|
|
this.showOsd(null, 'touchpad-disabled-symbolic', _("Keyboard and pointer released"), null, null, false);
|
2020-06-20 20:08:45 -03:00
|
|
|
setCursor('DEFAULT');
|
|
|
|
|
this.activeArea.reactive = false;
|
|
|
|
|
this.removeInternalKeybindings();
|
|
|
|
|
} else {
|
|
|
|
|
// add Shell.ActionMode.NORMAL to keep system keybindings enabled (e.g. Alt + F2 ...)
|
2020-06-25 06:41:15 -03:00
|
|
|
let actionMode = (this.activeArea.isWriting ? WRITING_ACTION_MODE : DRAWING_ACTION_MODE) | Shell.ActionMode.NORMAL;
|
|
|
|
|
if (!Main.pushModal(this.activeArea, { actionMode: actionMode }))
|
2020-06-20 20:08:45 -03:00
|
|
|
return false;
|
|
|
|
|
this.addInternalKeybindings();
|
|
|
|
|
this.activeArea.reactive = true;
|
|
|
|
|
this.activeArea.initPointerCursor();
|
2020-06-29 07:21:21 -03:00
|
|
|
if (source && source == global.display)
|
|
|
|
|
this.showOsd(null, 'input-touchpad-symbolic', _("Keyboard and pointer grabbed"), null, null, false);
|
2020-06-20 20:08:45 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
},
|
|
|
|
|
|
2019-03-11 20:29:14 -03:00
|
|
|
toggleDrawing: function() {
|
2019-03-05 08:36:59 -03:00
|
|
|
if (this.activeArea) {
|
2019-03-10 09:05:38 -03:00
|
|
|
let activeIndex = this.areas.indexOf(this.activeArea);
|
2019-03-11 13:53:35 -03:00
|
|
|
let save = activeIndex == Main.layoutManager.primaryIndex && this.settings.get_boolean('persistent-drawing');
|
2019-03-10 09:05:38 -03:00
|
|
|
|
2020-06-20 20:08:45 -03:00
|
|
|
this.showOsd(null, this.leaveGicon, _("Leaving drawing mode"));
|
|
|
|
|
this.activeArea.leaveDrawingMode(save);
|
2019-03-05 08:36:59 -03:00
|
|
|
if (this.hiddenList)
|
|
|
|
|
this.togglePanelAndDockOpacity();
|
2019-03-10 09:05:38 -03:00
|
|
|
|
2020-06-24 18:16:22 -03:00
|
|
|
if (Main._findModal(this.activeArea) != -1)
|
2020-06-20 20:08:45 -03:00
|
|
|
this.toggleModal();
|
|
|
|
|
this.toggleContainer();
|
2019-03-05 08:36:59 -03:00
|
|
|
this.activeArea = null;
|
2020-06-20 07:59:46 -03:00
|
|
|
} else {
|
2019-03-05 08:36:59 -03:00
|
|
|
// avoid to deal with Meta changes (global.display/global.screen)
|
|
|
|
|
let currentIndex = Main.layoutManager.monitors.indexOf(Main.layoutManager.currentMonitor);
|
|
|
|
|
this.activeArea = this.areas[currentIndex];
|
2020-06-20 20:08:45 -03:00
|
|
|
this.toggleContainer();
|
|
|
|
|
if (!this.toggleModal()) {
|
|
|
|
|
this.toggleContainer();
|
|
|
|
|
this.activeArea = null;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-03-10 09:05:38 -03:00
|
|
|
|
2020-06-20 20:08:45 -03:00
|
|
|
this.activeArea.enterDrawingMode();
|
2019-03-28 18:01:39 -03:00
|
|
|
this.osdDisabled = this.settings.get_boolean('osd-disabled');
|
2020-06-20 07:59:46 -03:00
|
|
|
let label = _("<small>Press <i>%s</i> for help</small>").format(this.activeArea.helper.helpKeyLabel) + "\n\n" + _("Entering drawing mode");
|
|
|
|
|
this.showOsd(null, this.enterGicon, label, null, null, true);
|
2019-03-05 08:36:59 -03:00
|
|
|
}
|
2019-03-28 18:01:39 -03:00
|
|
|
|
|
|
|
|
if (this.indicator)
|
2020-06-20 20:08:45 -03:00
|
|
|
this.indicator.sync(Boolean(this.activeArea));
|
2019-03-05 08:36:59 -03:00
|
|
|
},
|
|
|
|
|
|
2020-06-25 06:41:15 -03:00
|
|
|
updateActionMode: function() {
|
|
|
|
|
Main.actionMode = (this.activeArea.isWriting ? WRITING_ACTION_MODE : DRAWING_ACTION_MODE) | Shell.ActionMode.NORMAL;
|
|
|
|
|
},
|
|
|
|
|
|
2020-06-20 09:25:23 -03:00
|
|
|
// Use level -1 to set no level through a signal.
|
2020-06-20 07:59:46 -03:00
|
|
|
showOsd: function(emitter, icon, label, color, level, long) {
|
2019-03-05 08:36:59 -03:00
|
|
|
let activeIndex = this.areas.indexOf(this.activeArea);
|
2020-06-20 07:59:46 -03:00
|
|
|
if (activeIndex == -1 || this.osdDisabled)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
let hideTimeoutSave;
|
2020-06-27 17:35:43 -03:00
|
|
|
if (long && GS_VERSION >= '3.28.0') {
|
|
|
|
|
hideTimeoutSave = OsdWindow.HIDE_TIMEOUT;
|
|
|
|
|
OsdWindow.HIDE_TIMEOUT = HIDE_TIMEOUT_LONG;
|
|
|
|
|
}
|
2020-06-20 07:59:46 -03:00
|
|
|
|
|
|
|
|
let maxLevel;
|
|
|
|
|
if (level == -1)
|
|
|
|
|
level = null;
|
|
|
|
|
else if (level > 100)
|
|
|
|
|
maxLevel = 2;
|
|
|
|
|
|
|
|
|
|
// GS 3.32- : bar from 0 to 100
|
|
|
|
|
// GS 3.34+ : bar from 0 to 1
|
|
|
|
|
if (level && GS_VERSION > '3.33.0')
|
|
|
|
|
level = level / 100;
|
|
|
|
|
|
|
|
|
|
if (icon && typeof icon == 'string')
|
|
|
|
|
icon = new Gio.ThemedIcon({ name: icon });
|
|
|
|
|
else if (!icon)
|
|
|
|
|
icon = this.enterGicon;
|
|
|
|
|
|
2020-06-20 09:25:23 -03:00
|
|
|
let osdWindow = Main.osdWindowManager._osdWindows[activeIndex];
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (!this.osdWindowConstraint)
|
|
|
|
|
this.osdWindowConstraint = new OsdWindowConstraint();
|
|
|
|
|
|
|
|
|
|
if (!osdWindow._box.get_constraint(this.osdWindowConstraint.constructor.name)) {
|
|
|
|
|
osdWindow._box.remove_constraint(osdWindow._boxConstraint);
|
|
|
|
|
osdWindow._box.add_constraint_with_name(this.osdWindowConstraint.constructor.name, this.osdWindowConstraint);
|
|
|
|
|
this.osdWindowConstraint._minSize = osdWindow._boxConstraint._minSize;
|
|
|
|
|
osdWindow._boxConstraintOld = osdWindow._boxConstraint;
|
|
|
|
|
osdWindow._boxConstraint = this.osdWindowConstraint;
|
|
|
|
|
let osdConstraintHandler = osdWindow._box.connect('notify::mapped', (box) => {
|
|
|
|
|
if (!box.mapped) {
|
|
|
|
|
osdWindow._boxConstraint = osdWindow._boxConstraintOld;
|
|
|
|
|
osdWindow._boxConstraint._minSize = this.osdWindowConstraint._minSize;
|
|
|
|
|
osdWindow._box.remove_constraint(this.osdWindowConstraint);
|
|
|
|
|
osdWindow._box.add_constraint(osdWindow._boxConstraint);
|
|
|
|
|
osdWindow._box.disconnect(osdConstraintHandler);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch(e) {
|
|
|
|
|
logError(e);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-20 07:59:46 -03:00
|
|
|
Main.osdWindowManager.show(activeIndex, icon, label, level, maxLevel);
|
2020-06-20 09:25:23 -03:00
|
|
|
osdWindow._label.get_clutter_text().set_use_markup(true);
|
2020-06-20 07:59:46 -03:00
|
|
|
|
|
|
|
|
if (color) {
|
2020-06-20 09:25:23 -03:00
|
|
|
osdWindow._icon.set_style(`color:${color};`);
|
|
|
|
|
osdWindow._label.set_style(`color:${color};`);
|
|
|
|
|
let osdColorChangedHandler = osdWindow._label.connect('notify::text', () => {
|
|
|
|
|
osdWindow._icon.set_style(`color:;`);
|
|
|
|
|
osdWindow._label.set_style(`color:;`);
|
|
|
|
|
osdWindow._label.disconnect(osdColorChangedHandler);
|
2020-06-20 07:59:46 -03:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (level === 0) {
|
2020-06-20 09:25:23 -03:00
|
|
|
osdWindow._label.add_style_class_name(WARNING_COLOR_STYLE_CLASS_NAME);
|
2020-06-20 07:59:46 -03:00
|
|
|
// the same label is shared by all GS OSD so the style must be removed after being used
|
2020-06-20 09:25:23 -03:00
|
|
|
let osdLabelChangedHandler = osdWindow._label.connect('notify::text', () => {
|
|
|
|
|
osdWindow._label.remove_style_class_name(WARNING_COLOR_STYLE_CLASS_NAME);
|
|
|
|
|
osdWindow._label.disconnect(osdLabelChangedHandler);
|
2020-06-20 07:59:46 -03:00
|
|
|
});
|
2019-03-12 19:37:34 -03:00
|
|
|
}
|
2020-06-20 07:59:46 -03:00
|
|
|
|
|
|
|
|
if (hideTimeoutSave)
|
|
|
|
|
OsdWindow.HIDE_TIMEOUT = hideTimeoutSave;
|
2019-03-05 08:36:59 -03:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
removeAreas: function() {
|
|
|
|
|
for (let i = 0; i < this.areas.length; i++) {
|
|
|
|
|
let area = this.areas[i];
|
2020-06-22 06:56:34 -03:00
|
|
|
area.disconnect(area.leaveDrawingHandler);
|
2020-06-25 06:41:15 -03:00
|
|
|
area.disconnect(area.updateActionModeHandler);
|
2020-06-22 06:56:34 -03:00
|
|
|
area.disconnect(area.showOsdHandler);
|
2020-07-30 06:13:23 -03:00
|
|
|
area.disconnect(area.showOsdGiconHandler);
|
2019-03-10 11:33:38 -03:00
|
|
|
let container = area.get_parent();
|
|
|
|
|
container.get_parent().remove_actor(container);
|
|
|
|
|
container.destroy();
|
2019-03-05 08:36:59 -03:00
|
|
|
}
|
|
|
|
|
this.areas = [];
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
disable: function() {
|
2020-01-06 17:24:29 -03:00
|
|
|
if (this.userStyleHandler && this.userStyleMonitor) {
|
|
|
|
|
this.userStyleMonitor.disconnect(this.userStyleHandler);
|
|
|
|
|
this.userStyleHandler = null;
|
|
|
|
|
}
|
|
|
|
|
if (this.userStyleMonitor) {
|
|
|
|
|
this.userStyleMonitor.cancel();
|
|
|
|
|
this.userStyleMonitor = null;
|
2019-03-05 08:36:59 -03:00
|
|
|
}
|
2019-03-08 08:28:03 -03:00
|
|
|
if (this.monitorChangedHandler) {
|
|
|
|
|
Main.layoutManager.disconnect(this.monitorChangedHandler);
|
|
|
|
|
this.monitorChangedHandler = null;
|
|
|
|
|
}
|
2019-03-28 18:01:39 -03:00
|
|
|
if (this.indicatorSettingHandler) {
|
|
|
|
|
this.settings.disconnect(this.indicatorSettingHandler);
|
|
|
|
|
this.indicatorSettingHandler = null;
|
|
|
|
|
}
|
2019-03-11 20:29:14 -03:00
|
|
|
if (this.desktopSettingHandler) {
|
|
|
|
|
this.settings.disconnect(this.desktopSettingHandler);
|
|
|
|
|
this.desktopSettingHandler = null;
|
|
|
|
|
}
|
|
|
|
|
if (this.persistentSettingHandler) {
|
|
|
|
|
this.settings.disconnect(this.persistentSettingHandler);
|
|
|
|
|
this.persistentSettingHandler = null;
|
|
|
|
|
}
|
2019-03-08 08:28:03 -03:00
|
|
|
|
2019-03-05 08:36:59 -03:00
|
|
|
if (this.activeArea)
|
|
|
|
|
this.toggleDrawing();
|
|
|
|
|
Main.wm.removeKeybinding('toggle-drawing');
|
2020-06-20 20:08:45 -03:00
|
|
|
Main.wm.removeKeybinding('toggle-modal');
|
2020-06-28 08:10:31 -03:00
|
|
|
Main.wm.removeKeybinding('erase-drawing');
|
2019-03-05 08:36:59 -03:00
|
|
|
this.removeAreas();
|
2019-03-28 18:01:39 -03:00
|
|
|
if (this.indicator)
|
|
|
|
|
this.indicator.disable();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-06-20 09:25:23 -03:00
|
|
|
// The same as the original, without forcing a ratio of 1.
|
|
|
|
|
const OsdWindowConstraint = new Lang.Class({
|
|
|
|
|
Name: 'DrawOnYourScreenOsdWindowConstraint',
|
|
|
|
|
Extends: OsdWindow.OsdWindowConstraint,
|
|
|
|
|
|
|
|
|
|
vfunc_update_allocation: function(actor, actorBox) {
|
|
|
|
|
// Clutter will adjust the allocation for margins,
|
|
|
|
|
// so add it to our minimum size
|
|
|
|
|
let minSize = this._minSize + actor.margin_top + actor.margin_bottom;
|
|
|
|
|
let [width, height] = actorBox.get_size();
|
|
|
|
|
|
|
|
|
|
// DO NOT Enforce a ratio of 1
|
|
|
|
|
let newWidth = Math.ceil(Math.max(minSize, width, height));
|
|
|
|
|
let newHeight = Math.ceil(Math.max(minSize, height));
|
|
|
|
|
actorBox.set_size(newWidth, newHeight);
|
|
|
|
|
|
|
|
|
|
// Recenter
|
|
|
|
|
let [x, y] = actorBox.get_origin();
|
|
|
|
|
actorBox.set_origin(Math.ceil(x + width / 2 - newWidth / 2),
|
|
|
|
|
Math.ceil(y + height / 2 - newHeight / 2));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const DrawingIndicator = new Lang.Class({
|
2019-03-28 18:01:39 -03:00
|
|
|
Name: 'DrawOnYourScreenIndicator',
|
|
|
|
|
|
|
|
|
|
_init: function() {
|
|
|
|
|
let [menuAlignment, dontCreateMenu] = [0, true];
|
|
|
|
|
this.button = new PanelMenu.Button(menuAlignment, "Drawing Indicator", dontCreateMenu);
|
2019-10-11 04:22:37 -03:00
|
|
|
this.buttonActor = GS_VERSION < '3.33.0' ? this.button.actor: this.button;
|
2019-03-28 18:01:39 -03:00
|
|
|
Main.panel.addToStatusArea('draw-on-your-screen-indicator', this.button);
|
|
|
|
|
|
|
|
|
|
this.icon = new St.Icon({ icon_name: 'applications-graphics-symbolic',
|
|
|
|
|
style_class: 'system-status-icon screencast-indicator' });
|
2019-10-11 04:22:37 -03:00
|
|
|
this.buttonActor.add_child(this.icon);
|
|
|
|
|
this.buttonActor.visible = false;
|
2019-03-28 18:01:39 -03:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
sync: function(visible) {
|
2019-10-11 04:22:37 -03:00
|
|
|
this.buttonActor.visible = visible;
|
2019-03-28 18:01:39 -03:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
disable: function() {
|
|
|
|
|
this.button.destroy();
|
2019-03-05 08:36:59 -03:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2019-11-27 02:04:37 -03:00
|
|
|
function setCursor(cursorName) {
|
|
|
|
|
// check display or screen (API changes)
|
|
|
|
|
if (global.display.set_cursor)
|
|
|
|
|
global.display.set_cursor(Meta.Cursor[cursorName]);
|
|
|
|
|
else if (global.screen && global.screen.set_cursor)
|
|
|
|
|
global.screen.set_cursor(Meta.Cursor[cursorName]);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-05 08:36:59 -03:00
|
|
|
|