Update from upstream by squashing

commit 6172ea4fdf435d7125697d40af2c17ae5ff3a8c6
Author: Shuhei Kubota <kubota.shuhei+github@gmail.com>
Date:   Sat Nov 4 15:30:11 2023 +0900

    build: same config as csv2xlsx

commit 6c522e8ca857f7218db476153ffd06e8b7d2bdde
Author: Shuhei Kubota <kubota.shuhei+github@gmail.com>
Date:   Sat Nov 4 15:11:53 2023 +0900

    change: debug output

commit 4cec3963cdc20c781bbacde8be927591145b95ca
Author: Shuhei Kubota <kubota.shuhei+github@gmail.com>
Date:   Sat Nov 4 15:10:26 2023 +0900

    chore: use gli/v2

commit 958c93d6256bbb4611f21f870087c074a783001b
Author: Shuhei Kubota <kubota.shuhei+github@gmail.com>
Date:   Fri Nov 3 20:45:57 2023 +0900

    fix(alpha): improve output, variable name

commit 8bc79c6bd2c4a93c087e8fea7c2e306e7028466c
Author: Shuhei Kubota <kubota.shuhei+github@gmail.com>
Date:   Fri Nov 3 20:18:34 2023 +0900

    refactor: remove unused code

commit 7a14926dd7f83dd6a41f3baa6c905b7c81191a93
Author: Shuhei Kubota <kubota.shuhei+github@gmail.com>
Date:   Fri Nov 3 20:18:59 2023 +0900

    build: go 1.21

commit 40007434e6fdbc3ad485862b3d2785d7ba7263a8
Author: Shuhei Kubota <kubota.shuhei+github@gmail.com>
Date:   Fri Nov 3 20:18:15 2023 +0900

    fix: call cancel finally

commit 5b02edacd34942adedf38d089737d3c8130d52e3
Author: Shuhei Kubota <kubota.shuhei+github@gmail.com>
Date:   Fri Nov 3 20:16:34 2023 +0900

    fix: typo
This commit is contained in:
Evan 2024-04-04 10:49:31 -04:00
parent e8feb8401f
commit a839fe4655
6 changed files with 87 additions and 62 deletions

View file

@ -5,8 +5,9 @@ package vvin
import (
"errors"
"os"
"github.com/shu-go/rog"
"github.com/shu-go/nmfmt"
)
type alphaCmd struct {
@ -14,19 +15,22 @@ type alphaCmd struct {
func (c alphaCmd) Run(args []string, g globalCmd) error {
if len(args) != 1 {
return errors.New("an argument is required")
return errors.New("an argument (opacity; 0%-100% or 0-255) is required")
}
alpha := toInt(args[0], 255)
if g.Debug {
rog.Printf("alpha = %v -> %v", args[0], alpha)
}
opacity := toInt(args[0], 255)
g.debug(os.Stderr, "opacity $=arg:q -> $opacity/255\n",
nmfmt.M{
"arg": args[0],
"opacity": opacity,
})
style, _, _ := getWindowLong.Call(uintptr(g.targetHandle), gwlEXStyle)
setWindowLong.Call(uintptr(g.targetHandle), gwlEXStyle, style|wsEXLayered)
setLayeredWindowAttributes.Call(uintptr(g.targetHandle), 0, uintptr(alpha), lwaAlpha)
if alpha == 255 {
setLayeredWindowAttributes.Call(uintptr(g.targetHandle), 0, uintptr(opacity), lwaAlpha)
if opacity == 255 {
setWindowLong.Call(uintptr(g.targetHandle), gwlEXStyle, style&^wsEXLayered)
}

View file

@ -5,9 +5,10 @@ package vvin
import (
"errors"
"os"
"unsafe"
"github.com/shu-go/rog"
"github.com/shu-go/nmfmt"
)
type resizeCmd struct {
@ -32,9 +33,11 @@ func (c *resizeCmd) Before(g globalCmd) error {
oldrect := c.rect
if g.Debug {
rog.Print(oldrect)
}
g.debug(os.Stderr, "$=original\n",
nmfmt.M{
"original": oldrect,
})
if c.Left != "" {
c.rect.Left = toInt(c.Left, g.scrWidth)
}
@ -51,12 +54,11 @@ func (c *resizeCmd) Before(g globalCmd) error {
} else {
c.rect.Bottom = c.rect.Top + (oldrect.Bottom - oldrect.Top)
}
if g.Debug {
if c.Restore {
rog.Print("restore")
} else {
rog.Print(c.rect)
}
if c.Restore {
g.debug(os.Stderr, "restore\n")
} else {
g.debug(os.Stderr, "resized $rect\n", nmfmt.M{"rect": c.rect})
}
return nil

View file

@ -12,16 +12,14 @@ import (
"strings"
"syscall"
"time"
"github.com/shu-go/gli"
)
type waitCmd struct {
_ struct{} `help:"[--close] {Title}"`
Closed bool `help:"wait until the window is closed"`
Interval gli.Duration `cli:"interval,i=DURATION" default:"1s"`
Timeout gli.Duration `cli:"timeout=DURATION" default:"0s" help:"zelo value means ininite"`
Closed bool `help:"wait until the window is closed"`
Interval time.Duration `cli:"interval,i=DURATION" default:"1s"`
Timeout time.Duration `cli:"timeout=DURATION" default:"0s" help:"zero value means ininite"`
}
func (c waitCmd) Run(args []string) error {
@ -33,10 +31,13 @@ func (c waitCmd) Run(args []string) error {
t := strings.ToLower(args[0])
var ctx context.Context
var cancel func()
if c.Timeout == 0 {
ctx = context.Background()
cancel = func() {}
} else {
ctx, _ = context.WithTimeout(context.Background(), c.Timeout.Duration())
ctx, cancel = context.WithTimeout(context.Background(), c.Timeout)
}
signalChan := make(chan os.Signal, 1)
@ -48,6 +49,7 @@ waitLoop:
for {
wins, err := listAllWindows()
if err != nil {
cancel()
return err
}
@ -67,14 +69,15 @@ waitLoop:
fmt.Fprintln(os.Stderr, "cancelled")
break waitLoop
case <-ctx.Done():
fmt.Fprintln(os.Stderr, "cancelled")
fmt.Fprintln(os.Stderr, "cancelled (timeout)")
break waitLoop
default:
//nop
}
time.Sleep(c.Interval.Duration())
time.Sleep(c.Interval)
}
cancel()
return nil
}

15
go.mod
View file

@ -1,9 +1,16 @@
module git.bigun.dev/evan/vvin
module github.com/shu-go/vvin
go 1.13
go 1.21
require (
github.com/mitchellh/go-ps v1.0.0
github.com/shu-go/gli v1.5.7
github.com/shu-go/rog v0.1.0
github.com/shu-go/gli/v2 v2.0.1
github.com/shu-go/nmfmt v0.1.0
)
require (
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/shu-go/cliparser v0.2.2 // indirect
)

25
go.sum
View file

@ -1,22 +1,17 @@
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b h1:9+ke9YJ9KGWw5ANXK6ozjoK47uI3uNbXv4YVINBnGm8=
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/shu-go/cliparser v0.2.1 h1:09Nqe/SBmHr00DAQM3JxkVnSCBkGf8P5+7EtHWVndh0=
github.com/shu-go/cliparser v0.2.1/go.mod h1:oX+xgwUi9B2OzBFudKc5ayoqWhlVAbuN67rAqyWvvQ4=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/shu-go/cliparser v0.2.2 h1:EONHyGHC+9l2mukTBNsxvngXro73T22kXb+agVFd0CY=
github.com/shu-go/cliparser v0.2.2/go.mod h1:oX+xgwUi9B2OzBFudKc5ayoqWhlVAbuN67rAqyWvvQ4=
github.com/shu-go/clise v0.0.0-20190822023516-79849fb81cfe/go.mod h1:VLiMEzXMBozBLD37i3id3qPflaupus48v/979ipQ43s=
github.com/shu-go/gli v1.5.2 h1:sn15ZBwgy3cAhMQc3+5IhTzCZxi3kuESVPfP3D7qJ8E=
github.com/shu-go/gli v1.5.2/go.mod h1:3m4JxIHbLp5yx2LgyKOj8cqN2IcJC0slhZB6mewmlvI=
github.com/shu-go/gli v1.5.7/go.mod h1:WZSG6NFYr/1rwT2F3Oms0gWyklvjJNDW6qvBfZ/tM4U=
github.com/shu-go/gli/v2 v2.0.1 h1:XA1QSfUdpWW1FIqLjuXo+Gs/IjEy+uviuxKQ45IRYC8=
github.com/shu-go/gli/v2 v2.0.1/go.mod h1:pSC0XKb69hEarQpiQU74CNiKpcS7a90iJAMUGL3SinQ=
github.com/shu-go/gotwant v0.0.0-20190920074605-b4f19c0bac91 h1:nwDc3kHbf9scf1UZIWiWw5tZF3Z4yOJAMjNN+kYXJwE=
github.com/shu-go/gotwant v0.0.0-20190920074605-b4f19c0bac91/go.mod h1:FZepfqvib0mXjHiaQPTv0RUD5QMpMA/FHLfBQjZRRQg=
github.com/shu-go/rog v0.1.0 h1:mplglNOiUN1ujq0UTkosB5NL/GQhFX2gRYcen7aEhTY=
github.com/shu-go/rog v0.1.0/go.mod h1:gO+FpqgnHoxbF6FPJN6PaAEl6hcZRLNL+nQZgbbElzo=
github.com/shu-go/nmfmt v0.1.0 h1:gL5u0yiIsegh2gofeNUpAJPWCNgOF+qIivBc9qO/KoE=
github.com/shu-go/nmfmt v0.1.0/go.mod h1:ulgNf0sfuQEEdX2cM71sGviSEKDf9DUXlm5WtFn0PJY=

48
vvin.go
View file

@ -1,11 +1,9 @@
//go:build windows
// +build windows
package vvin
package main
import (
"errors"
"fmt"
"io"
"math"
"os"
"strconv"
@ -14,13 +12,19 @@ import (
"unsafe"
"github.com/mitchellh/go-ps"
"github.com/shu-go/gli"
"github.com/shu-go/gli/v2"
"github.com/shu-go/nmfmt"
)
// Version is app version
var Version string
type globalCmd struct {
Target string `cli:"target,t=WINDOW_TITLE" help:"default to current window"`
Debug bool `help:"output debug info"`
debug func(io.Writer, string, ...any) (int, error) // nmfmt
Minimize minCmd `cli:"minimize,min" help:"minimize/restore"`
Maximize maxCmd `cli:"maximize,max" help:"maximize/restore"`
Resize resizeCmd `cli:"resize,move,mv" help:"resize/move"`
@ -30,11 +34,18 @@ type globalCmd struct {
targetHandle syscall.Handle
scrWidth, scrHeight int
frameWidth, frameHeight int
scrWidth, scrHeight int
}
func (c *globalCmd) Before() error {
c.debug = func(io.Writer, string, ...any) (int, error) {
return 0, nil
}
if c.Debug {
c.debug = nmfmt.Fprintf
}
c.debug(os.Stderr, "Debug enabled.\n")
wins, err := listAllWindows()
if err != nil {
return err
@ -46,6 +57,12 @@ func (c *globalCmd) Before() error {
}
c.targetHandle = win.Handle
c.debug(os.Stderr, "$=target:q -> $=handle:x\n",
nmfmt.M{
"target": c.Target,
"handle": c.targetHandle,
})
w, _, _ := getSystemMetrics.Call(smCXVirtualScreen)
h, _, _ := getSystemMetrics.Call(smCYVirtualScreen)
c.scrWidth = int(w)
@ -54,15 +71,17 @@ func (c *globalCmd) Before() error {
return nil
}
func Start(args []string) error {
func main() {
app := gli.NewWith(&globalCmd{})
app.Name = "vvin"
app.Desc = "Change window properties for Windows"
app.Version = "0.8.0"
app.Version = Version
app.Usage = ``
app.Copyright = "(C) 2019 Shuhei Kubota"
app.SuppressErrorOutput = true
return app.Run(args)
if err := app.Run(os.Args); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
var (
@ -112,8 +131,8 @@ const (
hwndTopmost = ^uintptr(0)
hwndNoTopmost = ^uintptr(1)
spiGetAnimation = 0x0048
spiSetAnimation = 0x0049
//spiGetAnimation = 0x0048
//spiSetAnimation = 0x0049
)
type (
@ -126,11 +145,6 @@ type (
rect struct {
Left, Top, Right, Bottom int32
}
anmationinfo struct {
Size uint32
Animate int32
}
)
func listAllWindows() (wins []*window, err error) {