/*SPDX-FileCopyrightText: 2012-2016 Eike Hein <hein@kde.org>SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <kde@privat.broulik.de>SPDX-License-Identifier: GPL-2.0-or-later*/import QtQuickimport org.kde.plasma.plasmoidimport org.kde.plasma.core as PlasmaCoreimport org.kde.plasma.extras as PlasmaExtrasimport org.kde.taskmanager as TaskManagerimport org.kde.plasma.private.mpris as Mprisimport plasma.applet.org.kde.plasma.taskmanager as TaskManagerAppletPlasmaExtras.Menu {id: menurequired property TaskManagerApplet.Backend backendrequired property Mpris.Mpris2Model mpris2Sourcerequired property /*QModelIndex*/var modelIndexreadonly property var atm: TaskManager.AbstractTasksModelproperty bool showAllPlaces: falseplacement: {if (Plasmoid.location === PlasmaCore.Types.LeftEdge) {return PlasmaExtras.Menu.RightPosedTopAlignedPopup;} else if (Plasmoid.location === PlasmaCore.Types.TopEdge) {return PlasmaExtras.Menu.BottomPosedLeftAlignedPopup;} else if (Plasmoid.location === PlasmaCore.Types.RightEdge) {return PlasmaExtras.Menu.LeftPosedTopAlignedPopup;} else {return PlasmaExtras.Menu.TopPosedLeftAlignedPopup;}}minimumWidth: (visualParent as Item).widthonStatusChanged: {if (visualParent && get(TaskManager.AbstractTasksModel.LauncherUrlWithoutIcon).toString() !== "" && status === PlasmaExtras.Menu.Open) {activitiesDesktopsMenu.refresh();} else if (status === PlasmaExtras.Menu.Closed) {menu.destroy();}}Component.onCompleted: {// Cannot have "Connections" as child of PlasmaExtras.Menu.backend.showAllPlaces.connect(showContextMenuWithAllPlaces);}Component.onDestruction: {backend.showAllPlaces.disconnect(showContextMenuWithAllPlaces);}function showContextMenuWithAllPlaces(): void {(visualParent as Task).showContextMenu({showAllPlaces: true});}function get(modelProp: int): var {return tasksModel.data(modelIndex, modelProp)}function show(): void {Plasmoid.contextualActionsAboutToShow();loadDynamicLaunchActions(get(TaskManager.AbstractTasksModel.LauncherUrlWithoutIcon));openRelative();}function newMenuItem(parent: QtObject): PlasmaExtras.MenuItem {return Qt.createQmlObject(`import org.kde.plasma.extras as PlasmaExtrasPlasmaExtras.MenuItem {}`, parent) as PlasmaExtras.MenuItem;}function newSeparator(parent: QtObject): PlasmaExtras.MenuItem {return Qt.createQmlObject(`import org.kde.plasma.extras as PlasmaExtrasPlasmaExtras.MenuItem { separator: true }`, parent) as PlasmaExtras.MenuItem;}function loadDynamicLaunchActions(launcherUrl: url): void {let sections = [];const placesActions = backend.placesActions(launcherUrl, showAllPlaces, menu);if (placesActions.length > 0) {sections.push({title: i18nc("@title:group for section of menu items", "Places"),group: "places",actions: placesActions});} else {sections.push({title: i18nc("@title:group for section of menu items", "Recent Files"),group: "recents",actions: backend.recentDocumentActions(launcherUrl, menu)});}// We always have actions category.sections = sections.filter(section => section.actions.length > 0);sections.push({title: i18nc("@title:group for section of menu items", "Actions"),group: "actions",actions: backend.jumpListActions(launcherUrl, menu)});// C++ can override section heading by returning a QString as first actionsections.forEach((section) => {if (typeof section.actions[0] === "string") {section.title = section.actions.shift(); // take first}});// QMenu does not limit its width automatically. Even if we set a maximumWidth// it would just cut off text rather than eliding. So we do this manually.const textMetrics = Qt.createQmlObject("import QtQuick; TextMetrics {}", menu);textMetrics.elide = Qt.ElideRight;textMetrics.elideWidth = TaskManagerApplet.LayoutMetrics.maximumContextMenuTextWidth();sections.forEach(section => {if (section["actions"].length > 0 || section["group"] === "actions") {// Don't add the "Actions" header if the menu has nothing but actions// in it, because then it's redundant (all menus have actions)if (section.group !== "actions" || sections.length > 1) {var sectionHeader = newMenuItem(menu);sectionHeader.text = section["title"];sectionHeader.section = true;menu.addMenuItem(sectionHeader, startNewInstanceItem);}}for (var i = 0; i < section["actions"].length; ++i) {var item = newMenuItem(menu);item.action = section["actions"][i];textMetrics.text = item.action.text.replace("&", "&&");item.action.text = textMetrics.elidedText;menu.addMenuItem(item, startNewInstanceItem);}});// Add Media Player control actionsconst playerData = mpris2Source.playerForLauncherUrl(launcherUrl, get(TaskManager.AbstractTasksModel.AppPid));if (playerData && playerData.canControl && !(get(TaskManager.AbstractTasksModel.WinIdList) !== undefined && get(TaskManager.AbstractTasksModel.WinIdList).length > 1)) {const playing = playerData.playbackStatus === Mpris.PlaybackStatus.Playing;let menuItem = menu.newMenuItem(menu);menuItem.text = i18nc("Play previous track", "Previous Track");menuItem.icon = "media-skip-backward";menuItem.enabled = Qt.binding(() => {return playerData.canGoPrevious;});menuItem.clicked.connect(() => {playerData.Previous();});menu.addMenuItem(menuItem, startNewInstanceItem);menuItem = menu.newMenuItem(menu);// PlasmaCore Menu doesn't actually handle icons or labels changing at runtime...menuItem.text = Qt.binding(() => {// if CanPause, toggle the menu entry between Play & Pause, otherwise always use Playreturn playing && playerData.canPause ? i18nc("Pause playback", "Pause") : i18nc("Start playback", "Play");});menuItem.icon = Qt.binding(() => {return playing && playerData.canPause ? "media-playback-pause" : "media-playback-start";});menuItem.enabled = Qt.binding(() => {return playing ? playerData.canPause : playerData.canPlay;});menuItem.clicked.connect(() => {if (playing) {playerData.Pause();} else {playerData.Play();}});menu.addMenuItem(menuItem, startNewInstanceItem);menuItem = menu.newMenuItem(menu);menuItem.text = i18nc("Play next track", "Next Track");menuItem.icon = "media-skip-forward";menuItem.enabled = Qt.binding(() => {return playerData.canGoNext;});menuItem.clicked.connect(() => {playerData.Next();});menu.addMenuItem(menuItem, startNewInstanceItem);menuItem = menu.newMenuItem(menu);menuItem.text = i18nc("Stop playback", "Stop");menuItem.icon = "media-playback-stop";menuItem.enabled = Qt.binding(() => {return playerData.canStop;});menuItem.clicked.connect(() => {playerData.Stop();});menu.addMenuItem(menuItem, startNewInstanceItem);// Technically media controls and audio streams are separate but for the user they're// semantically related, don't add a separator in between.if (!(menu.visualParent as Task).hasAudioStream) {menu.addMenuItem(newSeparator(menu), startNewInstanceItem);}// If we don't have a window associated with the player but we can quit// it through MPRIS we'll offer a "Quit" option instead of "Close"if (!closeWindowItem.visible && playerData.canQuit) {menuItem = menu.newMenuItem(menu);menuItem.text = i18nc("Quit media player app", "Quit");menuItem.icon = "application-exit";menuItem.visible = Qt.binding(() => {return !closeWindowItem.visible;});menuItem.clicked.connect(() => {playerData.Quit();});menu.addMenuItem(menuItem);}// If we don't have a window associated with the player but we can raise// it through MPRIS we'll offer a "Restore" optionif (get(TaskManager.AbstractTasksModel.IsLauncher) && !startNewInstanceItem.visible && playerData.canRaise) {menuItem = menu.newMenuItem(menu);menuItem.text = i18nc("Open or bring to the front window of media player app", "Restore");menuItem.icon = playerData.iconName;menuItem.visible = Qt.binding(() => {return !startNewInstanceItem.visible;});menuItem.clicked.connect(() => {playerData.Raise();});menu.addMenuItem(menuItem, startNewInstanceItem);}}// We allow mute/unmute whenever an application has a stream, regardless of whether it// is actually playing sound.// This way you can unmute, e.g. a telephony app, even after the conversation has ended,// so you still have it ringing later on.if ((menu.visualParent as Task).hasAudioStream) {const muteItem = menu.newMenuItem(menu);muteItem.checkable = true;muteItem.checked = Qt.binding(() => {return menu.visualParent && menu.visualParent.muted;});muteItem.clicked.connect(() => {menu.visualParent.toggleMuted();});muteItem.text = i18nc("@option:check inmenu, no separate unmute action", "Mute");muteItem.icon = "audio-volume-muted" + (Application.layoutDirection === Qt.RightToLeft ? "-rtl" : "");menu.addMenuItem(muteItem, startNewInstanceItem);menu.addMenuItem(newSeparator(menu), startNewInstanceItem);}}PlasmaExtras.MenuItem {id: startNewInstanceItemvisible: menu.get(TaskManager.AbstractTasksModel.CanLaunchNewInstance)text: i18nc("action:inmenu", "Open New Window")icon: "window-new"onClicked: tasksModel.requestNewInstance(menu.modelIndex)}PlasmaExtras.MenuItem {id: virtualDesktopsMenuItemvisible: virtualDesktopInfo.numberOfDesktops > 1&& (menu.visualParent && !menu.get(TaskManager.AbstractTasksModel.IsLauncher)&& !menu.get(TaskManager.AbstractTasksModel.IsStartup)&& menu.get(TaskManager.AbstractTasksModel.IsVirtualDesktopsChangeable))enabled: visibletext: i18nc("action:inmenu", "Move to &Desktop")icon: "virtual-desktops"readonly property Connections virtualDesktopsMenuConnections: Connections {target: virtualDesktopInfofunction onNumberOfDesktopsChanged(): void {Qt.callLater(virtualDesktopsMenu.refresh);}function onDesktopIdsChanged(): void {Qt.callLater(virtualDesktopsMenu.refresh);}function onDesktopNamesChanged(): void {Qt.callLater(virtualDesktopsMenu.refresh);}}readonly property PlasmaExtras.Menu _virtualDesktopsMenu: PlasmaExtras.Menu {id: virtualDesktopsMenuvisualParent: virtualDesktopsMenuItem.actionfunction refresh(): void {clearMenuItems();if (virtualDesktopInfo.numberOfDesktops <= 1 || !virtualDesktopsMenuItem.enabled) {return;}let menuItem = menu.newMenuItem(virtualDesktopsMenu);menuItem.text = i18nc("action:inmenu", "Move &To Current Desktop");menuItem.enabled = Qt.binding(() => {if (!menu.visualParent) {return false;}let isAnyTaskNotOnCurrentDesktop = false;TaskManagerApplet.TaskTools.foreachChildTask((childIndex) => {const screenGeometry = tasksModel.data(childIndex, TaskManager.AbstractTasksModel.ScreenGeometry);const currentDesktop = virtualDesktopInfo.currentDesktopByScreenGeometry(screenGeometry);isAnyTaskNotOnCurrentDesktop = isAnyTaskNotOnCurrentDesktop || tasksModel.data(childIndex, TaskManager.AbstractTasksModel.VirtualDesktops).indexOf(currentDesktop) === -1;}, menu.modelIndex, tasksModel);return isAnyTaskNotOnCurrentDesktop;});menuItem.clicked.connect(() => {TaskManagerApplet.TaskTools.foreachChildTask((childIndex) => {tasksModel.requestVirtualDesktops(childIndex, [virtualDesktopInfo.currentDesktopByScreenGeometry(tasksModel.data(childIndex, TaskManager.AbstractTasksModel.ScreenGeometry))]);}, menu.modelIndex, tasksModel);});menuItem = menu.newMenuItem(virtualDesktopsMenu);menuItem.text = i18nc("action:inmenu", "&All Desktops");menuItem.checkable = true;menuItem.checked = Qt.binding(() => {return menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsOnAllVirtualDesktops);});menuItem.clicked.connect(() => {tasksModel.requestVirtualDesktops(menu.modelIndex, []);});menu.backend.setActionGroup(menuItem.action);menu.newSeparator(virtualDesktopsMenu);for (let i = 0; i < virtualDesktopInfo.desktopNames.length; ++i) {menuItem = menu.newMenuItem(virtualDesktopsMenu);menuItem.text = virtualDesktopInfo.desktopNames[i];menuItem.checkable = true;menuItem.checked = Qt.binding((i => {return () => menu.visualParent && menu.get(TaskManager.AbstractTasksModel.VirtualDesktops).indexOf(virtualDesktopInfo.desktopIds[i]) > -1;})(i));menuItem.clicked.connect((i => {return () => tasksModel.requestVirtualDesktops(menu.modelIndex, [virtualDesktopInfo.desktopIds[i]]);})(i));menu.backend.setActionGroup(menuItem.action);}menu.newSeparator(virtualDesktopsMenu);menuItem = menu.newMenuItem(virtualDesktopsMenu);menuItem.text = i18nc("action:inmenu", "&New Desktop");menuItem.icon = "list-add";menuItem.clicked.connect(() => {tasksModel.requestNewVirtualDesktop(menu.modelIndex);});}Component.onCompleted: refresh()}}PlasmaExtras.MenuItem {id: activitiesDesktopsMenuItemvisible: activityInfo.numberOfRunningActivities > 1&& (menu.visualParent && !menu.get(TaskManager.AbstractTasksModel.IsLauncher)&& !menu.get(TaskManager.AbstractTasksModel.IsStartup))enabled: visibletext: i18nc("action:inmenu", "Show in &Activities")icon: "activities"readonly property Connections activityInfoConnections: Connections {target: activityInfofunction onNumberOfRunningActivitiesChanged(): void {activitiesDesktopsMenu.refresh()}}readonly property PlasmaExtras.Menu _activitiesDesktopsMenu: PlasmaExtras.Menu {id: activitiesDesktopsMenuvisualParent: activitiesDesktopsMenuItem.actionfunction refresh(): void {clearMenuItems();if (activityInfo.numberOfRunningActivities <= 1) {return;}let menuItem = menu.newMenuItem(activitiesDesktopsMenu);menuItem.text = i18nc("action:inmenu", "Add To Current Activity");menuItem.enabled = Qt.binding(() => {return menu.visualParent && menu.get(TaskManager.AbstractTasksModel.Activities).length > 0 &&menu.get(TaskManager.AbstractTasksModel.Activities).indexOf(activityInfo.currentActivity) < 0;});menuItem.clicked.connect(() => {tasksModel.requestActivities(menu.modelIndex, menu.get(TaskManager.AbstractTasksModel.Activities).concat(activityInfo.currentActivity));});menuItem = menu.newMenuItem(activitiesDesktopsMenu);menuItem.text = i18nc("action:inmenu", "All Activities");menuItem.checkable = true;menuItem.checked = Qt.binding(() => {return menu.visualParent && menu.get(TaskManager.AbstractTasksModel.Activities).length === 0;});menuItem.toggled.connect(checked => {let newActivities = []; // will cast to an empty QStringList i.e all activitiesif (!checked) {newActivities = [activityInfo.currentActivity];}tasksModel.requestActivities(menu.modelIndex, newActivities);});menu.newSeparator(activitiesDesktopsMenu);const runningActivities = activityInfo.runningActivities();for (let i = 0; i < runningActivities.length; ++i) {const activityId = runningActivities[i];menuItem = menu.newMenuItem(activitiesDesktopsMenu);menuItem.text = activityInfo.activityName(runningActivities[i]);menuItem.icon = activityInfo.activityIcon(runningActivities[i]);menuItem.checkable = true;menuItem.checked = Qt.binding((activityId => {return () => menu.visualParent && menu.get(TaskManager.AbstractTasksModel.Activities).indexOf(activityId) >= 0;})(activityId));menuItem.toggled.connect((activityId => {return checked => {let newActivities = menu.get(TaskManager.AbstractTasksModel.Activities);if (checked) {newActivities = newActivities.concat(activityId);} else {const index = newActivities.indexOf(activityId);if (index < 0) {return;}newActivities.splice(index, 1);}return tasksModel.requestActivities(menu.modelIndex, newActivities);};})(activityId));}menu.newSeparator(activitiesDesktopsMenu);for (let i = 0; i < runningActivities.length; ++i) {const activityId = runningActivities[i];const onActivities = menu.get(TaskManager.AbstractTasksModel.Activities);// if the task is on a single activity, don't insert a "move to" item for that activityif (onActivities.length === 1 && onActivities[0] === activityId) {continue;}menuItem = menu.newMenuItem(activitiesDesktopsMenu);menuItem.text = i18nc("action:inmenu", "Move to %1", activityInfo.activityName(activityId))menuItem.icon = activityInfo.activityIcon(activityId)menuItem.clicked.connect((activityId => {return () => tasksModel.requestActivities(menu.modelIndex, [activityId]);})(activityId));}menu.newSeparator(activitiesDesktopsMenu);}Component.onCompleted: refresh()}}PlasmaExtras.MenuItem {id: screensMenuItemvisible: screensInstantiator.count > 1&& (menu.visualParent && !menu.get(TaskManager.AbstractTasksModel.IsLauncher)&& !menu.get(TaskManager.AbstractTasksModel.IsStartup))enabled: visibletext: i18nc("action:inmenu", "Move to &Screen")icon: "computer"readonly property PlasmaCore.ActionGroup _screensActionGroup: PlasmaCore.ActionGroup {id: screensActionGroup}readonly property PlasmaExtras.Menu _screensMenu: PlasmaExtras.Menu {id: screensMenuvisualParent: screensMenuItem.action}readonly property Instantiator _screensInstantiator: Instantiator {id: screensInstantiatormodel: PlasmaCore.ScreensModel {id: screensModel}delegate: PlasmaExtras.MenuItem {id: screenMenuItemrequired property int indexrequired property string namerequired property var screenHandleparent: screensMenuaction: PlasmaCore.Action {text: {const name = screenMenuItem.screenHandle.name;if (name.startsWith("eDP-") || name.startsWith("LVDS-") || name.startsWith("DSI-")) {return i18nc("@item:inmenu List of all Screens to send a window to.", "Built-in Screen");} else {return i18nc("@item:inmenu List of all Screens to send a window to, manufacturer, model (output identifier)","%1 %2 (%3)", screenMenuItem.screenHandle.manufacturer, screenMenuItem.screenHandle.model, name);}}actionGroup: screensActionGroupcheckable: true}// This is not done on the PlasmaCore.Action because it has a "menu" property// which shadows the "menu" id of the ContextMenu.checked: {const currentScreenGeometry = screenMenuItem.screenHandle.geometry;let isAnyTaskNotOnCurrentScreen = false;TaskManagerApplet.TaskTools.foreachChildTask((childIndex) => {const screenGeometry = tasksModel.data(childIndex, TaskManager.AbstractTasksModel.ScreenGeometry);console.log(screenGeometry, currentScreenGeometry);// TODO Expose current screen as QScreen in WindowTasksModel.isAnyTaskNotOnCurrentScreen = isAnyTaskNotOnCurrentScreen ||(screenGeometry.x !== currentScreenGeometry.x|| screenGeometry.y !== currentScreenGeometry.y|| screenGeometry.width !== currentScreenGeometry.width|| screenGeometry.height !== currentScreenGeometry.height);}, menu.modelIndex, tasksModel);return !isAnyTaskNotOnCurrentScreen;}onClicked: {tasksModel.requestSendToOutput(menu.modelIndex, screenMenuItem.screenHandle);}}}}PlasmaExtras.MenuItem {id: launcherToggleActionvisible: menu.visualParent&& !menu.get(TaskManager.AbstractTasksModel.IsLauncher)&& !menu.get(TaskManager.AbstractTasksModel.IsStartup)&& Plasmoid.immutability !== PlasmaCore.Types.SystemImmutable&& (activityInfo.numberOfRunningActivities < 2)&& !doesBelongToCurrentActivity()enabled: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.LauncherUrlWithoutIcon).toString() !== ""text: i18nc("action:inmenu", "&Pin to Task Manager")icon: "window-pin"function doesBelongToCurrentActivity(): bool {return tasksModel.launcherActivities(menu.get(TaskManager.AbstractTasksModel.LauncherUrlWithoutIcon)).some(activity => activity === activityInfo.currentActivity || activity === activityInfo.nullUuid);}onClicked: {tasksModel.requestAddLauncher(menu.get(TaskManager.AbstractTasksModel.LauncherUrl));}}PlasmaExtras.MenuItem {id: showLauncherInActivitiesItemtext: i18nc("action:inmenu", "&Pin to Task Manager")icon: "window-pin"visible: menu.visualParent&& !menu.get(TaskManager.AbstractTasksModel.IsStartup)&& Plasmoid.immutability !== PlasmaCore.Types.SystemImmutable&& (activityInfo.numberOfRunningActivities >= 2)readonly property Connections activitiesLaunchersMenuConnections: Connections {target: activityInfofunction onNumberOfRunningActivitiesChanged(): void {activitiesDesktopsMenu.refresh()}}readonly property PlasmaExtras.Menu _activitiesLaunchersMenu: PlasmaExtras.Menu {id: activitiesLaunchersMenuvisualParent: showLauncherInActivitiesItem.actionfunction refresh(): void {clearMenuItems();if (menu.visualParent === null) return;const createNewItem = (id, title, iconName, url, activities) => {var result = menu.newMenuItem(activitiesLaunchersMenu);result.text = title;result.icon = iconName;result.visible = true;result.checkable = true;result.checked = activities.some(activity => activity === id);result.clicked.connect(() => {if (result.checked) {tasksModel.requestAddLauncherToActivity(url, id);} else {tasksModel.requestRemoveLauncherFromActivity(url, id);}});return result;};if (menu.visualParent === null) return;const url = menu.get(TaskManager.AbstractTasksModel.LauncherUrlWithoutIcon);const activities = tasksModel.launcherActivities(url);createNewItem(activityInfo.nullUuid, i18nc("action:inmenu", "On All Activities"), "", url, activities);if (activityInfo.numberOfRunningActivities <= 1) {return;}createNewItem(activityInfo.currentActivity, i18nc("action:inmenu", "On The Current Activity"), activityInfo.activityIcon(activityInfo.currentActivity), url, activities);menu.newSeparator(activitiesLaunchersMenu);activityInfo.runningActivities().forEach(id => {createNewItem(id, activityInfo.activityName(id), activityInfo.activityIcon(id), url, activities);});}Component.onCompleted: {menu.visualParentChanged.connect(refresh);refresh();}}}PlasmaExtras.MenuItem {visible: (menu.visualParent&& menu.get(TaskManager.AbstractTasksModel.IsStartup) !== true&& Plasmoid.immutability !== PlasmaCore.Types.SystemImmutable&& !launcherToggleAction.visible&& activityInfo.numberOfRunningActivities < 2)text: i18nc("action:inmenu", "Unpin from Task Manager")icon: "window-unpin"onClicked: {tasksModel.requestRemoveLauncher(menu.get(TaskManager.AbstractTasksModel.LauncherUrlWithoutIcon));}}PlasmaExtras.MenuItem {id: moreActionsMenuItemvisible: (menu.visualParent && !menu.get(TaskManager.AbstractTasksModel.IsLauncher) && !menu.get(TaskManager.AbstractTasksModel.IsStartup))enabled: visibletext: i18nc("item:inmenu opens submenu", "More")icon: "view-more-symbolic"readonly property PlasmaExtras.Menu moreMenu: PlasmaExtras.Menu {visualParent: moreActionsMenuItem.actionPlasmaExtras.MenuItem {enabled: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsMovable)text: i18nc("action:inmenu", "&Move")icon: "transform-move"onClicked: tasksModel.requestMove(menu.modelIndex)}PlasmaExtras.MenuItem {enabled: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsResizable)text: i18nc("action:inmenu", "Re&size")icon: "transform-scale"onClicked: tasksModel.requestResize(menu.modelIndex)}PlasmaExtras.MenuItem {visible: (menu.visualParent && !menu.get(TaskManager.AbstractTasksModel.IsLauncher) && !menu.get(TaskManager.AbstractTasksModel.IsStartup))enabled: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsMaximizable)checkable: truechecked: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsMaximized)text: i18nc("action:inmenu", "Ma&ximize")icon: "window-maximize"onClicked: tasksModel.requestToggleMaximized(menu.modelIndex)}PlasmaExtras.MenuItem {visible: (menu.visualParent && !menu.get(TaskManager.AbstractTasksModel.IsLauncher) && !menu.get(TaskManager.AbstractTasksModel.IsStartup))enabled: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsMinimizable)checkable: truechecked: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsMinimized)text: i18nc("action:inmenu", "Mi&nimize")icon: "window-minimize"onClicked: tasksModel.requestToggleMinimized(menu.modelIndex)}PlasmaExtras.MenuItem {checkable: truechecked: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsKeepAbove)text: i18nc("action:inmenu", "Keep &Above Others")icon: "window-keep-above"onClicked: tasksModel.requestToggleKeepAbove(menu.modelIndex)}PlasmaExtras.MenuItem {checkable: truechecked: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsKeepBelow)text: i18nc("action:inmenu", "Keep &Below Others")icon: "window-keep-below"onClicked: tasksModel.requestToggleKeepBelow(menu.modelIndex)}PlasmaExtras.MenuItem {enabled: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsFullScreenable)checkable: truechecked: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsFullScreen)text: i18nc("action:inmenu", "&Fullscreen")icon: "view-fullscreen"onClicked: tasksModel.requestToggleFullScreen(menu.modelIndex)}PlasmaExtras.MenuItem {enabled: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.CanSetNoBoder)checkable: truechecked: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.HasNoBorder)text: i18nc("@action:inmenu", "&No Titlebar and Frame")icon: "edit-none-border"onClicked: tasksModel.requestToggleNoBorder(menu.modelIndex)}PlasmaExtras.MenuItem {enabled: menu.visualParentcheckable: truechecked: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsExcludedFromCapture)visible: Qt.platform.pluginName === "wayland"text: i18nc("@action:inmenu", "&Hide from Screencast")icon: "view-private"onClicked: tasksModel.requestToggleExcludeFromCapture(menu.modelIndex)}PlasmaExtras.MenuItem {separator: true}PlasmaExtras.MenuItem {visible: (Plasmoid.configuration.groupingStrategy !== 0) && menu.get(TaskManager.AbstractTasksModel.IsWindow)checkable: truechecked: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsGroupable)text: i18nc("@option:check inmenu", "Allow this program to be grouped")icon: "view-group"onClicked: tasksModel.requestToggleGrouping(menu.modelIndex)}}}PlasmaExtras.MenuItem { separator: true }PlasmaExtras.MenuItem {property PlasmaCore.Action configureAction: nullenabled: configureAction && configureAction.enabledvisible: configureAction && configureAction.visibletext: configureAction ? configureAction.text : ""icon: configureAction ? configureAction.icon : ""onClicked: configureAction.trigger()Component.onCompleted: configureAction = Plasmoid.internalAction("configure")}PlasmaExtras.MenuItem {property PlasmaCore.Action editModeAction: nullenabled: editModeAction && editModeAction.enabledvisible: editModeAction && editModeAction.visibletext: editModeAction ? editModeAction.text : ""icon: editModeAction ? editModeAction.icon : ""onClicked: editModeAction.trigger()Component.onCompleted: editModeAction = Plasmoid.containment.internalAction("configure")}PlasmaExtras.MenuItem { separator: true }PlasmaExtras.MenuItem {id: closeWindowItemvisible: (menu.visualParent && !menu.get(TaskManager.AbstractTasksModel.IsLauncher) && !menu.get(TaskManager.AbstractTasksModel.IsStartup))enabled: menu.visualParent && menu.get(TaskManager.AbstractTasksModel.IsClosable)text: menu.get(TaskManager.AbstractTasksModel.IsGroupParent) ? i18nc("@action:inmenu", "&Close All") : i18nc("@action:inmenu", "&Close")icon: "window-close"onClicked: {if (tasks.groupDialog !== null && tasks.groupDialog.visualParent === menu.visualParent) {tasks.groupDialog.visible = false;}tasksModel.requestClose(menu.modelIndex);}}}