added quickshell and updated zsh
This commit is contained in:
507
home/hypr/quickshell/components/MenuBar.qml
Normal file
507
home/hypr/quickshell/components/MenuBar.qml
Normal file
@@ -0,0 +1,507 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user