diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index f9c7dd9a..b383c919 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -4,439 +4,11 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- -import Clutter from 'gi://Clutter'; -import Gio from 'gi://Gio'; -import GObject from 'gi://GObject'; -import Meta from 'gi://Meta'; -import St from 'gi://St'; +import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js'; -import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js'; - -import * as DND from 'resource:///org/gnome/shell/ui/dnd.js'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'; -import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js'; -import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'; -const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences'; -const WORKSPACE_KEY = 'workspace-names'; - -const TOOLTIP_OFFSET = 6; -const TOOLTIP_ANIMATION_TIME = 150; - -const MAX_THUMBNAILS = 6; - -class WindowPreview extends St.Button { - static { - GObject.registerClass(this); - } - - constructor(window) { - super({ - style_class: 'workspace-indicator-window-preview', - }); - - this._delegate = this; - DND.makeDraggable(this, {restoreOnSuccess: true}); - - this._window = window; - - this._window.connectObject( - 'size-changed', () => this._checkRelayout(), - 'position-changed', () => this._checkRelayout(), - 'notify::minimized', this._updateVisible.bind(this), - 'notify::window-type', this._updateVisible.bind(this), - this); - this._updateVisible(); - - global.display.connectObject('notify::focus-window', - this._onFocusChanged.bind(this), this); - this._onFocusChanged(); - } - - // needed for DND - get metaWindow() { - return this._window; - } - - _onFocusChanged() { - if (global.display.focus_window === this._window) - this.add_style_class_name('active'); - else - this.remove_style_class_name('active'); - } - - _checkRelayout() { - const monitor = Main.layoutManager.findIndexForActor(this); - const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); - if (this._window.get_frame_rect().overlap(workArea)) - this.queue_relayout(); - } - - _updateVisible() { - this.visible = this._window.window_type !== Meta.WindowType.DESKTOP && - this._window.showing_on_its_workspace(); - } -} - -class WorkspaceLayout extends Clutter.LayoutManager { - static { - GObject.registerClass(this); - } - - vfunc_get_preferred_width() { - return [0, 0]; - } - - vfunc_get_preferred_height() { - return [0, 0]; - } - - vfunc_allocate(container, box) { - const monitor = Main.layoutManager.findIndexForActor(container); - const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); - const hscale = box.get_width() / workArea.width; - const vscale = box.get_height() / workArea.height; - - for (const child of container) { - const childBox = new Clutter.ActorBox(); - const frameRect = child.metaWindow.get_frame_rect(); - childBox.set_size( - Math.round(Math.min(frameRect.width, workArea.width) * hscale), - Math.round(Math.min(frameRect.height, workArea.height) * vscale)); - childBox.set_origin( - Math.round((frameRect.x - workArea.x) * hscale), - Math.round((frameRect.y - workArea.y) * vscale)); - child.allocate(childBox); - } - } -} - -class WorkspaceThumbnail extends St.Button { - static { - GObject.registerClass(this); - } - - constructor(index) { - super({ - style_class: 'workspace', - child: new Clutter.Actor({ - layout_manager: new WorkspaceLayout(), - clip_to_allocation: true, - x_expand: true, - y_expand: true, - }), - }); - - this._tooltip = new St.Label({ - style_class: 'dash-label', - visible: false, - }); - Main.uiGroup.add_child(this._tooltip); - - this.connect('destroy', this._onDestroy.bind(this)); - this.connect('notify::hover', this._syncTooltip.bind(this)); - - this._index = index; - this._delegate = this; // needed for DND - - this._windowPreviews = new Map(); - - let workspaceManager = global.workspace_manager; - this._workspace = workspaceManager.get_workspace_by_index(index); - - this._workspace.connectObject( - 'window-added', (ws, window) => this._addWindow(window), - 'window-removed', (ws, window) => this._removeWindow(window), - this); - - global.display.connectObject('restacked', - this._onRestacked.bind(this), this); - - this._workspace.list_windows().forEach(w => this._addWindow(w)); - this._onRestacked(); - } - - acceptDrop(source) { - if (!source.metaWindow) - return false; - - this._moveWindow(source.metaWindow); - return true; - } - - handleDragOver(source) { - if (source.metaWindow) - return DND.DragMotionResult.MOVE_DROP; - else - return DND.DragMotionResult.CONTINUE; - } - - _addWindow(window) { - if (this._windowPreviews.has(window)) - return; - - let preview = new WindowPreview(window); - preview.connect('clicked', (a, btn) => this.emit('clicked', btn)); - this._windowPreviews.set(window, preview); - this.child.add_child(preview); - } - - _removeWindow(window) { - let preview = this._windowPreviews.get(window); - if (!preview) - return; - - this._windowPreviews.delete(window); - preview.destroy(); - } - - _onRestacked() { - let lastPreview = null; - let windows = global.get_window_actors().map(a => a.meta_window); - for (let i = 0; i < windows.length; i++) { - let preview = this._windowPreviews.get(windows[i]); - if (!preview) - continue; - - this.child.set_child_above_sibling(preview, lastPreview); - lastPreview = preview; - } - } - - _moveWindow(window) { - let monitorIndex = Main.layoutManager.findIndexForActor(this); - if (monitorIndex !== window.get_monitor()) - window.move_to_monitor(monitorIndex); - window.change_workspace_by_index(this._index, false); - } - - on_clicked() { - let ws = global.workspace_manager.get_workspace_by_index(this._index); - if (ws) - ws.activate(global.get_current_time()); - } - - _syncTooltip() { - if (this.hover) { - this._tooltip.set({ - text: Meta.prefs_get_workspace_name(this._index), - visible: true, - opacity: 0, - }); - - const [stageX, stageY] = this.get_transformed_position(); - const thumbWidth = this.allocation.get_width(); - const thumbHeight = this.allocation.get_height(); - const tipWidth = this._tooltip.width; - const xOffset = Math.floor((thumbWidth - tipWidth) / 2); - const monitor = Main.layoutManager.findMonitorForActor(this); - const x = Math.clamp( - stageX + xOffset, - monitor.x, - monitor.x + monitor.width - tipWidth); - const y = stageY + thumbHeight + TOOLTIP_OFFSET; - this._tooltip.set_position(x, y); - } - - this._tooltip.ease({ - opacity: this.hover ? 255 : 0, - duration: TOOLTIP_ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - onComplete: () => (this._tooltip.visible = this.hover), - }); - } - - _onDestroy() { - this._tooltip.destroy(); - } -} - -class WorkspaceIndicator extends PanelMenu.Button { - static { - GObject.registerClass(this); - } - - constructor() { - super(0.5, _('Workspace Indicator')); - - let container = new St.Widget({ - layout_manager: new Clutter.BinLayout(), - x_expand: true, - y_expand: true, - }); - this.add_child(container); - - let workspaceManager = global.workspace_manager; - - this._currentWorkspace = workspaceManager.get_active_workspace_index(); - this._statusLabel = new St.Label({ - style_class: 'panel-workspace-indicator', - y_align: Clutter.ActorAlign.CENTER, - text: this._labelText(), - }); - - container.add_child(this._statusLabel); - - this._thumbnailsBox = new St.BoxLayout({ - style_class: 'panel-workspace-indicator-box', - y_expand: true, - reactive: true, - }); - - container.add_child(this._thumbnailsBox); - - this._workspacesItems = []; - this._workspaceSection = new PopupMenu.PopupMenuSection(); - this.menu.addMenuItem(this._workspaceSection); - - workspaceManager.connectObject( - 'notify::n-workspaces', this._nWorkspacesChanged.bind(this), GObject.ConnectFlags.AFTER, - 'workspace-switched', this._onWorkspaceSwitched.bind(this), GObject.ConnectFlags.AFTER, - 'notify::layout-rows', this._updateThumbnailVisibility.bind(this), - this); - - this.connect('scroll-event', this._onScrollEvent.bind(this)); - this._thumbnailsBox.connect('scroll-event', this._onScrollEvent.bind(this)); - this._createWorkspacesSection(); - this._updateThumbnails(); - this._updateThumbnailVisibility(); - - this._settings = new Gio.Settings({schema_id: WORKSPACE_SCHEMA}); - this._settings.connectObject(`changed::${WORKSPACE_KEY}`, - this._updateMenuLabels.bind(this), this); - } - - _onDestroy() { - Main.panel.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS); - - super._onDestroy(); - } - - _updateThumbnailVisibility() { - const {workspaceManager} = global; - const vertical = workspaceManager.layout_rows === -1; - const useMenu = - vertical || workspaceManager.n_workspaces > MAX_THUMBNAILS; - this.reactive = useMenu; - - this._statusLabel.visible = useMenu; - this._thumbnailsBox.visible = !useMenu; - - // Disable offscreen-redirect when showing the workspace switcher - // so that clip-to-allocation works - Main.panel.set_offscreen_redirect(useMenu - ? Clutter.OffscreenRedirect.ALWAYS - : Clutter.OffscreenRedirect.AUTOMATIC_FOR_OPACITY); - } - - _onWorkspaceSwitched() { - this._currentWorkspace = global.workspace_manager.get_active_workspace_index(); - - this._updateMenuOrnament(); - this._updateActiveThumbnail(); - - this._statusLabel.set_text(this._labelText()); - } - - _nWorkspacesChanged() { - this._createWorkspacesSection(); - this._updateThumbnails(); - this._updateThumbnailVisibility(); - } - - _updateMenuOrnament() { - for (let i = 0; i < this._workspacesItems.length; i++) { - this._workspacesItems[i].setOrnament(i === this._currentWorkspace - ? PopupMenu.Ornament.DOT - : PopupMenu.Ornament.NO_DOT); - } - } - - _updateActiveThumbnail() { - let thumbs = this._thumbnailsBox.get_children(); - for (let i = 0; i < thumbs.length; i++) { - if (i === this._currentWorkspace) - thumbs[i].add_style_class_name('active'); - else - thumbs[i].remove_style_class_name('active'); - } - } - - _labelText(workspaceIndex) { - if (workspaceIndex === undefined) { - workspaceIndex = this._currentWorkspace; - return (workspaceIndex + 1).toString(); - } - return Meta.prefs_get_workspace_name(workspaceIndex); - } - - _updateMenuLabels() { - for (let i = 0; i < this._workspacesItems.length; i++) - this._workspacesItems[i].label.text = this._labelText(i); - } - - _createWorkspacesSection() { - let workspaceManager = global.workspace_manager; - - this._workspaceSection.removeAll(); - this._workspacesItems = []; - this._currentWorkspace = workspaceManager.get_active_workspace_index(); - - let i = 0; - for (; i < workspaceManager.n_workspaces; i++) { - this._workspacesItems[i] = new PopupMenu.PopupMenuItem(this._labelText(i)); - this._workspaceSection.addMenuItem(this._workspacesItems[i]); - this._workspacesItems[i].workspaceId = i; - this._workspacesItems[i].label_actor = this._statusLabel; - this._workspacesItems[i].connect('activate', (actor, _event) => { - this._activate(actor.workspaceId); - }); - - this._workspacesItems[i].setOrnament(i === this._currentWorkspace - ? PopupMenu.Ornament.DOT - : PopupMenu.Ornament.NO_DOT); - } - - this._statusLabel.set_text(this._labelText()); - } - - _updateThumbnails() { - let workspaceManager = global.workspace_manager; - - this._thumbnailsBox.destroy_all_children(); - - for (let i = 0; i < workspaceManager.n_workspaces; i++) { - let thumb = new WorkspaceThumbnail(i); - this._thumbnailsBox.add_child(thumb); - } - this._updateActiveThumbnail(); - } - - _activate(index) { - let workspaceManager = global.workspace_manager; - - if (index >= 0 && index < workspaceManager.n_workspaces) { - let metaWorkspace = workspaceManager.get_workspace_by_index(index); - metaWorkspace.activate(global.get_current_time()); - } - } - - _onScrollEvent(actor, event) { - let direction = event.get_scroll_direction(); - let diff = 0; - if (direction === Clutter.ScrollDirection.DOWN) - diff = 1; - else if (direction === Clutter.ScrollDirection.UP) - diff = -1; - else - return; - - - let newIndex = global.workspace_manager.get_active_workspace_index() + diff; - this._activate(newIndex); - } -} +import {WorkspaceIndicator} from './workspaceIndicator.js'; export default class WorkspaceIndicatorExtension extends Extension { enable() { diff --git a/extensions/workspace-indicator/meson.build b/extensions/workspace-indicator/meson.build index 36daa535..6dd08dae 100644 --- a/extensions/workspace-indicator/meson.build +++ b/extensions/workspace-indicator/meson.build @@ -9,4 +9,4 @@ extension_data += configure_file( ) extension_data += files('stylesheet.css') -extension_sources += files('prefs.js') +extension_sources += files('prefs.js', 'workspaceIndicator.js') diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js new file mode 100644 index 00000000..6b0903d5 --- /dev/null +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -0,0 +1,438 @@ +// SPDX-FileCopyrightText: 2011 Erick Pérez Castellanos +// SPDX-FileCopyrightText: 2011 Giovanni Campagna +// SPDX-FileCopyrightText: 2017 Florian Müllner +// +// SPDX-License-Identifier: GPL-2.0-or-later + +import Clutter from 'gi://Clutter'; +import Gio from 'gi://Gio'; +import GObject from 'gi://GObject'; +import Meta from 'gi://Meta'; +import St from 'gi://St'; + +import {gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js'; + +import * as DND from 'resource:///org/gnome/shell/ui/dnd.js'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js'; +import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'; + +const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences'; +const WORKSPACE_KEY = 'workspace-names'; + +const TOOLTIP_OFFSET = 6; +const TOOLTIP_ANIMATION_TIME = 150; + +const MAX_THUMBNAILS = 6; + +class WindowPreview extends St.Button { + static { + GObject.registerClass(this); + } + + constructor(window) { + super({ + style_class: 'workspace-indicator-window-preview', + }); + + this._delegate = this; + DND.makeDraggable(this, {restoreOnSuccess: true}); + + this._window = window; + + this._window.connectObject( + 'size-changed', () => this._checkRelayout(), + 'position-changed', () => this._checkRelayout(), + 'notify::minimized', this._updateVisible.bind(this), + 'notify::window-type', this._updateVisible.bind(this), + this); + this._updateVisible(); + + global.display.connectObject('notify::focus-window', + this._onFocusChanged.bind(this), this); + this._onFocusChanged(); + } + + // needed for DND + get metaWindow() { + return this._window; + } + + _onFocusChanged() { + if (global.display.focus_window === this._window) + this.add_style_class_name('active'); + else + this.remove_style_class_name('active'); + } + + _checkRelayout() { + const monitor = Main.layoutManager.findIndexForActor(this); + const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); + if (this._window.get_frame_rect().overlap(workArea)) + this.queue_relayout(); + } + + _updateVisible() { + this.visible = this._window.window_type !== Meta.WindowType.DESKTOP && + this._window.showing_on_its_workspace(); + } +} + +class WorkspaceLayout extends Clutter.LayoutManager { + static { + GObject.registerClass(this); + } + + vfunc_get_preferred_width() { + return [0, 0]; + } + + vfunc_get_preferred_height() { + return [0, 0]; + } + + vfunc_allocate(container, box) { + const monitor = Main.layoutManager.findIndexForActor(container); + const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); + const hscale = box.get_width() / workArea.width; + const vscale = box.get_height() / workArea.height; + + for (const child of container) { + const childBox = new Clutter.ActorBox(); + const frameRect = child.metaWindow.get_frame_rect(); + childBox.set_size( + Math.round(Math.min(frameRect.width, workArea.width) * hscale), + Math.round(Math.min(frameRect.height, workArea.height) * vscale)); + childBox.set_origin( + Math.round((frameRect.x - workArea.x) * hscale), + Math.round((frameRect.y - workArea.y) * vscale)); + child.allocate(childBox); + } + } +} + +class WorkspaceThumbnail extends St.Button { + static { + GObject.registerClass(this); + } + + constructor(index) { + super({ + style_class: 'workspace', + child: new Clutter.Actor({ + layout_manager: new WorkspaceLayout(), + clip_to_allocation: true, + x_expand: true, + y_expand: true, + }), + }); + + this._tooltip = new St.Label({ + style_class: 'dash-label', + visible: false, + }); + Main.uiGroup.add_child(this._tooltip); + + this.connect('destroy', this._onDestroy.bind(this)); + this.connect('notify::hover', this._syncTooltip.bind(this)); + + this._index = index; + this._delegate = this; // needed for DND + + this._windowPreviews = new Map(); + + let workspaceManager = global.workspace_manager; + this._workspace = workspaceManager.get_workspace_by_index(index); + + this._workspace.connectObject( + 'window-added', (ws, window) => this._addWindow(window), + 'window-removed', (ws, window) => this._removeWindow(window), + this); + + global.display.connectObject('restacked', + this._onRestacked.bind(this), this); + + this._workspace.list_windows().forEach(w => this._addWindow(w)); + this._onRestacked(); + } + + acceptDrop(source) { + if (!source.metaWindow) + return false; + + this._moveWindow(source.metaWindow); + return true; + } + + handleDragOver(source) { + if (source.metaWindow) + return DND.DragMotionResult.MOVE_DROP; + else + return DND.DragMotionResult.CONTINUE; + } + + _addWindow(window) { + if (this._windowPreviews.has(window)) + return; + + let preview = new WindowPreview(window); + preview.connect('clicked', (a, btn) => this.emit('clicked', btn)); + this._windowPreviews.set(window, preview); + this.child.add_child(preview); + } + + _removeWindow(window) { + let preview = this._windowPreviews.get(window); + if (!preview) + return; + + this._windowPreviews.delete(window); + preview.destroy(); + } + + _onRestacked() { + let lastPreview = null; + let windows = global.get_window_actors().map(a => a.meta_window); + for (let i = 0; i < windows.length; i++) { + let preview = this._windowPreviews.get(windows[i]); + if (!preview) + continue; + + this.child.set_child_above_sibling(preview, lastPreview); + lastPreview = preview; + } + } + + _moveWindow(window) { + let monitorIndex = Main.layoutManager.findIndexForActor(this); + if (monitorIndex !== window.get_monitor()) + window.move_to_monitor(monitorIndex); + window.change_workspace_by_index(this._index, false); + } + + on_clicked() { + let ws = global.workspace_manager.get_workspace_by_index(this._index); + if (ws) + ws.activate(global.get_current_time()); + } + + _syncTooltip() { + if (this.hover) { + this._tooltip.set({ + text: Meta.prefs_get_workspace_name(this._index), + visible: true, + opacity: 0, + }); + + const [stageX, stageY] = this.get_transformed_position(); + const thumbWidth = this.allocation.get_width(); + const thumbHeight = this.allocation.get_height(); + const tipWidth = this._tooltip.width; + const xOffset = Math.floor((thumbWidth - tipWidth) / 2); + const monitor = Main.layoutManager.findMonitorForActor(this); + const x = Math.clamp( + stageX + xOffset, + monitor.x, + monitor.x + monitor.width - tipWidth); + const y = stageY + thumbHeight + TOOLTIP_OFFSET; + this._tooltip.set_position(x, y); + } + + this._tooltip.ease({ + opacity: this.hover ? 255 : 0, + duration: TOOLTIP_ANIMATION_TIME, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + onComplete: () => (this._tooltip.visible = this.hover), + }); + } + + _onDestroy() { + this._tooltip.destroy(); + } +} + +export class WorkspaceIndicator extends PanelMenu.Button { + static { + GObject.registerClass(this); + } + + constructor() { + super(0.5, _('Workspace Indicator')); + + let container = new St.Widget({ + layout_manager: new Clutter.BinLayout(), + x_expand: true, + y_expand: true, + }); + this.add_child(container); + + let workspaceManager = global.workspace_manager; + + this._currentWorkspace = workspaceManager.get_active_workspace_index(); + this._statusLabel = new St.Label({ + style_class: 'panel-workspace-indicator', + y_align: Clutter.ActorAlign.CENTER, + text: this._labelText(), + }); + + container.add_child(this._statusLabel); + + this._thumbnailsBox = new St.BoxLayout({ + style_class: 'panel-workspace-indicator-box', + y_expand: true, + reactive: true, + }); + + container.add_child(this._thumbnailsBox); + + this._workspacesItems = []; + this._workspaceSection = new PopupMenu.PopupMenuSection(); + this.menu.addMenuItem(this._workspaceSection); + + workspaceManager.connectObject( + 'notify::n-workspaces', this._nWorkspacesChanged.bind(this), GObject.ConnectFlags.AFTER, + 'workspace-switched', this._onWorkspaceSwitched.bind(this), GObject.ConnectFlags.AFTER, + 'notify::layout-rows', this._updateThumbnailVisibility.bind(this), + this); + + this.connect('scroll-event', this._onScrollEvent.bind(this)); + this._thumbnailsBox.connect('scroll-event', this._onScrollEvent.bind(this)); + this._createWorkspacesSection(); + this._updateThumbnails(); + this._updateThumbnailVisibility(); + + this._settings = new Gio.Settings({schema_id: WORKSPACE_SCHEMA}); + this._settings.connectObject(`changed::${WORKSPACE_KEY}`, + this._updateMenuLabels.bind(this), this); + } + + _onDestroy() { + Main.panel.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS); + + super._onDestroy(); + } + + _updateThumbnailVisibility() { + const {workspaceManager} = global; + const vertical = workspaceManager.layout_rows === -1; + const useMenu = + vertical || workspaceManager.n_workspaces > MAX_THUMBNAILS; + this.reactive = useMenu; + + this._statusLabel.visible = useMenu; + this._thumbnailsBox.visible = !useMenu; + + // Disable offscreen-redirect when showing the workspace switcher + // so that clip-to-allocation works + Main.panel.set_offscreen_redirect(useMenu + ? Clutter.OffscreenRedirect.ALWAYS + : Clutter.OffscreenRedirect.AUTOMATIC_FOR_OPACITY); + } + + _onWorkspaceSwitched() { + this._currentWorkspace = global.workspace_manager.get_active_workspace_index(); + + this._updateMenuOrnament(); + this._updateActiveThumbnail(); + + this._statusLabel.set_text(this._labelText()); + } + + _nWorkspacesChanged() { + this._createWorkspacesSection(); + this._updateThumbnails(); + this._updateThumbnailVisibility(); + } + + _updateMenuOrnament() { + for (let i = 0; i < this._workspacesItems.length; i++) { + this._workspacesItems[i].setOrnament(i === this._currentWorkspace + ? PopupMenu.Ornament.DOT + : PopupMenu.Ornament.NO_DOT); + } + } + + _updateActiveThumbnail() { + let thumbs = this._thumbnailsBox.get_children(); + for (let i = 0; i < thumbs.length; i++) { + if (i === this._currentWorkspace) + thumbs[i].add_style_class_name('active'); + else + thumbs[i].remove_style_class_name('active'); + } + } + + _labelText(workspaceIndex) { + if (workspaceIndex === undefined) { + workspaceIndex = this._currentWorkspace; + return (workspaceIndex + 1).toString(); + } + return Meta.prefs_get_workspace_name(workspaceIndex); + } + + _updateMenuLabels() { + for (let i = 0; i < this._workspacesItems.length; i++) + this._workspacesItems[i].label.text = this._labelText(i); + } + + _createWorkspacesSection() { + let workspaceManager = global.workspace_manager; + + this._workspaceSection.removeAll(); + this._workspacesItems = []; + this._currentWorkspace = workspaceManager.get_active_workspace_index(); + + let i = 0; + for (; i < workspaceManager.n_workspaces; i++) { + this._workspacesItems[i] = new PopupMenu.PopupMenuItem(this._labelText(i)); + this._workspaceSection.addMenuItem(this._workspacesItems[i]); + this._workspacesItems[i].workspaceId = i; + this._workspacesItems[i].label_actor = this._statusLabel; + this._workspacesItems[i].connect('activate', (actor, _event) => { + this._activate(actor.workspaceId); + }); + + this._workspacesItems[i].setOrnament(i === this._currentWorkspace + ? PopupMenu.Ornament.DOT + : PopupMenu.Ornament.NO_DOT); + } + + this._statusLabel.set_text(this._labelText()); + } + + _updateThumbnails() { + let workspaceManager = global.workspace_manager; + + this._thumbnailsBox.destroy_all_children(); + + for (let i = 0; i < workspaceManager.n_workspaces; i++) { + let thumb = new WorkspaceThumbnail(i); + this._thumbnailsBox.add_child(thumb); + } + this._updateActiveThumbnail(); + } + + _activate(index) { + let workspaceManager = global.workspace_manager; + + if (index >= 0 && index < workspaceManager.n_workspaces) { + let metaWorkspace = workspaceManager.get_workspace_by_index(index); + metaWorkspace.activate(global.get_current_time()); + } + } + + _onScrollEvent(actor, event) { + let direction = event.get_scroll_direction(); + let diff = 0; + if (direction === Clutter.ScrollDirection.DOWN) + diff = 1; + else if (direction === Clutter.ScrollDirection.UP) + diff = -1; + else + return; + + + let newIndex = global.workspace_manager.get_active_workspace_index() + diff; + this._activate(newIndex); + } +} diff --git a/po/POTFILES.in b/po/POTFILES.in index 4abfcfca..4ddf88bc 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -19,5 +19,5 @@ extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml extensions/window-list/prefs.js extensions/window-list/workspaceIndicator.js extensions/windowsNavigator/extension.js -extensions/workspace-indicator/extension.js extensions/workspace-indicator/prefs.js +extensions/workspace-indicator/workspaceIndicator.js