import QtQuick import QtQuick.Layouts import QtQuick.Controls import Quickshell import Quickshell.Wayland import Quickshell.Hyprland import Quickshell.Services.SystemTray import "../theme" import ".." PanelWindow { id: menuBarWindow property var modelData screen: modelData anchors { top: true left: true right: true } // Set implicitHeight to accommodate bar + open popups without clipping implicitHeight: (GlobalState.appleMenuVisible || GlobalState.activeDropdownMenu !== "" || GlobalState.volumePopupVisible || GlobalState.wifiPopupVisible || GlobalState.batteryPopupVisible || GlobalState.calendarPopupVisible) ? 420 : Theme.menuBarHeight color: "transparent" WlrLayershell.layer: WlrLayer.Top WlrLayershell.namespace: "quickshell-menubar" WlrLayershell.keyboardFocus: WlrKeyboardFocus.None // Set exclusive zone only for the 26px bar exclusiveZone: Theme.menuBarHeight // Background Bar (26px) Rectangle { id: barRect anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right height: Theme.menuBarHeight color: Theme.menuBarBg border.color: Theme.menuBarBorder border.width: 0 // Bottom hairline border Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom height: 1 color: Theme.menuBarBorder } RowLayout { anchors.fill: parent anchors.leftMargin: 12 anchors.rightMargin: 12 spacing: 0 // ================================================================= // LEFT SIDE: Apple Menu + App Title + Standard Menus // ================================================================= RowLayout { Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter spacing: 2 // Apple Logo Button Rectangle { id: appleBtn width: 28 height: 20 radius: Theme.radiusSmall color: (GlobalState.appleMenuVisible || appleMouse.containsMouse) ? Qt.rgba(1.0, 1.0, 1.0, 0.18) : "transparent" Image { anchors.centerIn: parent width: 14 height: 14 source: "../assets/apple.svg" sourceSize: Qt.size(14, 14) } MouseArea { id: appleMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { const wasOpen = GlobalState.appleMenuVisible; GlobalState.closeAllPopups(); GlobalState.appleMenuVisible = !wasOpen; } } } // Active App Title (Bold) Rectangle { id: appTitleBtn implicitWidth: appTitleText.implicitWidth + 16 height: 20 radius: Theme.radiusSmall color: titleMouse.containsMouse ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" Text { id: appTitleText anchors.centerIn: parent text: GlobalState.activeWindowClass || "Finder" font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeMenuBar font.weight: Font.Bold color: Theme.textPrimary } MouseArea { id: titleMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { const wasOpen = (GlobalState.activeDropdownMenu === "File"); GlobalState.closeAllPopups(); GlobalState.activeDropdownMenu = wasOpen ? "" : "File"; } } } // Standard Menus: File, Edit, View, Window, Help Repeater { model: ["File", "Edit", "View", "Window", "Help"] delegate: Rectangle { id: menuBtn implicitWidth: menuText.implicitWidth + 14 height: 20 radius: Theme.radiusSmall color: (GlobalState.activeDropdownMenu === modelData || menuMouse.containsMouse) ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" Text { id: menuText anchors.centerIn: parent text: modelData font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeMenuBar font.weight: Font.Normal color: Theme.textPrimary } MouseArea { id: menuMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onEntered: { // If a menu is already open, hovering switches to this one if (GlobalState.activeDropdownMenu !== "") { GlobalState.activeDropdownMenu = modelData; } } onClicked: { const wasOpen = (GlobalState.activeDropdownMenu === modelData); GlobalState.closeAllPopups(); GlobalState.activeDropdownMenu = wasOpen ? "" : modelData; } } } } } // Spacer Item { Layout.fillWidth: true } // ================================================================= // RIGHT SIDE: Tray + Media + Volume + Wifi + Battery + Spotlight + Control Center + Clock // ================================================================= RowLayout { Layout.alignment: Qt.AlignRight | Qt.AlignVCenter spacing: 4 // System Tray Icons Repeater { model: SystemTray.items delegate: Rectangle { required property SystemTrayItem modelData width: 22 height: 20 radius: Theme.radiusSmall color: trayMouse.containsMouse ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" Image { anchors.centerIn: parent width: 15 height: 15 source: modelData.icon || "" sourceSize: Qt.size(15, 15) } MouseArea { id: trayMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: modelData.activate() } } } // Media Indicator (visible if playing) Rectangle { visible: GlobalState.mediaPlaying implicitWidth: mediaRow.implicitWidth + 12 height: 20 radius: Theme.radiusSmall color: mediaMouse.containsMouse ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" RowLayout { id: mediaRow anchors.centerIn: parent spacing: 4 Image { width: 13 height: 13 source: "../assets/music.svg" sourceSize: Qt.size(13, 13) } Text { text: GlobalState.mediaTitle ? `${GlobalState.mediaTitle.substring(0, 18)}...` : "Playing" font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeSmall color: Theme.textSecondary } } MouseArea { id: mediaMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: GlobalState.mediaPlayPause() } } // Volume Item Rectangle { id: volBtn width: 26 height: 20 radius: Theme.radiusSmall color: (GlobalState.volumePopupVisible || volMouse.containsMouse) ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" Image { anchors.centerIn: parent width: 14 height: 14 source: "../assets/volume.svg" sourceSize: Qt.size(14, 14) } MouseArea { id: volMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { const wasOpen = GlobalState.volumePopupVisible; GlobalState.closeAllPopups(); GlobalState.volumePopupVisible = !wasOpen; } } } // Wi-Fi Item Rectangle { id: wifiBtn width: 26 height: 20 radius: Theme.radiusSmall color: (GlobalState.wifiPopupVisible || wifiMouse.containsMouse) ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" Image { anchors.centerIn: parent width: 14 height: 14 source: "../assets/wifi.svg" sourceSize: Qt.size(14, 14) } MouseArea { id: wifiMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { const wasOpen = GlobalState.wifiPopupVisible; GlobalState.closeAllPopups(); GlobalState.wifiPopupVisible = !wasOpen; } } } // Battery Item Rectangle { id: batBtn implicitWidth: batRow.implicitWidth + 8 height: 20 radius: Theme.radiusSmall color: (GlobalState.batteryPopupVisible || batMouse.containsMouse) ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" RowLayout { id: batRow anchors.centerIn: parent spacing: 4 Text { visible: GlobalState.batteryPresent text: `${GlobalState.batteryPercent}%` font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeSmall color: Theme.textPrimary } Image { width: 18 height: 12 source: "../assets/battery.svg" sourceSize: Qt.size(18, 12) } } MouseArea { id: batMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { const wasOpen = GlobalState.batteryPopupVisible; GlobalState.closeAllPopups(); GlobalState.batteryPopupVisible = !wasOpen; } } } // Spotlight Search Button Rectangle { id: spotBtn width: 26 height: 20 radius: Theme.radiusSmall color: (GlobalState.spotlightVisible || spotMouse.containsMouse) ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" Image { anchors.centerIn: parent width: 14 height: 14 source: "../assets/spotlight.svg" sourceSize: Qt.size(14, 14) } MouseArea { id: spotMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: GlobalState.toggleSpotlight() } } // Control Center / Notification Center Toggle Button Rectangle { id: ccBtn width: 26 height: 20 radius: Theme.radiusSmall color: (GlobalState.controlCenterVisible || ccMouse.containsMouse) ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" Image { anchors.centerIn: parent width: 14 height: 14 source: "../assets/controlcenter.svg" sourceSize: Qt.size(14, 14) } MouseArea { id: ccMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: GlobalState.toggleControlCenter() } } // Date & Time (Clock) Rectangle { id: clockBtn implicitWidth: clockRow.implicitWidth + 10 height: 20 radius: Theme.radiusSmall color: (GlobalState.calendarPopupVisible || clockMouse.containsMouse) ? Qt.rgba(1.0, 1.0, 1.0, 0.15) : "transparent" RowLayout { id: clockRow anchors.centerIn: parent spacing: 6 Text { text: GlobalState.dateString font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeMenuBar color: Theme.textSecondary } Text { text: GlobalState.timeString font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeMenuBar font.weight: Font.Medium color: Theme.textPrimary } } MouseArea { id: clockMouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { const wasOpen = GlobalState.calendarPopupVisible; GlobalState.closeAllPopups(); GlobalState.calendarPopupVisible = !wasOpen; } } } } } } // ========================================================================= // DROPDOWNS & POPUPS // ========================================================================= // 1. Apple Menu Dropdown AppleMenu { id: appleDropdown visible: GlobalState.appleMenuVisible x: 8 y: Theme.menuBarHeight + 2 } // 2. Application Menus Dropdown (File, Edit, View, Window, Help) AppMenuDropdown { id: appMenuDropdown visible: GlobalState.activeDropdownMenu !== "" menuName: GlobalState.activeDropdownMenu x: 60 y: Theme.menuBarHeight + 2 } // 3. Volume Popup VolumePopup { id: volumeDropdown visible: GlobalState.volumePopupVisible anchors.top: barRect.bottom anchors.topMargin: 2 anchors.right: parent.right anchors.rightMargin: 190 } // 4. Wi-Fi Popup WifiPopup { id: wifiDropdown visible: GlobalState.wifiPopupVisible anchors.top: barRect.bottom anchors.topMargin: 2 anchors.right: parent.right anchors.rightMargin: 160 } // 5. Battery Popup BatteryPopup { id: batteryDropdown visible: GlobalState.batteryPopupVisible anchors.top: barRect.bottom anchors.topMargin: 2 anchors.right: parent.right anchors.rightMargin: 110 } // 6. Calendar Popup CalendarPopup { id: calDropdown visible: GlobalState.calendarPopupVisible anchors.top: barRect.bottom anchors.topMargin: 2 anchors.right: parent.right anchors.rightMargin: 10 } }