From 81a4d3b4e0dae463bf69ea8c4dc53420f5cee353 Mon Sep 17 00:00:00 2001 From: purian23 Date: Sat, 4 Jul 2026 16:10:56 -0400 Subject: [PATCH] feat(Notepad): add notepad desktop entry & IPC commands file handling --- Makefile | 2 ++ assets/com.danklinux.dms.notepad.desktop | 11 +++++++++ distro/debian/dms-git/debian/rules | 1 + distro/debian/dms/debian/rules | 1 + distro/fedora/dms-git.spec | 2 ++ distro/fedora/dms.spec | 2 ++ distro/opensuse/dms-git.spec | 2 ++ distro/opensuse/dms.spec | 2 ++ distro/ubuntu/dms-git/debian/rules | 2 ++ distro/ubuntu/dms/debian/rules | 2 ++ distro/void/srcpkgs/dms-git/template | 1 + distro/void/srcpkgs/dms/template | 1 + docs/IPC.md | 4 ++++ flake.nix | 2 ++ quickshell/DMSShellIPC.qml | 16 +++++++++++++ .../Modals/DankLauncherV2/Controller.qml | 4 ++++ quickshell/Modules/Notepad/Notepad.qml | 19 +++++++++++++++ .../Modules/Notepad/NotepadPopoutWindow.qml | 1 + .../Modules/Settings/DefaultAppsTab.qml | 2 +- quickshell/Services/AppSearchService.qml | 10 ++++++++ quickshell/Services/NotepadStorageService.qml | 23 +++++++++++++++++++ quickshell/Services/PopoutService.qml | 18 +++++++++++++++ quickshell/Widgets/DankSlideout.qml | 2 ++ 23 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 assets/com.danklinux.dms.notepad.desktop diff --git a/Makefile b/Makefile index b166680f3..fa2d4f042 100644 --- a/Makefile +++ b/Makefile @@ -77,6 +77,7 @@ install-desktop: @echo "Installing desktop entries..." @install -D -m 644 $(ASSETS_DIR)/dms-open.desktop $(APPLICATIONS_DIR)/dms-open.desktop @install -D -m 644 $(ASSETS_DIR)/com.danklinux.dms.desktop $(APPLICATIONS_DIR)/com.danklinux.dms.desktop + @install -D -m 644 $(ASSETS_DIR)/com.danklinux.dms.notepad.desktop $(APPLICATIONS_DIR)/com.danklinux.dms.notepad.desktop @update-desktop-database -q $(APPLICATIONS_DIR) 2>/dev/null || true @echo "Desktop entries installed" @@ -120,6 +121,7 @@ uninstall-desktop: @echo "Removing desktop entries..." @rm -f $(APPLICATIONS_DIR)/dms-open.desktop @rm -f $(APPLICATIONS_DIR)/com.danklinux.dms.desktop + @rm -f $(APPLICATIONS_DIR)/com.danklinux.dms.notepad.desktop @update-desktop-database -q $(APPLICATIONS_DIR) 2>/dev/null || true @echo "Desktop entries removed" diff --git a/assets/com.danklinux.dms.notepad.desktop b/assets/com.danklinux.dms.notepad.desktop new file mode 100644 index 000000000..63ed258a4 --- /dev/null +++ b/assets/com.danklinux.dms.notepad.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Name=DMS Notepad +GenericName=Text Editor +Comment=Quick notes and text files in the dank desktop shell +Exec=dms ipc call notepad openFile %f +Icon=danklogo +Terminal=false +Categories=Utility;TextEditor; +MimeType=text/plain;text/markdown; +StartupNotify=false diff --git a/distro/debian/dms-git/debian/rules b/distro/debian/dms-git/debian/rules index 8b5a16fcd..0ca79f87b 100755 --- a/distro/debian/dms-git/debian/rules +++ b/distro/debian/dms-git/debian/rules @@ -74,6 +74,7 @@ override_dh_auto_install: install -Dm644 assets/systemd/dms.service debian/dms-git/usr/lib/systemd/user/dms.service; \ install -Dm644 assets/dms-open.desktop debian/dms-git/usr/share/applications/dms-open.desktop; \ install -Dm644 assets/com.danklinux.dms.desktop debian/dms-git/usr/share/applications/com.danklinux.dms.desktop; \ + install -Dm644 assets/com.danklinux.dms.notepad.desktop debian/dms-git/usr/share/applications/com.danklinux.dms.notepad.desktop; \ install -Dm644 assets/danklogo.svg debian/dms-git/usr/share/icons/hicolor/scalable/apps/danklogo.svg; \ else \ echo "ERROR: quickshell directory not found!" && \ diff --git a/distro/debian/dms/debian/rules b/distro/debian/dms/debian/rules index b1a1b5cb6..ad0abdc48 100755 --- a/distro/debian/dms/debian/rules +++ b/distro/debian/dms/debian/rules @@ -67,6 +67,7 @@ override_dh_auto_install: install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/assets/systemd/dms.service debian/dms/usr/lib/systemd/user/dms.service; \ install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/assets/dms-open.desktop debian/dms/usr/share/applications/dms-open.desktop; \ install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/assets/com.danklinux.dms.desktop debian/dms/usr/share/applications/com.danklinux.dms.desktop; \ + install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/assets/com.danklinux.dms.notepad.desktop debian/dms/usr/share/applications/com.danklinux.dms.notepad.desktop; \ install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/assets/danklogo.svg debian/dms/usr/share/icons/hicolor/scalable/apps/danklogo.svg; \ else \ echo "ERROR: DankMaterialShell-$(UPSTREAM_VERSION) directory not found!" && \ diff --git a/distro/fedora/dms-git.spec b/distro/fedora/dms-git.spec index a5d9d43eb..841747303 100644 --- a/distro/fedora/dms-git.spec +++ b/distro/fedora/dms-git.spec @@ -122,6 +122,7 @@ install -Dm644 assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.servic install -Dm644 assets/dms-open.desktop %{buildroot}%{_datadir}/applications/dms-open.desktop install -Dm644 assets/com.danklinux.dms.desktop %{buildroot}%{_datadir}/applications/com.danklinux.dms.desktop +install -Dm644 assets/com.danklinux.dms.notepad.desktop %{buildroot}%{_datadir}/applications/com.danklinux.dms.notepad.desktop install -Dm644 assets/danklogo.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg # Install shell files to shared data location @@ -146,6 +147,7 @@ pkill -USR1 -x dms >/dev/null 2>&1 || : %{_userunitdir}/dms.service %{_datadir}/applications/dms-open.desktop %{_datadir}/applications/com.danklinux.dms.desktop +%{_datadir}/applications/com.danklinux.dms.notepad.desktop %{_datadir}/icons/hicolor/scalable/apps/danklogo.svg %files -n dms-cli diff --git a/distro/fedora/dms.spec b/distro/fedora/dms.spec index 20d547f88..807065894 100644 --- a/distro/fedora/dms.spec +++ b/distro/fedora/dms.spec @@ -90,6 +90,7 @@ install -Dm644 %{_builddir}/dms-qml/assets/systemd/dms.service %{buildroot}%{_us install -Dm644 %{_builddir}/dms-qml/assets/dms-open.desktop %{buildroot}%{_datadir}/applications/dms-open.desktop install -Dm644 %{_builddir}/dms-qml/assets/com.danklinux.dms.desktop %{buildroot}%{_datadir}/applications/com.danklinux.dms.desktop +install -Dm644 %{_builddir}/dms-qml/assets/com.danklinux.dms.notepad.desktop %{buildroot}%{_datadir}/applications/com.danklinux.dms.notepad.desktop install -Dm644 %{_builddir}/dms-qml/assets/danklogo.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg install -dm755 %{buildroot}%{_datadir}/quickshell/dms @@ -113,6 +114,7 @@ pkill -USR1 -x dms >/dev/null 2>&1 || : %{_userunitdir}/dms.service %{_datadir}/applications/dms-open.desktop %{_datadir}/applications/com.danklinux.dms.desktop +%{_datadir}/applications/com.danklinux.dms.notepad.desktop %{_datadir}/icons/hicolor/scalable/apps/danklogo.svg %files -n dms-cli diff --git a/distro/opensuse/dms-git.spec b/distro/opensuse/dms-git.spec index b813257d7..fd5766800 100644 --- a/distro/opensuse/dms-git.spec +++ b/distro/opensuse/dms-git.spec @@ -117,6 +117,7 @@ install -Dm644 assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.servic install -Dm644 assets/dms-open.desktop %{buildroot}%{_datadir}/applications/dms-open.desktop install -Dm644 assets/com.danklinux.dms.desktop %{buildroot}%{_datadir}/applications/com.danklinux.dms.desktop +install -Dm644 assets/com.danklinux.dms.notepad.desktop %{buildroot}%{_datadir}/applications/com.danklinux.dms.notepad.desktop install -Dm644 assets/danklogo.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg install -dm755 %{buildroot}%{_datadir}/quickshell/dms @@ -153,6 +154,7 @@ pkill -USR1 -x dms >/dev/null 2>&1 || : %{_userunitdir}/dms.service %{_datadir}/applications/dms-open.desktop %{_datadir}/applications/com.danklinux.dms.desktop +%{_datadir}/applications/com.danklinux.dms.notepad.desktop %dir %{_datadir}/icons/hicolor %dir %{_datadir}/icons/hicolor/scalable %dir %{_datadir}/icons/hicolor/scalable/apps diff --git a/distro/opensuse/dms.spec b/distro/opensuse/dms.spec index 224dc9fb1..5be054cb1 100644 --- a/distro/opensuse/dms.spec +++ b/distro/opensuse/dms.spec @@ -66,6 +66,7 @@ install -Dm644 assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.servic install -Dm644 assets/dms-open.desktop %{buildroot}%{_datadir}/applications/dms-open.desktop install -Dm644 assets/com.danklinux.dms.desktop %{buildroot}%{_datadir}/applications/com.danklinux.dms.desktop +install -Dm644 assets/com.danklinux.dms.notepad.desktop %{buildroot}%{_datadir}/applications/com.danklinux.dms.notepad.desktop install -Dm644 assets/danklogo.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg install -dm755 %{buildroot}%{_datadir}/quickshell/dms @@ -100,6 +101,7 @@ pkill -USR1 -x dms >/dev/null 2>&1 || : %{_userunitdir}/dms.service %{_datadir}/applications/dms-open.desktop %{_datadir}/applications/com.danklinux.dms.desktop +%{_datadir}/applications/com.danklinux.dms.notepad.desktop %dir %{_datadir}/icons/hicolor %dir %{_datadir}/icons/hicolor/scalable %dir %{_datadir}/icons/hicolor/scalable/apps diff --git a/distro/ubuntu/dms-git/debian/rules b/distro/ubuntu/dms-git/debian/rules index b2713e5ec..92e19c8df 100755 --- a/distro/ubuntu/dms-git/debian/rules +++ b/distro/ubuntu/dms-git/debian/rules @@ -75,6 +75,8 @@ override_dh_auto_install: debian/dms-git/usr/share/applications/dms-open.desktop install -Dm644 dms-git-repo/assets/com.danklinux.dms.desktop \ debian/dms-git/usr/share/applications/com.danklinux.dms.desktop + install -Dm644 dms-git-repo/assets/com.danklinux.dms.notepad.desktop \ + debian/dms-git/usr/share/applications/com.danklinux.dms.notepad.desktop install -Dm644 dms-git-repo/assets/danklogo.svg \ debian/dms-git/usr/share/icons/hicolor/scalable/apps/danklogo.svg diff --git a/distro/ubuntu/dms/debian/rules b/distro/ubuntu/dms/debian/rules index 6558e2302..a01280acc 100755 --- a/distro/ubuntu/dms/debian/rules +++ b/distro/ubuntu/dms/debian/rules @@ -56,6 +56,8 @@ override_dh_auto_install: debian/dms/usr/share/applications/dms-open.desktop install -Dm644 DankMaterialShell-$(BASE_VERSION)/assets/com.danklinux.dms.desktop \ debian/dms/usr/share/applications/com.danklinux.dms.desktop + install -Dm644 DankMaterialShell-$(BASE_VERSION)/assets/com.danklinux.dms.notepad.desktop \ + debian/dms/usr/share/applications/com.danklinux.dms.notepad.desktop install -Dm644 DankMaterialShell-$(BASE_VERSION)/assets/danklogo.svg \ debian/dms/usr/share/icons/hicolor/scalable/apps/danklogo.svg diff --git a/distro/void/srcpkgs/dms-git/template b/distro/void/srcpkgs/dms-git/template index 0afacaaf6..fe1f4cc4e 100644 --- a/distro/void/srcpkgs/dms-git/template +++ b/distro/void/srcpkgs/dms-git/template @@ -43,6 +43,7 @@ post_install() { # Desktop entry + icon vinstall "${wrksrc}/assets/dms-open.desktop" 644 usr/share/applications vinstall "${wrksrc}/assets/com.danklinux.dms.desktop" 644 usr/share/applications + vinstall "${wrksrc}/assets/com.danklinux.dms.notepad.desktop" 644 usr/share/applications vinstall "${wrksrc}/assets/danklogo.svg" 644 usr/share/icons/hicolor/scalable/apps # Shell completions (generated by the built binary; skip when cross-building) diff --git a/distro/void/srcpkgs/dms/template b/distro/void/srcpkgs/dms/template index 7cd62cec0..dbcfd891a 100644 --- a/distro/void/srcpkgs/dms/template +++ b/distro/void/srcpkgs/dms/template @@ -33,6 +33,7 @@ post_install() { # Desktop entry + icon vinstall "${wrksrc}/assets/dms-open.desktop" 644 usr/share/applications vinstall "${wrksrc}/assets/com.danklinux.dms.desktop" 644 usr/share/applications + vinstall "${wrksrc}/assets/com.danklinux.dms.notepad.desktop" 644 usr/share/applications vinstall "${wrksrc}/assets/danklogo.svg" 644 usr/share/icons/hicolor/scalable/apps # Shell completions (generated by the built binary; skip when cross-building) diff --git a/docs/IPC.md b/docs/IPC.md index b458e7ee1..bdfc7fbea 100644 --- a/docs/IPC.md +++ b/docs/IPC.md @@ -684,6 +684,10 @@ Notepad/scratchpad modal control for quick note-taking. - `open` - Show notepad modal - `close` - Hide notepad modal - `toggle` - Toggle notepad modal visibility +- `openFile ` - Show notepad and load a file into a tab, reusing an existing tab if that file is already open + - Parameters: `path` - Absolute path to a file. Empty path behaves like `open`. + - Returns: Success/failure message + - This is what `com.danklinux.dms.notepad.desktop`'s `Exec=dms ipc call notepad openFile %f` uses so Notepad shows up in "Open With" pickers for text files. - `expand` - Expand the active notepad width and open it if hidden - `collapse` - Collapse the active notepad width without changing visibility - `toggleExpand` - Toggle the active notepad width between collapsed and expanded diff --git a/flake.nix b/flake.nix index c4207e3e6..52b402958 100644 --- a/flake.nix +++ b/flake.nix @@ -133,6 +133,8 @@ $out/share/applications/dms-open.desktop install -D ${rootSrc}/assets/com.danklinux.dms.desktop \ $out/share/applications/com.danklinux.dms.desktop + install -D ${rootSrc}/assets/com.danklinux.dms.notepad.desktop \ + $out/share/applications/com.danklinux.dms.notepad.desktop install -D ${rootSrc}/core/assets/danklogo.svg \ $out/share/hicolor/scalable/apps/danklogo.svg diff --git a/quickshell/DMSShellIPC.qml b/quickshell/DMSShellIPC.qml index 9ac839dab..496942ee1 100644 --- a/quickshell/DMSShellIPC.qml +++ b/quickshell/DMSShellIPC.qml @@ -385,6 +385,22 @@ Item { return "NOTEPAD_OPEN_FAILED"; } + function openFile(path: string): string { + if (!path) + return open(); + if (SettingsData.notepadDefaultMode === "popout") { + PopoutService.openNotepadPopoutWithFile(path); + return "NOTEPAD_OPEN_FILE_SUCCESS"; + } + var instance = getActiveNotepadInstance(); + if (instance) { + instance.show(); + instance.loadedItem?.openExternalFile(path); + return "NOTEPAD_OPEN_FILE_SUCCESS"; + } + return "NOTEPAD_OPEN_FILE_FAILED"; + } + function close(): string { if (SettingsData.notepadDefaultMode === "popout") { PopoutService.notepadPopout?.hide(); diff --git a/quickshell/Modals/DankLauncherV2/Controller.qml b/quickshell/Modals/DankLauncherV2/Controller.qml index e347c2a99..17aba5d17 100644 --- a/quickshell/Modals/DankLauncherV2/Controller.qml +++ b/quickshell/Modals/DankLauncherV2/Controller.qml @@ -787,6 +787,8 @@ Item { if (isCategoryFiltered) { var rawApps = AppSearchService.getAppsInCategory(appCategory); for (var i = 0; i < rawApps.length; i++) { + if (AppSearchService.isShadowedByCoreApp(rawApps[i])) + continue; allItems.push(getOrTransformApp(rawApps[i])); } // Also include core apps (DMS Settings etc.) that match this category @@ -1182,6 +1184,8 @@ Item { var items = []; for (var i = 0; i < apps.length; i++) { + if (AppSearchService.isShadowedByCoreApp(apps[i])) + continue; items.push(getOrTransformApp(apps[i])); } diff --git a/quickshell/Modules/Notepad/Notepad.qml b/quickshell/Modules/Notepad/Notepad.qml index c79aa1a01..7021e7421 100644 --- a/quickshell/Modules/Notepad/Notepad.qml +++ b/quickshell/Modules/Notepad/Notepad.qml @@ -212,6 +212,25 @@ Item { }); } + function openExternalFile(path) { + if (!path) + return; + + for (var i = 0; i < NotepadStorageService.tabs.length; i++) { + var tab = NotepadStorageService.tabs[i]; + if (tab && !tab.isTemporary && tab.filePath === path) { + textEditor.autoSaveToSession(); + switchToTab(i); + return; + } + } + + textEditor.autoSaveToSession(); + NotepadStorageService.createTabForFile(path); + root.currentFileName = path.split('/').pop(); + root.currentFileUrl = "file://" + path; + } + function loadFromFile(fileUrl) { if (hasUnsavedChanges()) { root.pendingFileUrl = fileUrl; diff --git a/quickshell/Modules/Notepad/NotepadPopoutWindow.qml b/quickshell/Modules/Notepad/NotepadPopoutWindow.qml index 3c20f7aa6..e53b23f78 100644 --- a/quickshell/Modules/Notepad/NotepadPopoutWindow.qml +++ b/quickshell/Modules/Notepad/NotepadPopoutWindow.qml @@ -9,6 +9,7 @@ FloatingWindow { id: win property alias shouldBeVisible: win.visible + property alias notepad: notepad function show() { visible = true; diff --git a/quickshell/Modules/Settings/DefaultAppsTab.qml b/quickshell/Modules/Settings/DefaultAppsTab.qml index ae010aa3a..9c84c90e8 100644 --- a/quickshell/Modules/Settings/DefaultAppsTab.qml +++ b/quickshell/Modules/Settings/DefaultAppsTab.qml @@ -41,7 +41,7 @@ Item { readonly property var mimeMapping: ({ [root.appCategory.WebBrowser]: ["x-scheme-handler/https", "x-scheme-handler/http", "text/html", "application/xhtml+xml"], [root.appCategory.FileManager]: ["inode/directory", "x-scheme-handler/file"], - [root.appCategory.TextEditor]: ["text/plain", "application/x-zerosize", "text/x-c++src", "text/x-csrc", "text/x-python", "text/x-shellscript", "application/json"], + [root.appCategory.TextEditor]: ["text/plain", "text/markdown", "application/x-zerosize", "text/x-c++src", "text/x-csrc", "text/x-python", "text/x-shellscript", "application/json"], [root.appCategory.ImageViewer]: ["image/png", "image/jpeg", "image/gif", "image/bmp", "image/webp", "image/avif", "image/svg+xml"], [root.appCategory.VideoPlayer]: ["video/mp4", "video/x-matroska", "video/webm", "video/avi", "video/mpeg", "video/quicktime", "video/x-msvideo"], [root.appCategory.MusicPlayer]: ["audio/mpeg", "audio/x-flac", "audio/wav", "audio/ogg", "audio/aac", "audio/webm"], diff --git a/quickshell/Services/AppSearchService.qml b/quickshell/Services/AppSearchService.qml index 4ac2a37ec..1c05d660a 100644 --- a/quickshell/Services/AppSearchService.qml +++ b/quickshell/Services/AppSearchService.qml @@ -165,6 +165,16 @@ Singleton { readonly property string dmsLogoPath: Qt.resolvedUrl("../assets/danklogo2.svg") + // Prevent desktop entry duplicates from core apps + readonly property var builtInShadowDesktopIds: ["com.danklinux.dms.notepad"] + + function isShadowedByCoreApp(app) { + if (!app) + return false; + const id = (app.id || "").replace(/\.desktop$/, ""); + return builtInShadowDesktopIds.includes(id); + } + readonly property var builtInPlugins: ({ "dms_settings": { id: "dms_settings", diff --git a/quickshell/Services/NotepadStorageService.qml b/quickshell/Services/NotepadStorageService.qml index ebbfb7ace..50d78894d 100644 --- a/quickshell/Services/NotepadStorageService.qml +++ b/quickshell/Services/NotepadStorageService.qml @@ -248,6 +248,29 @@ Singleton { return newTab } + function createTabForFile(path) { + var id = Date.now() + var fileName = path.split('/').pop() + + var newTab = { + id: id, + title: fileName, + filePath: path, + isTemporary: false, + lastModified: new Date().toISOString(), + cursorPosition: 0, + scrollPosition: 0 + } + + var newTabs = tabs.slice() + newTabs.push(newTab) + tabs = newTabs + currentTabIndex = tabs.length - 1 + saveMetadata() + + return newTab + } + function closeTab(tabIndex) { if (tabIndex < 0 || tabIndex >= tabs.length) return diff --git a/quickshell/Services/PopoutService.qml b/quickshell/Services/PopoutService.qml index 168a19539..2c1e1d385 100644 --- a/quickshell/Services/PopoutService.qml +++ b/quickshell/Services/PopoutService.qml @@ -909,6 +909,7 @@ Singleton { property var notepadPopout: null property var notepadPopoutLoader: null property bool _notepadPopoutWantsOpen: false + property string _notepadPendingOpenFilePath: "" function openNotepadPopout() { closeNotepadSlideouts(); @@ -920,10 +921,27 @@ Singleton { } } + function openNotepadPopoutWithFile(path) { + closeNotepadSlideouts(); + if (notepadPopout) { + notepadPopout.show(); + notepadPopout.notepad?.openExternalFile(path); + } else if (notepadPopoutLoader) { + _notepadPendingOpenFilePath = path; + _notepadPopoutWantsOpen = true; + notepadPopoutLoader.active = true; + } + } + function _onNotepadPopoutLoaded() { if (_notepadPopoutWantsOpen && notepadPopout) { _notepadPopoutWantsOpen = false; notepadPopout.show(); + if (_notepadPendingOpenFilePath) { + const pendingPath = _notepadPendingOpenFilePath; + _notepadPendingOpenFilePath = ""; + notepadPopout.notepad?.openExternalFile(pendingPath); + } } } diff --git a/quickshell/Widgets/DankSlideout.qml b/quickshell/Widgets/DankSlideout.qml index 8dc4ffcb4..80e20bb88 100644 --- a/quickshell/Widgets/DankSlideout.qml +++ b/quickshell/Widgets/DankSlideout.qml @@ -31,6 +31,7 @@ PanelWindow { property Component content: null property string title: "" property alias container: contentContainer + property alias loadedItem: contentLoader.item property real customTransparency: -1 property bool mappedVisible: false signal aboutToHide @@ -259,6 +260,7 @@ PanelWindow { anchors.bottomMargin: Theme.spacingL Loader { + id: contentLoader anchors.fill: parent sourceComponent: root.content }