mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge branch 'main' of github.com:noctalia-dev/noctalia-shell
This commit is contained in:
+51
-9
@@ -77,6 +77,8 @@ Loader {
|
||||
readonly property int peekHeight: 1
|
||||
readonly property int iconSize: Math.round(12 + 24 * (Settings.data.dock.size ?? 1))
|
||||
readonly property int floatingMargin: Settings.data.dock.floatingRatio * Style.marginL
|
||||
readonly property int maxWidth: modelData ? modelData.width * 0.8 : 1000
|
||||
readonly property int maxHeight: modelData ? modelData.height * 0.8 : 1000
|
||||
|
||||
// Dock position properties
|
||||
readonly property string dockPosition: Settings.data.dock.position
|
||||
@@ -532,7 +534,7 @@ Loader {
|
||||
WlrLayershell.exclusionMode: exclusive ? ExclusionMode.Auto : ExclusionMode.Ignore
|
||||
|
||||
implicitWidth: Math.round(dockContainerWrapper.width + (root.isVertical ? 0 : Style.marginXL * 6))
|
||||
implicitHeight: Math.round(dockContainerWrapper.height)
|
||||
implicitHeight: Math.round(dockContainerWrapper.height + (root.isVertical ? Style.marginXL * 6 : 0))
|
||||
|
||||
// Position based on dock setting
|
||||
anchors.top: dockPosition === "top"
|
||||
@@ -595,8 +597,8 @@ Loader {
|
||||
Rectangle {
|
||||
id: dockContainer
|
||||
// For vertical dock, swap width and height logic
|
||||
width: isVertical ? Math.round(iconSize * 1.5) : dockLayout.implicitWidth + Style.marginXL
|
||||
height: isVertical ? dockLayout.implicitHeight + Style.marginXL : Math.round(iconSize * 1.5)
|
||||
width: isVertical ? Math.round(iconSize * 1.5) : Math.min(dockLayout.implicitWidth + Style.marginXL, root.maxWidth)
|
||||
height: isVertical ? Math.min(dockLayout.implicitHeight + Style.marginXL, root.maxHeight) : Math.round(iconSize * 1.5)
|
||||
color: Qt.alpha(Color.mSurface, Settings.data.dock.backgroundOpacity)
|
||||
|
||||
// Anchor based on padding to achieve centering shift
|
||||
@@ -643,12 +645,50 @@ Loader {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Flickable {
|
||||
id: dock
|
||||
// Swap dimensions based on orientation
|
||||
width: isVertical ? parent.width - (Style.marginXL) : dockLayout.implicitWidth
|
||||
height: isVertical ? dockLayout.implicitHeight : parent.height - (Style.marginXL)
|
||||
// Use parent dimensions more directly to avoid clipping
|
||||
width: isVertical ? parent.width - Style.marginS * 2 : Math.min(dockLayout.implicitWidth, parent.width - Style.marginXL)
|
||||
height: !isVertical ? parent.height - Style.marginS * 2 : Math.min(dockLayout.implicitHeight, parent.height - Style.marginXL)
|
||||
contentWidth: dockLayout.implicitWidth
|
||||
contentHeight: dockLayout.implicitHeight
|
||||
anchors.centerIn: parent
|
||||
clip: true
|
||||
|
||||
flickableDirection: isVertical ? Flickable.VerticalFlick : Flickable.HorizontalFlick
|
||||
|
||||
// Keep interactive dependent on overflow
|
||||
interactive: isVertical ? contentHeight > height : contentWidth > width
|
||||
|
||||
// Centering margins
|
||||
leftMargin: !isVertical && contentWidth < width ? (width - contentWidth) / 2 : 0
|
||||
rightMargin: leftMargin
|
||||
topMargin: isVertical && contentHeight < height ? (height - contentHeight) / 2 : 0
|
||||
bottomMargin: topMargin
|
||||
|
||||
WheelHandler {
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
onWheel: event => {
|
||||
var delta = (event.angleDelta.y !== 0) ? event.angleDelta.y : event.angleDelta.x;
|
||||
if (root.isVertical) {
|
||||
dock.contentY = Math.max(-dock.topMargin, Math.min(dock.contentHeight - dock.height + dock.bottomMargin, dock.contentY - delta));
|
||||
} else {
|
||||
// For horizontal dock, we want to scroll contentX with BOTH x and y wheels
|
||||
var hDelta = (event.angleDelta.x !== 0) ? event.angleDelta.x : event.angleDelta.y;
|
||||
dock.contentX = Math.max(-dock.leftMargin, Math.min(dock.contentWidth - dock.width + dock.rightMargin, dock.contentX - hDelta));
|
||||
}
|
||||
event.accepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.horizontal: ScrollBar {
|
||||
visible: !isVertical && dock.interactive
|
||||
policy: ScrollBar.AsNeeded
|
||||
}
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
visible: isVertical && dock.interactive
|
||||
policy: ScrollBar.AsNeeded
|
||||
}
|
||||
|
||||
function getAppIcon(appData): string {
|
||||
if (!appData || !appData.appId)
|
||||
@@ -663,7 +703,10 @@ Loader {
|
||||
rows: isVertical ? -1 : 1
|
||||
rowSpacing: Style.marginS
|
||||
columnSpacing: Style.marginS
|
||||
anchors.centerIn: parent
|
||||
|
||||
// Ensure the layout takes its full implicit size
|
||||
width: implicitWidth
|
||||
height: implicitHeight
|
||||
|
||||
Repeater {
|
||||
model: dockApps
|
||||
@@ -909,7 +952,6 @@ Loader {
|
||||
// Only allow left-click dragging via axis control
|
||||
drag.target: iconContainer
|
||||
drag.axis: (pressedButtons & Qt.LeftButton) ? (root.isVertical ? Drag.YAxis : Drag.XAxis) : Drag.None
|
||||
preventStealing: true
|
||||
|
||||
onPressed: {
|
||||
var p1 = appButton.mapFromItem(dockContainer, 0, 0);
|
||||
|
||||
@@ -3,19 +3,20 @@
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
async def run_command(*args):
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
*args,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
*args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
stdout, stderr = await process.communicate()
|
||||
if process.returncode != 0:
|
||||
print(f"Error running {' '.join(args)}: {stderr.decode().strip()}", file=sys.stderr)
|
||||
return stdout.decode().strip()
|
||||
|
||||
|
||||
async def apply_gtk3_colors(config_dir: Path):
|
||||
gtk3_dir = config_dir / "gtk-3.0"
|
||||
colors_file = gtk3_dir / "noctalia.css"
|
||||
@@ -36,6 +37,7 @@ async def apply_gtk3_colors(config_dir: Path):
|
||||
print(f"Created symlink: {gtk_css} -> noctalia.css")
|
||||
return True
|
||||
|
||||
|
||||
async def apply_gtk4_colors(config_dir: Path):
|
||||
gtk4_dir = config_dir / "gtk-4.0"
|
||||
colors_file = gtk4_dir / "noctalia.css"
|
||||
@@ -50,35 +52,47 @@ async def apply_gtk4_colors(config_dir: Path):
|
||||
print("Updated GTK4 CSS import")
|
||||
return True
|
||||
|
||||
async def refresh_theme():
|
||||
raw_theme = await run_command("gsettings", "get", "org.gnome.desktop.interface", "gtk-theme")
|
||||
current_theme = raw_theme.strip("'")
|
||||
|
||||
raw_scheme = await run_command("gsettings", "get", "org.gnome.desktop.interface", "color-scheme")
|
||||
current_scheme = raw_scheme.strip("'")
|
||||
|
||||
if not current_theme: current_theme = "adw-gtk3-dark"
|
||||
if not current_scheme: current_scheme = "prefer-dark"
|
||||
|
||||
temp_scheme = "default" if current_scheme == "prefer-dark" else "prefer-dark"
|
||||
|
||||
# await run_command("gsettings", "set", "org.gnome.desktop.interface", "color-scheme", temp_scheme)
|
||||
# await run_command("dconf", "write", "/org/gnome/desktop/interface/color-scheme", f"'{temp_scheme}'")
|
||||
|
||||
# await run_command("gsettings", "set", "org.gnome.desktop.interface", "gtk-theme", "")
|
||||
# await run_command("dconf", "write", "/org/gnome/desktop/interface/gtk-theme", "''")
|
||||
|
||||
# await asyncio.sleep(0.01)
|
||||
|
||||
await run_command("gsettings", "set", "org.gnome.desktop.interface", "color-scheme", current_scheme)
|
||||
await run_command("dconf", "write", "/org/gnome/desktop/interface/color-scheme", f"'{current_scheme}'")
|
||||
|
||||
await run_command("gsettings", "set", "org.gnome.desktop.interface", "gtk-theme", current_theme)
|
||||
await run_command("dconf", "write", "/org/gnome/desktop/interface/gtk-theme", f"'{current_theme}'")
|
||||
async def refresh_theme():
|
||||
has_gsettings = shutil.which("gsettings")
|
||||
has_dconf = shutil.which("dconf")
|
||||
|
||||
if not has_gsettings and not has_dconf:
|
||||
print("No gsettings or dconf found, skip GTK refresh")
|
||||
return
|
||||
|
||||
if mode == "light":
|
||||
target_theme = "adw-gtk3"
|
||||
else:
|
||||
target_theme = "adw-gtk3-dark"
|
||||
|
||||
if has_gsettings:
|
||||
schemas = await run_command("gsettings", "list-schemas")
|
||||
if schemas and "org.gnome.desktop.interface" in schemas:
|
||||
await run_command("gsettings", "set", "org.gnome.desktop.interface", "color-scheme", f"prefer-{mode}")
|
||||
await run_command("gsettings", "set", "org.gnome.desktop.interface", "gtk-theme", f"{target_theme}")
|
||||
return
|
||||
|
||||
if has_dconf:
|
||||
await run_command("dconf", "write", "/org/gnome/desktop/interface/color-scheme", f"'prefer-{mode}'")
|
||||
await run_command("dconf", "write", "/org/gnome/desktop/interface/gtk-theme", f"'{target_theme}'")
|
||||
|
||||
|
||||
async def get_config_dir() -> Path:
|
||||
# 1. project-specific override
|
||||
if value := os.environ.get("NOCTALIA_CONFIG_DIR"):
|
||||
return Path(value).expanduser()
|
||||
|
||||
# 2. XDG standard
|
||||
if value := os.environ.get("XDG_CONFIG_HOME"):
|
||||
return Path(value).expanduser()
|
||||
|
||||
# 3. fallback
|
||||
return Path.home() / ".config"
|
||||
|
||||
|
||||
async def main():
|
||||
config_dir_path = sys.argv[1] if len(sys.argv) > 1 else os.path.expanduser("~/.config")
|
||||
config_dir = Path(config_dir_path)
|
||||
config_dir = await get_config_dir()
|
||||
|
||||
if not config_dir.is_dir():
|
||||
print(f"Error: Config directory not found: {config_dir}", file=sys.stderr)
|
||||
@@ -87,10 +101,7 @@ async def main():
|
||||
(config_dir / "gtk-3.0").mkdir(parents=True, exist_ok=True)
|
||||
(config_dir / "gtk-4.0").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
results = await asyncio.gather(
|
||||
apply_gtk3_colors(config_dir),
|
||||
apply_gtk4_colors(config_dir)
|
||||
)
|
||||
results = await asyncio.gather(apply_gtk3_colors(config_dir), apply_gtk4_colors(config_dir))
|
||||
|
||||
if all(results):
|
||||
await refresh_theme()
|
||||
@@ -98,5 +109,8 @@ async def main():
|
||||
else:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
mode = sys.argv[1] # light or dark
|
||||
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -66,7 +66,7 @@ Singleton {
|
||||
"path": "~/.config/gtk-4.0/noctalia.css"
|
||||
}
|
||||
],
|
||||
"postProcess": mode => `gsettings set org.gnome.desktop.interface color-scheme prefer-${mode} && python3 ${gtkRefreshScript}`
|
||||
"postProcess": mode => `python3 ${gtkRefreshScript} ${mode}`
|
||||
},
|
||||
{
|
||||
"id": "qt",
|
||||
|
||||
Reference in New Issue
Block a user