Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package nwg-dock-hyprland for openSUSE:Factory checked in at 2024-12-02 16:59:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nwg-dock-hyprland (Old) and /work/SRC/openSUSE:Factory/.nwg-dock-hyprland.new.28523 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nwg-dock-hyprland" Mon Dec 2 16:59:05 2024 rev:3 rq:1227646 version:0.3.3 Changes: -------- --- /work/SRC/openSUSE:Factory/nwg-dock-hyprland/nwg-dock-hyprland.changes 2024-06-17 19:34:20.068959287 +0200 +++ /work/SRC/openSUSE:Factory/.nwg-dock-hyprland.new.28523/nwg-dock-hyprland.changes 2024-12-02 16:59:27.426013658 +0100 @@ -1,0 +2,38 @@ +Fri Nov 29 03:24:00 UTC 2024 - [email protected] + +- Updated to version 0.3.3: + * Use separate task images (dots) and placement, according to the dock + position, (gh#nwg-piotr/nwg-dock-hyprland#62). + * Refresh the dock on item unpinned. + * Update dependencies. +- Changes from version 0.3.2; + * Added -p right position flag for left-handed users, + (gh#nwg-piotr/nwg-dock-hyprland#43). + * Hotspot layershell namespace renamed to "hotspot", to avoid blurring the + window together with the dock; +- Changes from version 0.3.1: + * Added -iw (ignoreWorkspaces) parameter to exclude clients from specified + workspaces, (gh#nwg-piotr/nwg-dock-hyprland#59). +- Changes from version 0.3.0: + * Open new instances of apps using middle mouse button, + (gh#nwg-piotr/nwg-dock-hyprland#51). + * Add "Close all windows" context menu entry, + (gh#nwg-piotr/nwg-dock-hyprland#50). + * Add signals to explicit show and hide window, + (gh#nwg-piotr/nwg-dock-hyprland#55): + + use of SIGUSR1 to toggle window visibility deprecated, + + added sigToggle (SIGRTMIN+1) to toggle window visibility, + + added sigShow (SIGRTMIN+2) to show the window, + + added sigHide (SIGRTMIN+3) to hide the window. +- Changes from version 0.2.2: + * Fixed crash on Hyprland v0.42.0: client.Fullscreen field type changed from + bool to int, (gh#nwg-piotr/nwg-dock-hyprland#48). +- Changes from version 0.2.1: + * Fixed, (gh#nwg-piotr/nwg-dock-hyprland#49). + * gotk3 updated. +- Changes from version 0.2.0: + * Added -lp flag for the launcher button position, + (gh#nwg-piotr/nwg-dock-hyprland#46). +- Add image(s) install to spec file. + +------------------------------------------------------------------- Old: ---- nwg-dock-hyprland-0.1.9.tar.gz New: ---- nwg-dock-hyprland-0.3.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nwg-dock-hyprland.spec ++++++ --- /var/tmp/diff_new_pack.hJCzJW/_old 2024-12-02 16:59:28.074040848 +0100 +++ /var/tmp/diff_new_pack.hJCzJW/_new 2024-12-02 16:59:28.078041016 +0100 @@ -18,7 +18,7 @@ Name: nwg-dock-hyprland -Version: 0.1.9 +Version: 0.3.3 Release: 0 Summary: Hyprland application dock License: MIT @@ -40,18 +40,20 @@ %build ## Note build takes around 10 minutes, so be patient as there is no output! -go build \ +go build -v \ -mod=vendor \ -buildmode=pie %install -install -d -m 0755 %{buildroot}%{_bindir} %{buildroot}%{_datadir}/%{name} +install -d -m 0755 %{buildroot}%{_bindir} %{buildroot}%{_datadir}/%{name}/images install -m 0755 %{name} %{buildroot}%{_bindir}/%{name} install -m 0644 config/style.css %{buildroot}%{_datadir}/%{name}/style.css +cp -ar images/* %{buildroot}%{_datadir}/%{name}/images/ %files %license LICENSE %{_bindir}/%{name} %dir %{_datadir}/%{name} %{_datadir}/%{name}/style.css +%{_datadir}/%{name}/images ++++++ nwg-dock-hyprland-0.1.9.tar.gz -> nwg-dock-hyprland-0.3.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nwg-dock-hyprland-0.1.9/README.md new/nwg-dock-hyprland-0.3.3/README.md --- old/nwg-dock-hyprland-0.1.9/README.md 2024-05-19 00:54:32.000000000 +0200 +++ new/nwg-dock-hyprland-0.3.3/README.md 2024-11-16 01:19:11.000000000 +0100 @@ -8,6 +8,8 @@ Wayland compositor. It features pinned buttons, client buttons and the launcher button. The latter by default starts [nwg-drawer](https://github.com/nwg-piotr/nwg-drawer). +You'll find a lot of useful information in [this video](https://youtu.be/16KX3vnbNcg?si=POGOVwYxPXDIrwrT) on the "My Linux For Work" YT channel by Stephan Raabe. +   @@ -102,8 +104,12 @@ Icon size (default 48) -ico string alternative name or path for the launcher ICOn + -iw string + Ignore the running applications on these Workspaces based on the workspace's name or id, e.g. "special,10" -l string Layer "overlay", "top" or "bottom" (default "overlay") + -lp string + Launcher button position, 'start' or 'end' (default "end") -mb int Margin Bottom -ml int @@ -125,6 +131,11 @@ -w int number of Workspaces you use (default 10) -x set eXclusive zone: move other windows aside; overrides the "-l" argument + +Usage of signals: + SIGRTMIN+1 (signal 35): toggle dock visibility (USR1 has been deprecated) + SIGRTMIN+2 (signal 36): show the dock + SIGRTMIN+3 (signal 37): hide the dock ```  diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nwg-dock-hyprland-0.1.9/go.mod new/nwg-dock-hyprland-0.3.3/go.mod --- old/nwg-dock-hyprland-0.1.9/go.mod 2024-05-19 00:54:32.000000000 +0200 +++ new/nwg-dock-hyprland-0.3.3/go.mod 2024-11-16 01:19:11.000000000 +0100 @@ -1,12 +1,12 @@ -module nwg-dock-hyprland +module github.com/nwg-piotr/nwg-dock-hyprland -go 1.22 +go 1.23 require ( github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37 github.com/dlasky/gotk3-layershell v0.0.0-20240515133811-5c5115f0d774 - github.com/gotk3/gotk3 v0.6.3 + github.com/gotk3/gotk3 v0.6.5-0.20240618185848-ff349ae13f56 github.com/sirupsen/logrus v1.9.3 ) -require golang.org/x/sys v0.20.0 // indirect +require golang.org/x/sys v0.27.0 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nwg-dock-hyprland-0.1.9/go.sum new/nwg-dock-hyprland-0.3.3/go.sum --- old/nwg-dock-hyprland-0.1.9/go.sum 2024-05-19 00:54:32.000000000 +0200 +++ new/nwg-dock-hyprland-0.3.3/go.sum 2024-11-16 01:19:11.000000000 +0100 @@ -3,17 +3,11 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dlasky/gotk3-layershell v0.0.0-20221218201547-1f6674a3f872 h1:16qcNl+UgbvudN7wPv+zq4mmDSYJWdLv5jbVhS7+OVI= -github.com/dlasky/gotk3-layershell v0.0.0-20221218201547-1f6674a3f872/go.mod h1:JHLx2Wz4mAPVwn4PFhC69ydwyHP4A3wQvlg7HKVVc1U= -github.com/dlasky/gotk3-layershell v0.0.0-20230802002603-b0c42cd8474f h1:qDnUQAD7tVX/gnL6uSgouzfGNA4xXH+B/fd6Ko19GgM= -github.com/dlasky/gotk3-layershell v0.0.0-20230802002603-b0c42cd8474f/go.mod h1:JHLx2Wz4mAPVwn4PFhC69ydwyHP4A3wQvlg7HKVVc1U= github.com/dlasky/gotk3-layershell v0.0.0-20240515133811-5c5115f0d774 h1:o87OVL4olQBlVwN3+NSVQpS6gj9FWUYtxOfHXWZigUE= github.com/dlasky/gotk3-layershell v0.0.0-20240515133811-5c5115f0d774/go.mod h1:JHLx2Wz4mAPVwn4PFhC69ydwyHP4A3wQvlg7HKVVc1U= github.com/gotk3/gotk3 v0.6.1/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q= -github.com/gotk3/gotk3 v0.6.2 h1:sx/PjaKfKULJPTPq8p2kn2ZbcNFxpOJqi4VLzMbEOO8= -github.com/gotk3/gotk3 v0.6.2/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q= -github.com/gotk3/gotk3 v0.6.3 h1:+Ke4WkM1TQUNOlM2TZH6szqknqo+zNbX3BZWVXjSHYw= -github.com/gotk3/gotk3 v0.6.3/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q= +github.com/gotk3/gotk3 v0.6.5-0.20240618185848-ff349ae13f56 h1:eR+xxC8qqKuPMTucZqaklBxLIT7/4L7dzhlwKMrDbj8= +github.com/gotk3/gotk3 v0.6.5-0.20240618185848-ff349ae13f56/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -21,14 +15,13 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nwg-dock-hyprland-0.1.9/hypr.go new/nwg-dock-hyprland-0.3.3/hypr.go --- old/nwg-dock-hyprland-0.1.9/hypr.go 2024-05-19 00:54:32.000000000 +0200 +++ new/nwg-dock-hyprland-0.3.3/hypr.go 2024-11-16 01:19:11.000000000 +0100 @@ -59,7 +59,7 @@ Pid int `json:"pid"` Xwayland bool `json:"xwayland"` Pinned bool `json:"pinned"` - Fullscreen bool `json:"fullscreen"` + Fullscreen int `json:"fullscreen"` FullscreenMode int `json:"fullscreenMode"` FakeFullscreen bool `json:"fakeFullscreen"` Grouped []interface{} `json:"grouped"` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nwg-dock-hyprland-0.1.9/images/task-empty-vertical.svg new/nwg-dock-hyprland-0.3.3/images/task-empty-vertical.svg --- old/nwg-dock-hyprland-0.1.9/images/task-empty-vertical.svg 1970-01-01 01:00:00.000000000 +0100 +++ new/nwg-dock-hyprland-0.3.3/images/task-empty-vertical.svg 2024-11-16 01:19:11.000000000 +0100 @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="9" + height="48" + viewBox="0 0 2.3812498 12.7" + version="1.1" + id="svg8" + inkscape:version="1.4 (e7c3feb100, 2024-10-09)" + sodipodi:docname="task-empty-vertical.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="17.303698" + inkscape:cx="21.382713" + inkscape:cy="24.907971" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + showgrid="false" + units="px" + inkscape:window-width="2552" + inkscape:window-height="1362" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Warstwa 1" + inkscape:groupmode="layer" + id="layer1" /> +</svg> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nwg-dock-hyprland-0.1.9/images/task-multiple-vertical.svg new/nwg-dock-hyprland-0.3.3/images/task-multiple-vertical.svg --- old/nwg-dock-hyprland-0.1.9/images/task-multiple-vertical.svg 1970-01-01 01:00:00.000000000 +0100 +++ new/nwg-dock-hyprland-0.3.3/images/task-multiple-vertical.svg 2024-11-16 01:19:11.000000000 +0100 @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="9" + height="48" + viewBox="0 0 2.3812498 12.7" + version="1.1" + id="svg8" + sodipodi:docname="task-multiple-vertical.svg" + inkscape:version="1.4 (e7c3feb100, 2024-10-09)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="17.303698" + inkscape:cx="20.862592" + inkscape:cy="17.973037" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + showgrid="false" + units="px" + inkscape:window-width="2552" + inkscape:window-height="1362" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Warstwa 1" + inkscape:groupmode="layer" + id="layer1"> + <circle + style="fill:#00ffff;fill-opacity:1;stroke:#444444;stroke-width:0.239071;stroke-opacity:1" + id="path833" + cx="-8.0527248" + cy="1.1906252" + r="0.93879807" + transform="rotate(-90)" /> + <circle + style="fill:#00ffff;fill-opacity:1;stroke:#444444;stroke-width:0.239071;stroke-opacity:1" + id="path833-3" + cx="-4.736042" + cy="1.1906252" + r="0.93879807" + transform="rotate(-90)" /> + </g> +</svg> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nwg-dock-hyprland-0.1.9/images/task-single-vertical.svg new/nwg-dock-hyprland-0.3.3/images/task-single-vertical.svg --- old/nwg-dock-hyprland-0.1.9/images/task-single-vertical.svg 1970-01-01 01:00:00.000000000 +0100 +++ new/nwg-dock-hyprland-0.3.3/images/task-single-vertical.svg 2024-11-16 01:19:11.000000000 +0100 @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="9" + height="48" + viewBox="0 0 2.3812498 12.7" + version="1.1" + id="svg8" + inkscape:version="1.4 (e7c3feb100, 2024-10-09)" + sodipodi:docname="task-single-vertival.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="17.303698" + inkscape:cx="18.753217" + inkscape:cy="17.973037" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + showgrid="false" + units="px" + inkscape:window-width="2552" + inkscape:window-height="1362" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Warstwa 1" + inkscape:groupmode="layer" + id="layer1"> + <circle + style="fill:#00ffff;fill-opacity:1;stroke:#444444;stroke-width:0.239071;stroke-opacity:1" + id="path833" + cx="1.1906252" + cy="6.3499999" + r="0.93879807" /> + </g> +</svg> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nwg-dock-hyprland-0.1.9/main.go new/nwg-dock-hyprland-0.3.3/main.go --- old/nwg-dock-hyprland-0.1.9/main.go 2024-05-19 00:54:32.000000000 +0200 +++ new/nwg-dock-hyprland-0.3.3/main.go 2024-11-16 01:19:11.000000000 +0100 @@ -1,13 +1,19 @@ package main +/* +#include <signal.h> +*/ +import "C" + import ( "flag" "fmt" "net" "os" - "os/exec" "os/signal" "path/filepath" + "slices" + "sort" "strconv" "strings" "syscall" @@ -22,7 +28,7 @@ "github.com/gotk3/gotk3/gtk" ) -const version = "0.1.9" +const version = "0.3.3" type WindowState int @@ -32,63 +38,69 @@ ) var ( + activeClient *client appDirs []string - dataHome string + clients []client configDirectory string - pinnedFile string - pinned []string - oldClients []client + dataHome string + detectorEnteredAt int64 + his string // $HYPRLAND_INSTANCE_SIGNATURE + hyprDir string // $XDG_RUNTIME_DIR/hypr since hyprland>0.39.1, earlier /tmp/hypr + ignoredWorkspaces []string + imgSizeScaled int + lastWinAddr string mainBox *gtk.Box - src glib.SourceHandle + monitors []monitor + oldClients []client outerOrientation, innerOrientation gtk.Orientation + pinned []string + pinnedFile string + src glib.SourceHandle widgetAnchor, menuAnchor gdk.Gravity - imgSizeScaled int win *gtk.Window windowStateChannel chan WindowState = make(chan WindowState, 1) - detectorEnteredAt int64 - his string // $HYPRLAND_INSTANCE_SIGNATURE - hyprDir string // $XDG_RUNTIME_DIR/hypr since hyprland>0.39.1, earlier /tmp/hypr - monitors []monitor - clients []client - activeClient *client - lastWinAddr string ) // Flags +var alignment = flag.String("a", "center", "Alignment in full width/height: \"start\", \"center\" or \"end\"") +var autohide = flag.Bool("d", false, "auto-hiDe: show dock when hotspot hovered, close when left or a button clicked") var cssFileName = flag.String("s", "style.css", "Styling: css file name") -var targetOutput = flag.String("o", "", "name of Output to display the dock on") +var debug = flag.Bool("debug", false, "turn on debug messages") var displayVersion = flag.Bool("v", false, "display Version information") -var autohide = flag.Bool("d", false, "auto-hiDe: show dock when hotspot hovered, close when left or a button clicked") -var full = flag.Bool("f", false, "take Full screen width/height") -var numWS = flag.Int64("w", 10, "number of Workspaces you use") -var position = flag.String("p", "bottom", "Position: \"bottom\", \"top\" or \"left\"") var exclusive = flag.Bool("x", false, "set eXclusive zone: move other windows aside; overrides the \"-l\" argument") -var imgSize = flag.Int("i", 48, "Icon size") +var full = flag.Bool("f", false, "take Full screen width/height") +var hotspotDelay = flag.Int64("hd", 20, "Hotspot Delay [ms]; the smaller, the faster mouse pointer needs to enter hotspot for the dock to appear; set 0 to disable") var ico = flag.String("ico", "", "alternative name or path for the launcher ICOn") -var layer = flag.String("l", "overlay", "Layer \"overlay\", \"top\" or \"bottom\"") +var ignoreWorkspaces = flag.String("iw", "", "Ignore the running applications on these Workspaces based on the workspace's name or id, e.g. \"special,10\"") +var imgSize = flag.Int("i", 48, "Icon size") var launcherCmd = flag.String("c", "", "Command assigned to the launcher button") -var alignment = flag.String("a", "center", "Alignment in full width/height: \"start\", \"center\" or \"end\"") -var marginTop = flag.Int("mt", 0, "Margin Top") +var launcherPos = flag.String("lp", "end", "Launcher button position, 'start' or 'end'") +var layer = flag.String("l", "overlay", "Layer \"overlay\", \"top\" or \"bottom\"") +var marginBottom = flag.Int("mb", 0, "Margin Bottom") var marginLeft = flag.Int("ml", 0, "Margin Left") var marginRight = flag.Int("mr", 0, "Margin Right") -var marginBottom = flag.Int("mb", 0, "Margin Bottom") -var hotspotDelay = flag.Int64("hd", 20, "Hotspot Delay [ms]; the smaller, the faster mouse pointer needs to enter hotspot for the dock to appear; set 0 to disable") +var marginTop = flag.Int("mt", 0, "Margin Top") var noLauncher = flag.Bool("nolauncher", false, "don't show the launcher button") +var numWS = flag.Int64("w", 10, "number of Workspaces you use") +var position = flag.String("p", "bottom", "Position: \"bottom\", \"top\" \"left\" or \"right\"") var resident = flag.Bool("r", false, "Leave the program resident, but w/o hotspot") -var debug = flag.Bool("debug", false, "turn on debug messages") +var targetOutput = flag.String("o", "", "name of Output to display the dock on") + +var vertical bool +var alignmentBox *gtk.Box -func buildMainBox(vbox *gtk.Box) { +func buildMainBox() { if mainBox != nil { mainBox.Destroy() } mainBox, _ = gtk.BoxNew(innerOrientation, 0) if *alignment == "start" { - vbox.PackStart(mainBox, false, true, 0) + alignmentBox.PackStart(mainBox, false, true, 0) } else if *alignment == "end" { - vbox.PackEnd(mainBox, false, true, 0) + alignmentBox.PackEnd(mainBox, false, true, 0) } else { - vbox.PackStart(mainBox, true, false, 0) + alignmentBox.PackStart(mainBox, true, false, 0) } var err error @@ -103,6 +115,23 @@ allItems = append(allItems, cntPin) } } + + // actually unnecessary in recent Hyprland versions, but just in case, see #44. + sort.Slice(clients, func(i, j int) bool { + if clients[i].Workspace.Id != clients[j].Workspace.Id { + return clients[i].Workspace.Id < clients[j].Workspace.Id + } else { + return clients[i].Class < clients[j].Class + } + }) + + // delete the clients that are on ignored workspaces + clients = slices.DeleteFunc(clients, func(cl client) bool { + // only use the part in front of ":" if something like "special:scratch_term" is being used + clWorkspace, _, _ := strings.Cut(cl.Workspace.Name, ":") + return isIn(ignoredWorkspaces, strconv.Itoa(cl.Workspace.Id)) || isIn(ignoredWorkspaces, clWorkspace) + }) + for _, cntTask := range clients { if !isIn(allItems, cntTask.Class) && !strings.Contains(*launcherCmd, cntTask.Class) && cntTask.Class != "" { allItems = append(allItems, cntTask.Class) @@ -122,16 +151,23 @@ imgSizeScaled = *imgSize } + if *launcherPos == "start" { + button := launcherButton(position) + if button != nil { + mainBox.PackStart(button, false, false, 0) + } + } + var alreadyAdded []string for _, pin := range pinned { if !inTasks(pin) { - button := pinnedButton(pin) + button := pinnedButton(pin, position) mainBox.PackStart(button, false, false, 0) } else { instances := taskInstances(pin) c := instances[0] if len(instances) == 1 { - button := taskButton(c, instances) + button := taskButton(c, instances, position) mainBox.PackStart(button, false, false, 0) if c.Class == activeClient.Class && !*autohide { button.SetProperty("name", "active") @@ -139,7 +175,7 @@ button.SetProperty("name", "") } } else if !isIn(alreadyAdded, c.Class) { - button := taskButton(c, instances) + button := taskButton(c, instances, position) mainBox.PackStart(button, false, false, 0) if c.Class == activeClient.Class && !*autohide { button.SetProperty("name", "active") @@ -161,7 +197,7 @@ if !inPinned(t.Class) && t.Class != "" { instances := taskInstances(t.Class) if len(instances) == 1 { - button := taskButton(t, instances) + button := taskButton(t, instances, position) mainBox.PackStart(button, false, false, 0) if t.Class == activeClient.Class && !*autohide { button.SetProperty("name", "active") @@ -169,7 +205,7 @@ button.SetProperty("name", "") } } else if !isIn(alreadyAdded, t.Class) { - button := taskButton(t, instances) + button := taskButton(t, instances, position) mainBox.PackStart(button, false, false, 0) if t.Class == activeClient.Class && !*autohide { button.SetProperty("name", "active") @@ -184,41 +220,11 @@ } } - if !*noLauncher && *launcherCmd != "" { - button, _ := gtk.ButtonNew() - var pixbuf *gdk.Pixbuf - var e error - if *ico == "" { - pixbuf, e = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/grid.svg"), imgSizeScaled, imgSizeScaled) - } else { - pixbuf, e = createPixbuf(*ico, imgSizeScaled) - } - if e == nil { - image, _ := gtk.ImageNewFromPixbuf(pixbuf) - button.SetImage(image) - button.SetAlwaysShowImage(true) - - button.Connect("clicked", func() { - elements := strings.Split(*launcherCmd, " ") - cmd := exec.Command(elements[0], elements[1:]...) - - go func() { - err := cmd.Run() - if err != nil { - log.Warnf("Unable to start program: %s", err.Error()) - } - }() - - if *autohide { - win.Hide() - } - }) - button.Connect("enter-notify-event", cancelClose) - } else { - log.Errorf("Unable to show grid button: %s", err.Error()) + if *launcherPos == "end" { + button := launcherButton(position) + if button != nil { + mainBox.PackStart(button, false, false, 0) } - - mainBox.PackStart(button, false, false, 0) } mainBox.ShowAll() @@ -230,7 +236,7 @@ layershell.InitForWindow(win) layershell.SetMonitor(win, &monitor) - layershell.SetNamespace(win, "nwg-dock-hotspot") + layershell.SetNamespace(win, "hotspot") var box *gtk.Box if *position == "bottom" || *position == "top" { @@ -243,7 +249,7 @@ detectorBox, _ := gtk.EventBoxNew() _ = detectorBox.SetProperty("name", "detector-box") - if *position == "bottom" { + if *position == "bottom" || *position == "right" { box.PackStart(detectorBox, false, false, 0) } else { box.PackEnd(detectorBox, false, false, 0) @@ -288,10 +294,14 @@ layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_RIGHT, *full) } - if *position == "left" { + if *position == "left" || *position == "right" { detectorBox.SetSizeRequest(w/3, h) hotspotBox.SetSizeRequest(2, h) - layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_LEFT, true) + if *position == "left" { + layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_LEFT, true) + } else { + layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_RIGHT, true) + } layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_TOP, *full) layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_BOTTOM, *full) @@ -310,6 +320,20 @@ } func main() { + sigRtmin := syscall.Signal(C.SIGRTMIN) + sigToggle := sigRtmin + 1 + sigShow := sigRtmin + 2 + sigHide := sigRtmin + 3 + + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s:\n", flag.CommandLine.Name()) + flag.PrintDefaults() + fmt.Fprintf(flag.CommandLine.Output(), "\nUsage of signals:\n") + fmt.Fprintf(flag.CommandLine.Output(), " SIGRTMIN+1 (%s): toggle dock visibility (USR1 has been deprecated)\n", sigToggle) + fmt.Fprintf(flag.CommandLine.Output(), " SIGRTMIN+2 (%s): show the dock\n", sigShow) + fmt.Fprintf(flag.CommandLine.Output(), " SIGRTMIN+3 (%s): hide the dock\n", sigHide) + } + flag.Parse() if *debug { log.SetLevel(log.DebugLevel) @@ -347,9 +371,8 @@ } // Gentle SIGTERM handler thanks to reiki4040 https://gist.github.com/reiki4040/be3705f307d3cd136e85 - // v0.2: we also need to support SIGUSR from now on. signalChan := make(chan os.Signal, 1) - signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGUSR1) + signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGUSR1, sigToggle, sigShow, sigHide) go func() { for { @@ -359,9 +382,8 @@ log.Info("SIGTERM received, bye bye!") gtk.MainQuit() case syscall.SIGUSR1: + log.Warn("SIGUSR1 for toggling visibility is deprecated, use SIGRTMIN+1") if *resident || *autohide { - // As win.Show() called from inside a goroutine randomly crashes GTK, - // let's just set e helper variable here. We'll be checking it with glib.TimeoutAdd. if !win.IsVisible() { log.Debug("SIGUSR1 received, showing the window") windowStateChannel <- WindowShow @@ -370,8 +392,41 @@ windowStateChannel <- WindowHide } } else { - log.Info("SIGUSR1 received, and I'm not resident, bye bye!") - gtk.MainQuit() + log.Debugf("SIGUSR1 received, but I'm not resident, ignoring") + } + case sigToggle: + if *resident || *autohide { + if !win.IsVisible() { + log.Debug("sigToggle received, showing the window") + windowStateChannel <- WindowShow + } else { + log.Debug("sigToggle received, hiding the window") + windowStateChannel <- WindowHide + } + } else { + log.Debug("sigToggle received, but I'm not resident, ignoring") + } + case sigShow: + if *resident || *autohide { + if !win.IsVisible() { + log.Debug("sigShow received, showing the window") + windowStateChannel <- WindowShow + } else { + log.Debug("sigShow received, but window already visible, ignoring") + } + } else { + log.Debug("sigToggle received, but I'm not resident, ignoring") + } + case sigHide: + if *resident || *autohide { + if !win.IsVisible() { + log.Debug("sigHide received, but window already hidden, ignoring") + } else { + log.Debug("sigHide received, hiding the window") + windowStateChannel <- WindowHide + } + } else { + log.Debug("sigHide received, but I'm not resident, ignoring") } default: log.Warn("Unknown signal") @@ -394,8 +449,8 @@ if *autohide || *resident { log.Info("Running instance found, terminating...") } else { - _ = syscall.Kill(i, syscall.SIGUSR1) - log.Info("Sending SIGUSR1 to running instance and bye, bye!") + _ = syscall.Kill(i, sigToggle) + log.Info("Sending sigToggle to running instance and bye, bye!") } } } @@ -438,6 +493,10 @@ } pinnedFile = filepath.Join(cacheDirectory, "nwg-dock-pinned") cssFile := filepath.Join(configDirectory, *cssFileName) + ignoredWorkspaces = strings.Split(*ignoreWorkspaces, ",") + if *ignoreWorkspaces != "" { + log.Infof("Ignored workspaces: %s\n", strings.Join(ignoredWorkspaces, ",")) + } appDirs = getAppDirs() @@ -498,8 +557,12 @@ layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_RIGHT, *full) } - if *position == "left" { - layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_LEFT, true) + if *position == "left" || *position == "right" { + if *position == "left" { + layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_LEFT, true) + } else { + layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_RIGHT, true) + } layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_TOP, *full) layershell.SetAnchor(win, layershell.LAYER_SHELL_EDGE_BOTTOM, *full) @@ -548,7 +611,7 @@ _ = outerBox.SetProperty("name", "box") win.Add(outerBox) - alignmentBox, _ := gtk.BoxNew(innerOrientation, 0) + alignmentBox, _ = gtk.BoxNew(innerOrientation, 0) outerBox.PackStart(alignmentBox, true, true, 0) mainBox, _ = gtk.BoxNew(innerOrientation, 0) @@ -558,7 +621,7 @@ refreshMainBox := func(forceRefresh bool) { if forceRefresh || (len(clients) != len(oldClients)) { glib.TimeoutAdd(0, func() bool { - buildMainBox(alignmentBox) + buildMainBox() oldClients = clients return false }) @@ -569,7 +632,7 @@ if err != nil { log.Fatalf("Couldn't list clients: %s", err) } - buildMainBox(alignmentBox) + buildMainBox() win.ShowAll() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nwg-dock-hyprland-0.1.9/tools.go new/nwg-dock-hyprland-0.3.3/tools.go --- old/nwg-dock-hyprland-0.1.9/tools.go 2024-05-19 00:54:32.000000000 +0200 +++ new/nwg-dock-hyprland-0.3.3/tools.go 2024-11-16 01:19:11.000000000 +0100 @@ -26,10 +26,15 @@ return found } -func pinnedButton(ID string) *gtk.Box { +func pinnedButton(ID string, position *string) *gtk.Box { + vertical = *position == "left" || *position == "right" + box, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0) + if vertical { + box.SetOrientation(gtk.ORIENTATION_HORIZONTAL) + } + button, _ := gtk.ButtonNew() - box.PackStart(button, false, false, 0) image, err := createImage(ID, imgSizeScaled) if err != nil || image == nil { @@ -46,15 +51,6 @@ button.SetImagePosition(gtk.POS_TOP) button.SetAlwaysShowImage(true) button.SetTooltipText(getName(ID)) - pixbuf, err := gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-empty.svg"), - imgSizeScaled, imgSizeScaled/8) - var img *gtk.Image - if err == nil { - img, err = gtk.ImageNewFromPixbuf(pixbuf) - if err == nil { - box.PackStart(img, false, false, 0) - } - } button.Connect("clicked", func() { launch(ID) @@ -62,7 +58,7 @@ button.Connect("button-release-event", func(btn *gtk.Button, e *gdk.Event) bool { btnEvent := gdk.EventButtonNewFromEvent(e) - if btnEvent.Button() == 1 { + if btnEvent.Button() == 1 || btnEvent.Button() == 2 { launch(ID) return true } else if btnEvent.Button() == 3 { @@ -74,6 +70,27 @@ }) button.Connect("enter-notify-event", cancelClose) + + var pixbuf *gdk.Pixbuf + if !vertical { + pixbuf, err = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-empty.svg"), + imgSizeScaled, imgSizeScaled/8) + } else { + pixbuf, err = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-empty-vertical.svg"), + imgSizeScaled/8, imgSizeScaled) + } + + if err == nil { + img, _ := gtk.ImageNewFromPixbuf(pixbuf) + if *position == "left" || *position == "top" { + box.PackStart(img, false, false, 0) + box.PackStart(button, false, false, 0) + } else { + box.PackStart(button, false, false, 0) + box.PackStart(img, false, false, 0) + } + } + return box } @@ -89,6 +106,69 @@ return *menu } +func launcherButton(position *string) *gtk.Box { + vertical = *position == "left" || *position == "right" + + box, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0) + if vertical { + box.SetOrientation(gtk.ORIENTATION_HORIZONTAL) + } + + if !*noLauncher && *launcherCmd != "" { + button, _ := gtk.ButtonNew() + var pixbuf *gdk.Pixbuf + var e error + if *ico == "" { + pixbuf, e = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/grid.svg"), imgSizeScaled, imgSizeScaled) + } else { + pixbuf, e = createPixbuf(*ico, imgSizeScaled) + } + if e == nil { + image, _ := gtk.ImageNewFromPixbuf(pixbuf) + button.SetImage(image) + button.SetAlwaysShowImage(true) + + button.Connect("clicked", func() { + elements := strings.Split(*launcherCmd, " ") + cmd := exec.Command(elements[0], elements[1:]...) + + go func() { + err := cmd.Run() + if err != nil { + log.Warnf("Unable to start program: %s", err.Error()) + } + }() + + if *autohide { + win.Hide() + } + }) + button.Connect("enter-notify-event", cancelClose) + + if !vertical { + pixbuf, e = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-empty.svg"), + imgSizeScaled, imgSizeScaled/8) + } else { + pixbuf, e = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-empty-vertical.svg"), + imgSizeScaled/8, imgSizeScaled) + } + + if e == nil { + img, _ := gtk.ImageNewFromPixbuf(pixbuf) + if *position == "left" || *position == "top" { + box.PackStart(img, false, false, 0) + box.PackStart(button, false, false, 0) + } else { + box.PackStart(button, false, false, 0) + box.PackStart(img, false, false, 0) + } + } + } + return box + } + return nil +} + /* Window on-leave-notify event hides the dock with glib Timeout 1000 ms. We might have left the window by accident, so let's clear the timeout if window re-entered. @@ -102,15 +182,23 @@ } } -func taskButton(t client, instances []client) *gtk.Box { +func taskButton(t client, instances []client, position *string) *gtk.Box { + vertical = *position == "left" || *position == "right" + box, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0) + if vertical { + box.SetOrientation(gtk.ORIENTATION_HORIZONTAL) + } + button, _ := gtk.ButtonNew() - box.PackStart(button, false, false, 0) image, _ := createImage(t.Class, imgSizeScaled) if image == nil { + //var pixbuf *gdk.Pixbuf + //var err error pixbuf, err := gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/icon-missing.svg"), imgSizeScaled, imgSizeScaled) + if err == nil { image, _ = gtk.ImageNewFromPixbuf(pixbuf) } @@ -124,21 +212,45 @@ button.SetTooltipText(getName(t.Class)) var img *gtk.Image - if len(instances) < 2 { - pixbuf, err := gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-single.svg"), - imgSizeScaled, imgSizeScaled/8) - if err == nil { - img, _ = gtk.ImageNewFromPixbuf(pixbuf) + var pixbuf *gdk.Pixbuf + var err error + if len(instances) > 1 { + if !vertical { + pixbuf, err = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-multiple.svg"), + imgSizeScaled, imgSizeScaled/8) + } else { + pixbuf, err = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-multiple-vertical.svg"), + imgSizeScaled/8, imgSizeScaled) + } + } else if len(instances) == 1 { + if !vertical { + pixbuf, err = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-single.svg"), + imgSizeScaled, imgSizeScaled/8) + } else { + pixbuf, err = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-single-vertical.svg"), + imgSizeScaled/8, imgSizeScaled) } } else { - pixbuf, err := gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-multiple.svg"), - imgSizeScaled, imgSizeScaled/8) - if err == nil { - img, _ = gtk.ImageNewFromPixbuf(pixbuf) + if !vertical { + pixbuf, err = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-empty.svg"), + imgSizeScaled, imgSizeScaled/8) + } else { + pixbuf, err = gdk.PixbufNewFromFileAtSize(filepath.Join(dataHome, "nwg-dock-hyprland/images/task-empty-vertical.svg"), + imgSizeScaled/8, imgSizeScaled) } } + if err == nil { + img, _ = gtk.ImageNewFromPixbuf(pixbuf) + } if img != nil { - box.PackStart(img, false, false, 0) + if *position == "left" || *position == "top" { + box.PackStart(img, false, false, 0) + box.PackStart(button, false, false, 0) + } else { + box.PackStart(button, false, false, 0) + box.PackStart(img, false, false, 0) + } + } button.Connect("enter-notify-event", cancelClose) @@ -161,6 +273,9 @@ log.Debugf("%s -> %s", cmd, reply) return true + } else if btnEvent.Button() == 2 { + launch(t.Class) + return true } else if btnEvent.Button() == 3 { contextMenu := clientMenuContext(t.Class, instances) contextMenu.PopupAtWidget(button, widgetAnchor, menuAnchor, nil) @@ -176,6 +291,9 @@ menu := clientMenu(t.Class, instances) menu.PopupAtWidget(button, widgetAnchor, menuAnchor, nil) return true + } else if btnEvent.Button() == 2 { + launch(t.Class) + return true } else if btnEvent.Button() == 3 { contextMenu := clientMenuContext(t.Class, instances) contextMenu.PopupAtWidget(button, widgetAnchor, menuAnchor, nil) @@ -310,6 +428,18 @@ }) menu.Append(item) + closeAllWindows, _ := gtk.MenuItemNew() + closeAllWindows.SetLabel("Close all windows") + closeAllWindows.Connect("activate", func() { + for _, instance := range instances { + address := instance.Address + cmd := fmt.Sprintf("dispatch closewindow address:%s", address) + reply, _ := hyprctl(cmd) + log.Infof("%s -> %s", cmd, reply) + } + }) + menu.Append(closeAllWindows) + pinItem, _ := gtk.MenuItemNew() if !inPinned(class) { pinItem.SetLabel("Pin") @@ -593,7 +723,6 @@ b4Separator = strings.Split(badAppID, " ")[0] for _, d := range appDirs { items, _ := os.ReadDir(d) - log.Info(">>>", items) // first look for exact 'class.desktop' file, see #31 for _, item := range items { @@ -727,6 +856,7 @@ func unpinTask(itemID string) { pinned = remove(pinned, itemID) savePinned() + buildMainBox() } func remove(s []string, r string) []string { ++++++ vendor.tar.zst ++++++ ++++ 4151 lines of diff (skipped)
