mobileshell: Manually specify QML files, and private some internal files

The globbing pattern for finding QML files is problematic because it
breaks when we add/delete a file (requiring us to delete
~/kde/build/plasma-mobile). It also placed every file (both public and
internal files) in the same flat namespace, carrying the risk of name
collisions between unrelated folders.

This commit manually specifies every file in the package. It also moves internal files in the actiondrawer folder into its own namespace. Followup MRs will do this process for other folders.
This commit is contained in:
Devin Lin 2025-07-17 01:42:35 -04:00
parent 62a2ddc5e7
commit bc3e80c479
15 changed files with 128 additions and 127 deletions

View file

@ -33,12 +33,111 @@ set_source_files_properties(
QT_QML_SINGLETON_TYPE TRUE QT_QML_SINGLETON_TYPE TRUE
) )
# Include qml and js files within ./qml/ # QML files meant to be used publicly
file(GLOB_RECURSE _qml_sources # TODO: move files gradually out of main namespace into sub namespaces
"qml/*.qml" ecm_target_qml_sources(mobileshellplugin SOURCES
"qml/*.js" qml/actiondrawer/ActionDrawer.qml
qml/actiondrawer/ActionDrawerOpenSurface.qml
qml/actiondrawer/ActionDrawerWindow.qml
qml/components/AppLaunch.qml
qml/components/BaseItem.qml
qml/components/Constants.qml
qml/components/Flickable.qml
qml/components/FlickableOpacityGradient.qml
qml/components/GridView.qml
qml/components/HapticsEffect.qml
qml/components/ListView.qml
qml/components/MarqueeLabel.qml
qml/components/PanelBackground.qml
qml/components/ScreenEdgeDragEffect.qml
qml/components/StartupFeedbackPanelFill.qml
qml/components/StartupFeedbackWindows.qml
qml/components/TextDropShadow.qml
qml/components/VelocityCalculator.qml
qml/dataproviders/AudioInfo.qml
qml/dataproviders/BatteryInfo.qml
qml/dataproviders/BluetoothInfo.qml
qml/dataproviders/NetworkInfo.qml
qml/dataproviders/SignalStrengthInfo.qml
qml/homescreen/BlurEffect.qml
qml/homescreen/DeviceLock.qml
qml/homescreen/HomeScreen.qml
qml/homescreen/WallpaperSelector.qml
qml/navigationpanel/NavigationPanel.qml
qml/navigationpanel/NavigationPanelAction.qml
qml/navigationpanel/NavigationPanelButton.qml
qml/popups/actionbuttons/ActionButton.qml
qml/popups/actionbuttons/ActionButtonsProvider.qml
qml/popups/actionbuttons/RotationButton.qml
qml/popups/notifications/NotificationPopup.qml
qml/popups/notifications/NotificationPopupManager.qml
qml/popups/notifications/NotificationPopupProvider.qml
qml/popups/notifications/PulseAudio.qml
qml/popups/volumeosd/AudioApplet.qml
qml/popups/volumeosd/DeviceListItem.qml
qml/popups/volumeosd/icon.js
qml/popups/volumeosd/ListItemBase.qml
qml/popups/volumeosd/PopupCard.qml
qml/popups/volumeosd/StreamListItem.qml
qml/popups/volumeosd/VolumeChangedPopup.qml
qml/popups/volumeosd/VolumeOSD.qml
qml/popups/volumeosd/VolumeOSDProvider.qml
qml/popups/PopupProviderLoader.qml
qml/statusbar/indicators/BatteryIndicator.qml
qml/statusbar/indicators/BluetoothIndicator.qml
qml/statusbar/indicators/InternetIndicator.qml
qml/statusbar/indicators/SignalStrengthIndicator.qml
qml/statusbar/indicators/VolumeIndicator.qml
qml/statusbar/ClockText.qml
qml/statusbar/StatusBar.qml
qml/statusbar/TaskWidget.qml
qml/widgets/krunner/KRunnerScreen.qml
qml/widgets/mediacontrols/BlurredBackground.qml
qml/widgets/mediacontrols/MediaControlsSource.qml
qml/widgets/mediacontrols/MediaControlsWidget.qml
qml/widgets/notifications/BaseNotificationItem.qml
qml/widgets/notifications/NotificationBodyLabel.qml
qml/widgets/notifications/NotificationCard.qml
qml/widgets/notifications/NotificationEditContextMenu.qml
qml/widgets/notifications/NotificationFooterActions.qml
qml/widgets/notifications/NotificationGroupHeader.qml
qml/widgets/notifications/NotificationItem.qml
qml/widgets/notifications/NotificationJobDetails.qml
qml/widgets/notifications/NotificationJobItem.qml
qml/widgets/notifications/NotificationPopupItem.qml
qml/widgets/notifications/NotificationReplyField.qml
qml/widgets/notifications/NotificationsModelType.qml
qml/widgets/notifications/NotificationsUtils.js
qml/widgets/notifications/NotificationsWidget.qml
qml/widgets/notifications/NotificationTimeText.qml
qml/widgets/notifications/ThumbnailStrip.qml
)
# Other supporting QML files
ecm_target_qml_sources(mobileshellplugin SOURCES
qml/actiondrawer/private/BrightnessItem.qml
qml/actiondrawer/private/Handle.qml
qml/actiondrawer/private/QuickSettings.qml
qml/actiondrawer/private/QuickSettingsDelegate.qml
qml/actiondrawer/private/QuickSettingsDrawer.qml
qml/actiondrawer/private/QuickSettingsFullDelegate.qml
qml/actiondrawer/private/QuickSettingsMinimizedDelegate.qml
qml/actiondrawer/private/QuickSettingsPanel.qml
qml/actiondrawer/private/ContentContainer.qml
qml/actiondrawer/private/LandscapeContentContainer.qml
qml/actiondrawer/private/NotificationDrawer.qml
qml/actiondrawer/private/PortraitContentContainer.qml
PATH actiondrawer/private
) )
ecm_target_qml_sources(mobileshellplugin SOURCES ${_qml_sources})
target_link_libraries(mobileshellplugin target_link_libraries(mobileshellplugin

View file

@ -12,9 +12,11 @@ import QtQuick.Window 2.2
import org.kde.plasma.components 3.0 as PlasmaComponents import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.private.nanoshell 2.0 as NanoShell import org.kde.plasma.private.nanoshell 2.0 as NanoShell
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.plasma.private.mobileshell.quicksettingsplugin as QS import org.kde.plasma.private.mobileshell.quicksettingsplugin as QS
import org.kde.plasma.private.mobileshell as MobileShell
import 'actiondrawer/private'
Item { Item {
id: root id: root
@ -96,7 +98,7 @@ Item {
/** /**
* The mode of the action drawer (portrait or landscape). * The mode of the action drawer (portrait or landscape).
*/ */
property int mode: (height > width && width <= largePortraitThreshold) ? ActionDrawer.Portrait : ActionDrawer.Landscape property int mode: (height > width && width <= largePortraitThreshold) ? MobileShell.ActionDrawer.Portrait : MobileShell.ActionDrawer.Landscape
/** /**
* At some point, even if the screen is technically portrait, if we have a ton of width it'd be best to just show the landscape mode. * At some point, even if the screen is technically portrait, if we have a ton of width it'd be best to just show the landscape mode.

View file

@ -83,14 +83,14 @@ Item {
// Proxy in the layout that switches between landscape and portrait mode. // Proxy in the layout that switches between landscape and portrait mode.
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
visible: root.actionDrawer.mode != ActionDrawer.Portrait visible: root.actionDrawer.mode != MobileShell.ActionDrawer.Portrait
LayoutItemProxy { target: contentContainerLoader } LayoutItemProxy { target: contentContainerLoader }
} }
// Mouse area for dismissing action drawer in portrait mode when background is clicked. // Mouse area for dismissing action drawer in portrait mode when background is clicked.
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
visible: root.actionDrawer.mode == ActionDrawer.Portrait visible: root.actionDrawer.mode == MobileShell.ActionDrawer.Portrait
// dismiss drawer when background is clicked // dismiss drawer when background is clicked
onClicked: root.actionDrawer.close(); onClicked: root.actionDrawer.close();
@ -106,8 +106,8 @@ Item {
anchors { anchors {
topMargin: notificationDrawer.height + 1 topMargin: notificationDrawer.height + 1
leftMargin: actionDrawer.mode == ActionDrawer.Portrait ? 0 : 10 leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : 10
rightMargin: actionDrawer.mode == ActionDrawer.Portrait ? 0 : notificationDrawer.notificationWidget.anchors.rightMargin + Kirigami.Units.gridUnit - notificationDrawer.anchors.leftMargin + 370 rightMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : notificationDrawer.notificationWidget.anchors.rightMargin + Kirigami.Units.gridUnit - notificationDrawer.anchors.leftMargin + 370
top: parent.top top: parent.top
left: parent.left left: parent.left
right: parent.right right: parent.right
@ -170,8 +170,8 @@ Item {
top: parent.top top: parent.top
left: parent.left left: parent.left
right: parent.right right: parent.right
rightMargin: root.actionDrawer.mode == ActionDrawer.Portrait ? 0 : 360 rightMargin: root.actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : 360
leftMargin: actionDrawer.mode == ActionDrawer.Portrait ? 0 : notificationDrawer.minWidthHeight * 0.06 leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : notificationDrawer.minWidthHeight * 0.06
} }
} }
@ -185,8 +185,8 @@ Item {
left: parent.left left: parent.left
right: parent.right right: parent.right
} }
height: root.actionDrawer.mode === ActionDrawer.Portrait ? actionDrawer.offsetResistance : root.height height: root.actionDrawer.mode === MobileShell.ActionDrawer.Portrait ? actionDrawer.offsetResistance : root.height
interactive: root.actionDrawer.mode === ActionDrawer.Portrait interactive: root.actionDrawer.mode === MobileShell.ActionDrawer.Portrait
onSwipeStarted: root.startSwipe() onSwipeStarted: root.startSwipe()
onSwipeEnded: root.endSwipe() onSwipeEnded: root.endSwipe()
@ -199,7 +199,7 @@ Item {
// Proxy in the layout that switches between landscape and portrait mode. // Proxy in the layout that switches between landscape and portrait mode.
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
visible: root.actionDrawer.mode == ActionDrawer.Portrait visible: root.actionDrawer.mode == MobileShell.ActionDrawer.Portrait
LayoutItemProxy { target: contentContainerLoader } LayoutItemProxy { target: contentContainerLoader }
} }
} }
@ -219,7 +219,7 @@ Item {
readonly property real minimizedToFullProgress: root.actionDrawer.openToPinnedMode ? (root.actionDrawer.opened ? applyMinMax(offsetDist / totalOffsetDist) : 0) : 1 readonly property real minimizedToFullProgress: root.actionDrawer.openToPinnedMode ? (root.actionDrawer.opened ? applyMinMax(offsetDist / totalOffsetDist) : 0) : 1
asynchronous: true asynchronous: true
sourceComponent: root.actionDrawer.mode == ActionDrawer.Portrait ? portraitContentContainer : landscapeContentContainer sourceComponent: root.actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? portraitContentContainer : landscapeContentContainer
} }
// The portrait content container. // The portrait content container.
@ -252,11 +252,11 @@ Item {
// Components shared between the two layouts. // Components shared between the two layouts.
// This allows us to avoid having to reload the components every time the screen size changes. // This allows us to avoid having to reload the components every time the screen size changes.
property MobileShell.QuickSettings quickSettings: MobileShell.QuickSettings { property QuickSettings quickSettings: QuickSettings {
id: quickSettings id: quickSettings
actionDrawer: root.actionDrawer actionDrawer: root.actionDrawer
quickSettingsModel: root.quickSettingsModel quickSettingsModel: root.quickSettingsModel
fullViewProgress: (root.actionDrawer.mode == ActionDrawer.Portrait) ? contentContainerLoader.minimizedToFullProgress : 1.0 fullViewProgress: (root.actionDrawer.mode == MobileShell.ActionDrawer.Portrait) ? contentContainerLoader.minimizedToFullProgress : 1.0
} }
property MobileShell.StatusBar statusBar: MobileShell.StatusBar { property MobileShell.StatusBar statusBar: MobileShell.StatusBar {
@ -265,9 +265,9 @@ Item {
Kirigami.Theme.inherit: false Kirigami.Theme.inherit: false
backgroundColor: "transparent" backgroundColor: "transparent"
showSecondRow: root.actionDrawer.mode == ActionDrawer.Portrait showSecondRow: root.actionDrawer.mode == MobileShell.ActionDrawer.Portrait
showDropShadow: false showDropShadow: false
showTime: root.actionDrawer.mode == ActionDrawer.Portrait showTime: root.actionDrawer.mode == MobileShell.ActionDrawer.Portrait
// security reasons, system tray also doesn't work on lockscreen // security reasons, system tray also doesn't work on lockscreen
disableSystemTray: root.actionDrawer.restrictedPermissions disableSystemTray: root.actionDrawer.restrictedPermissions

View file

@ -24,8 +24,8 @@ Item {
property alias notificationWidget: notificationWidget property alias notificationWidget: notificationWidget
property real contentY: notificationWidget.listView.contentY property real contentY: notificationWidget.listView.contentY
property real topPadding: actionDrawer.mode == ActionDrawer.Portrait ? Kirigami.Units.largeSpacing : date.y + date.height + Kirigami.Units.smallSpacing * 6 property real topPadding: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? Kirigami.Units.largeSpacing : date.y + date.height + Kirigami.Units.smallSpacing * 6
property real topMargin: actionDrawer.mode == ActionDrawer.Portrait ? actionDrawer.offsetResistance + 1 : 0 property real topMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? actionDrawer.offsetResistance + 1 : 0
readonly property real minWidthHeight: Math.min(actionDrawer.width, actionDrawer.height) readonly property real minWidthHeight: Math.min(actionDrawer.width, actionDrawer.height)
readonly property bool hasNotifications: notificationWidget.hasNotifications readonly property bool hasNotifications: notificationWidget.hasNotifications
@ -54,8 +54,8 @@ Item {
id: notificationWidget id: notificationWidget
anchors.fill: parent anchors.fill: parent
anchors.topMargin: root.topMargin anchors.topMargin: root.topMargin
anchors.rightMargin: actionDrawer.mode == ActionDrawer.Portrait ? 0 : Math.max(root.width - Kirigami.Units.gridUnit * 25, 0) anchors.rightMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : Math.max(root.width - Kirigami.Units.gridUnit * 25, 0)
anchors.leftMargin: actionDrawer.mode == ActionDrawer.Portrait ? 0 : -Kirigami.Units.gridUnit anchors.leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : -Kirigami.Units.gridUnit
historyModel: actionDrawer.notificationModel historyModel: actionDrawer.notificationModel
historyModelType: actionDrawer.notificationModelType historyModelType: actionDrawer.notificationModelType
@ -63,7 +63,7 @@ Item {
actionsRequireUnlock: actionDrawer.restrictedPermissions actionsRequireUnlock: actionDrawer.restrictedPermissions
onUnlockRequested: actionDrawer.permissionsRequested() onUnlockRequested: actionDrawer.permissionsRequested()
topPadding: root.topPadding topPadding: root.topPadding
showHeader: actionDrawer.mode != ActionDrawer.Portrait showHeader: actionDrawer.mode != MobileShell.ActionDrawer.Portrait
listView.interactive: !actionDrawer.dragging && root.listOverflowing listView.interactive: !actionDrawer.dragging && root.listOverflowing
Connections { Connections {
@ -158,7 +158,7 @@ Item {
Item { Item {
id: landscapeModeHeader id: landscapeModeHeader
anchors.fill: parent anchors.fill: parent
visible: actionDrawer.mode != ActionDrawer.Portrait visible: actionDrawer.mode != MobileShell.ActionDrawer.Portrait
transform: [ transform: [
Translate { Translate {

View file

@ -1,100 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023 Yari Polla <skilvingr@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick
import QtQuick.Layouts
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.private.nanoshell as NanoShell
import org.kde.kirigami as Kirigami
/*
* A context popup menu closable by tapping outside it.
* Being it a FullScreenOverlay, no event is delivered to underlying components until it's closed.
*
* - property relatedTo: Item to which the popup is related; the popup will spawn either above or below it, depending on its y value.
* If no item is supplied, the popup will spawn at the center of the screen.
* - property title: The title for the menu.
* - property menuActions: The menu will be composed of these actions.
* - function showOverlay(): Spawns the popup.
*/
NanoShell.FullScreenOverlay {
id: overlay
visible: false
color: "transparent"
property point mappedGlobalCoordinates
property Item relatedTo: null
property string title
property list<Kirigami.Action> menuActions
function showOverlay() {
if (!overlay.visible) {
overlay.visible = true;
menu.open();
}
}
Item {
id: containerItem
height: menu.implicitHeight
width: menu.implicitWidth
readonly property point coordinates: {
if (relatedTo) { // Place next to Item
return mapFromGlobal(mappedGlobalCoordinates.x, mappedGlobalCoordinates.y);
} else { // Place at the center of the screen
return Qt.point((overlay.width - width) / 2, (overlay.height - height) / 2);
}
}
x: coordinates.x
y: coordinates.y
transform: Translate {
x: 0
y: (containerItem.coordinates.y <= overlay.height/2 ? relatedTo.height : -containerItem.height) - Constants.topPanelHeight
}
PlasmaComponents.Menu {
id: menu
title: overlay.title
closePolicy: PlasmaComponents.Menu.CloseOnReleaseOutside | PlasmaComponents.Menu.CloseOnEscape
onClosed: overlay.close()
Component.onCompleted: {
for (var i = 0; i < menuActions.length; i++) {
appendItem(menuActions[i]);
}
}
function appendItem(button) {
menu.addItem(menuItem.createObject(
menu,
{
iconName: button.iconName,
text: i18n(button.text),
callback: button.triggered
}));
}
Component {
id: menuItem
PlasmaComponents.MenuItem {
property string iconName: ""
property var callback: () => {}
icon.name: iconName
onClicked: callback()
}
}
}
}
}