Add command line options

This commit is contained in:
pancakes 2025-08-26 23:07:07 +10:00
parent cca7f91303
commit f93a3cef4d
Signed by: pancakes
SSH key fingerprint: SHA256:yrp4c4hhaPoPG07fb4QyQIgAdlbUdsJvUAydJEWnfTw
2 changed files with 130 additions and 107 deletions

View file

@ -12,6 +12,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="GirCore.Gtk-4.0" Version="0.6.3" /> <PackageReference Include="GirCore.Gtk-4.0" Version="0.6.3" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta7.25380.108" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -1,25 +1,43 @@
using Gdk; using System.CommandLine;
using Gdk;
using Gio; using Gio;
using GLib; using GLib;
using Gtk; using Gtk;
using Pango; using Pango;
using ZwlrLayerShell; using ZwlrLayerShell;
using Application = Gtk.Application; using Application = Gtk.Application;
using TimeSpan = System.TimeSpan;
using Variant = GLib.Variant; using Variant = GLib.Variant;
if (!LayerShell.IsSupported()) var overlayLayer = new Option<bool>("--overlay", "-o")
{ Description = "Use the overlay layer instead of the top layer." };
var horizontalMargin = new Option<uint>("--hmargin", "-H")
{ Description = "Horizontal margin from screen edge in pixels.", DefaultValueFactory = parseResult => 55 };
var verticalMargin = new Option<uint>("--vmargin", "-V")
{ Description = "Vertical margin from screen edge in pixels.", DefaultValueFactory = parseResult => 15 };
var root = new RootCommand("Displays your current song like in Deltarune Chapter 1.")
{ Options = { overlayLayer, horizontalMargin, verticalMargin } };
root.SetAction(RunApplication);
var rootParsed = root.Parse(args);
return rootParsed.Invoke();
void RunApplication(ParseResult parseResult)
{ {
if (!LayerShell.IsSupported())
{
Console.WriteLine("You must be running on a Wayland compositor that supports zwlr_layer_shell_v1"); Console.WriteLine("You must be running on a Wayland compositor that supports zwlr_layer_shell_v1");
return 255; return;
} }
ApplicationWindow? window = null; ApplicationWindow? window = null;
var application = Application.New("gay.pancakes.deltatune_wls", Gio.ApplicationFlags.FlagsNone); var application = Application.New("gay.pancakes.deltatune_wls", Gio.ApplicationFlags.FlagsNone);
GLib.Functions.TimeoutAdd(GLib.Constants.PRIORITY_DEFAULT, 500, () => GLib.Functions.TimeoutAdd(GLib.Constants.PRIORITY_DEFAULT, 500, () =>
{ {
if (window == null) return true; if (window == null) return true;
var playerctl = Subprocess.New(["playerctl", "metadata", "--format", "{{ title }}"], var playerctl = Subprocess.New(["playerctl", "metadata", "--format", "{{ title }}"],
@ -34,20 +52,22 @@ GLib.Functions.TimeoutAdd(GLib.Constants.PRIORITY_DEFAULT, 500, () =>
window.ActivateAction("new_song", Variant.NewString(line?.Trim() ?? "")); window.ActivateAction("new_song", Variant.NewString(line?.Trim() ?? ""));
return true; return true;
}); });
application.OnActivate += (sender, eventArgs) => application.OnActivate += (sender, eventArgs) =>
{ {
window = ApplicationWindow.New((Application)sender); window = ApplicationWindow.New((Application)sender);
LayerShell.InitForWindow(window); LayerShell.InitForWindow(window);
LayerShell.SetNamespace(window, "deltatune-wls"); LayerShell.SetNamespace(window, "deltatune-wls");
LayerShell.SetLayer(window, Layer.Top); LayerShell.SetLayer(window, parseResult.GetValue(overlayLayer) ? Layer.Overlay : Layer.Top);
LayerShell.SetAnchor(window, Edge.Left, true); LayerShell.SetAnchor(window, Edge.Left, true);
LayerShell.SetAnchor(window, Edge.Right, true); LayerShell.SetAnchor(window, Edge.Right, true);
LayerShell.SetAnchor(window, Edge.Top, true); LayerShell.SetAnchor(window, Edge.Top, true);
LayerShell.SetMargin(window, 15); LayerShell.SetMargin(window, Edge.Left, (int)parseResult.GetValue(horizontalMargin));
LayerShell.SetMargin(window, Edge.Left, 55); LayerShell.SetMargin(window, Edge.Right, (int)parseResult.GetValue(horizontalMargin));
LayerShell.SetMargin(window, Edge.Top, (int)parseResult.GetValue(verticalMargin));
LayerShell.SetMargin(window, Edge.Bottom, (int)parseResult.GetValue(verticalMargin));
var label = Label.New(null); var label = Label.New(null);
label.Halign = Align.Start; label.Halign = Align.Start;
@ -70,7 +90,8 @@ application.OnActivate += (sender, eventArgs) =>
if (!label.HasCssClass("fade-in")) if (!label.HasCssClass("fade-in"))
{ {
label.AddCssClass("fade-in"); label.AddCssClass("fade-in");
GLib.Functions.TimeoutAddSeconds(GLib.Constants.PRIORITY_DEFAULT, 9, () => { GLib.Functions.TimeoutAddSeconds(GLib.Constants.PRIORITY_DEFAULT, 9, () =>
{
label.RemoveCssClass("fade-in"); label.RemoveCssClass("fade-in");
return false; return false;
}); });
@ -80,26 +101,26 @@ application.OnActivate += (sender, eventArgs) =>
window.AddAction(action); window.AddAction(action);
window.Present(); window.Present();
}; };
var css = CssProvider.New(); var css = CssProvider.New();
css.LoadFromString(""" css.LoadFromString("""
window { window {
background-color: transparent; background-color: transparent;
} }
window label { window label {
font-size: x-large; font-size: x-large;
color: white; color: white;
text-shadow: -1px -1px 0 #15249a, 1px -1px 0 #15249a, -1px 1px 0 #15249a, 1px 1px 0 #15249a;; text-shadow: -1px -1px 0 #15249a, 1px -1px 0 #15249a, -1px 1px 0 #15249a, 1px 1px 0 #15249a;;
opacity: 0; opacity: 0;
} }
.fade-in { .fade-in {
animation: 8s fade-in ease-in-out both; animation: 8s fade-in ease-in-out both;
} }
@keyframes fade-in { @keyframes fade-in {
0% { 0% {
transform: translateX(80px); transform: translateX(80px);
opacity: 0; opacity: 0;
@ -122,9 +143,10 @@ window label {
transform: translateX(0); transform: translateX(0);
opacity: 0; opacity: 0;
} }
} }
"""); """);
StyleContext.AddProviderForDisplay(Display.GetDefault()!, css, StyleContext.AddProviderForDisplay(Display.GetDefault()!, css,
Gtk.Constants.STYLE_PROVIDER_PRIORITY_APPLICATION); Gtk.Constants.STYLE_PROVIDER_PRIORITY_APPLICATION);
return application.RunWithSynchronizationContext(null); application.RunWithSynchronizationContext(null);
}