Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // It would be nice if a "focused" prop was
- // provided by default by ShellApps...
- //
- // Things also get a little weird when there are more
- // than one instance of a player running at the same time.
- // As far as ShellApp is concerned they are the same app.
- // So we have to jump though a bunch of hoops to keep track
- // of and differentiate the windows.
- var AppFocusWrapper = GObject.registerClass({
- GTypeName: "AppFocusWrapper",
- Properties: {
- "focused": GObject.ParamSpec.boolean(
- "focused", // property name
- "focused-prop", // nickname
- "If any window that belongs to the app is focused", // description
- GObject.ParamFlags.READABLE, // flags READABLE/READWRITE/CONSTRUCT/etc
- false // default value
- )
- }
- }, class AppFocusWrapper extends GObject.Object {
- _init(shellApp, busName) {
- super._init();
- this._app = shellApp;
- this._busName = busName;
- this._focused = false;
- this._onWindowsChanged();
- this._onAppearsFocusedChanged();
- this._windowsChangedId = this._app.connect(
- "windows-changed",
- this._onWindowsChanged.bind(this)
- );
- }
- get focused() {
- return this._focused;
- }
- _getNewAppWindow() {
- // We want an "unclaimed" "Normal" window.
- // Windows of all kinds, from all instances
- // of an app will show up in "get_windows".
- for (let window of this._app.get_windows()) {
- if (!window.skip_taskbar &&
- window.window_type === Meta.WindowType.NORMAL &&
- !window.hasOwnProperty("_busName")) {
- return window;
- }
- }
- return null;
- }
- _getCurrentAppWindow() {
- // We only want the window that matches this instance if any.
- for (let window of this._app.get_windows()) {
- if (window.hasOwnProperty("_busName") && window._busName === this._busName) {
- return window;
- }
- }
- return null;
- }
- _getNumOfInstances() {
- // Count the number of "claimed" windows.
- return Array.from(this._app.get_windows()).filter(w => w.hasOwnProperty("_busName")).length;
- }
- _onWindowsChanged() {
- // We get this signal when windows appear and disappear.
- // We only really care about them appearing.
- // We handle the disappear in _onUnmanaged.
- let currentAppWindow = this._getCurrentAppWindow();
- if (!currentAppWindow) {
- let appWindow = this._getNewAppWindow();
- if (appWindow) {
- appWindow._busName = this._busName;
- appWindow._unmanagedId = appWindow.connect(
- "unmanaged",
- this._onUnmanaged.bind(this)
- );
- appWindow._appearsFocusedId = appWindow.connect(
- "notify::appears-focused",
- this._onAppearsFocusedChanged.bind(this)
- );
- }
- }
- }
- _onAppearsFocusedChanged() {
- // Pretty self explanatory...
- let currentAppWindow = this._getCurrentAppWindow();
- let focused = currentAppWindow && currentAppWindow.has_focus();
- if (this._focused != focused) {
- this._focused = focused;
- this.notify("focused");
- }
- }
- _onUnmanaged() {
- // Basically for our purposes an "unmanaged" window is
- // one that has been hidden and is about to be destroyed.
- // So we disconnect our signals.
- let currentAppWindow = this._getCurrentAppWindow();
- if (currentAppWindow) {
- if (currentAppWindow.hasOwnProperty("_unmanagedId") && currentAppWindow._unmanagedId) {
- currentAppWindow.disconnect(appWindow._unmanagedId);
- currentAppWindow._unmanagedId = null;
- }
- if (currentAppWindow.hasOwnProperty("_appearsFocusedId") && currentAppWindow._appearsFocusedId) {
- currentAppWindow.disconnect(appWindow._appearsFocusedId);
- currentAppWindow._appearsFocusedId = null;
- }
- }
- }
- toggleWindow(minimize) {
- if (!this._focused) {
- // This is important. If we just called "activate" on an
- // app with more than one instance we'd just raise the
- // last active window regardless of which instance
- // we actually wanted to raise.
- // Multiple instance apps that have their window hidden
- // will get the last active window.
- if (this._getNumOfInstances() > 1) {
- let currentAppWindow = this._getCurrentAppWindow();
- let eventTimeStamp = Gtk.get_current_event_time();
- this._app.activate_window(
- currentAppWindow,
- eventTimeStamp
- );
- } else {
- this._app.activate();
- }
- return true;
- } else if (minimize) {
- let currentAppWindow = this._getCurrentAppWindow();
- if (currentAppWindow && currentAppWindow.can_minimize()) {
- currentAppWindow.minimize();
- return true;
- }
- }
- return false;
- }
- destroy() {
- if (this._app && this._windowsChangedId) {
- this._app.disconnect(this._windowsChangedId);
- }
- this._windowsChangedId = null;
- this._onUnmanaged();
- this._app = null;
- this._focused = null;
- this._busName = null;
- super.run_dispose();
- }
- });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement