Skip to content

Commit

Permalink
feat: Add support for multiple alternate resolutions.
Browse files Browse the repository at this point in the history
  • Loading branch information
sathya-pramodh committed Feb 20, 2024
1 parent d22d6ad commit 63f3da9
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 10 deletions.
35 changes: 35 additions & 0 deletions internal/cfg/binds.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ type Bind struct {
str string
}

// AltRes represents a list of alternate resolutions.
type AltRes []Rectangle

// UnmarshalTOML implements toml.Unmarshaler.
func (a *ActionList) UnmarshalTOML(value any) error {
actionsRaw, ok := value.([]any)
Expand Down Expand Up @@ -110,6 +113,9 @@ func (a *ActionList) UnmarshalTOML(value any) error {
if typ >= ActionWallLock && typ <= ActionWallResetOthers {
a.WallActions = append(a.WallActions, Action{typ, &num})
uniqueWall[Action{typ, &num}] = true
} else if typ == ActionIngameRes {
a.IngameActions = append(a.IngameActions, Action{typ, &num})
uniqueGame[Action{typ, &num}] = true
} else {
return fmt.Errorf("action %q cannot have number", actionStr)
}
Expand Down Expand Up @@ -177,6 +183,35 @@ func (b *Bind) UnmarshalTOML(value any) error {
return nil
}

// UnmarshalTOML implements toml.Unmarshaler.
func (a *AltRes) UnmarshalTOML(value any) error {
str, ok := value.(string)
if !ok {
resListRaw, ok := value.([]any)
if !ok {
return errors.New("parse alt_res as a single resolution or a list of resolutions")
}
for _, raw := range resListRaw {
var res Rectangle
resStr, ok := raw.(string)
if !ok {
return errors.New("parse alt_res as a list of resolutions")
}
if err := res.UnmarshalTOML(resStr); err != nil {
return fmt.Errorf("parse alternate resolution: %w", err)
}
*a = append(*a, res)
}
} else {
var res Rectangle
if err := res.UnmarshalTOML(str); err != nil {
return fmt.Errorf("parse alternate resolution: %w", err)
}
*a = append(*a, res)
}
return nil
}

// UnmarshalTOML implements toml.Unmarshaler.
func (k *Keybinds) UnmarshalTOML(value any) error {
m, ok := value.(map[string]any)
Expand Down
8 changes: 5 additions & 3 deletions internal/cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ type Profile struct {
UnpauseFocus bool `toml:"unpause_focus"` // Whether to unpause on focus
PollRate int `toml:"poll_rate"` // Polling rate for input handling
NormalRes *Rectangle `toml:"play_res"` // Normal resolution
AltRes *Rectangle `toml:"alt_res"` // Alternate ingame resolution
AltRes AltRes `toml:"alt_res"` // Alternate ingame resolution

Delay Delays `toml:"delay"`
Hooks Hooks `toml:"hooks"`
Expand Down Expand Up @@ -279,8 +279,10 @@ func validateProfile(conf *Profile) error {
if !validateRectangle(conf.NormalRes) {
return errors.New("invalid playing resolution")
}
if !validateRectangle(conf.AltRes) {
return errors.New("invalid alternate resolution")
for idx, res := range conf.AltRes {
if !validateRectangle(&res) {
return fmt.Errorf("invalid alternate resolution at index %d", idx)
}
}
alt := conf.AltRes != nil
normal := conf.NormalRes != nil
Expand Down
4 changes: 2 additions & 2 deletions internal/ctl/ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,8 @@ func (c *Controller) FocusInstance(id int) {

// ToggleResolution switches the given instance between the normal and alternate
// resolution.
func (c *Controller) ToggleResolution(id int) {
if c.manager.ToggleResolution(id) {
func (c *Controller) ToggleResolution(id int, resId int) {
if c.manager.ToggleResolution(id, resId) {
c.RunHook(HookAltRes)
} else {
c.RunHook(HookNormalRes)
Expand Down
10 changes: 9 additions & 1 deletion internal/ctl/moving.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,15 @@ func (m *MovingWall) Input(input Input) {
case cfg.ActionIngameFocus:
m.host.FocusInstance(m.active)
case cfg.ActionIngameRes:
m.host.ToggleResolution(m.active)
if action.Extra != nil {
resId := *action.Extra
if resId < 0 || resId > len(m.conf.AltRes)-1 {
continue
}
m.host.ToggleResolution(m.active, resId)
} else {
m.host.ToggleResolution(m.active, 0)
}
}
}
} else {
Expand Down
10 changes: 9 additions & 1 deletion internal/ctl/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,15 @@ func (m *Multi) Input(input Input) {
m.host.RunHook(HookReset)
}
case cfg.ActionIngameRes:
m.host.ToggleResolution(m.active)
if action.Extra != nil {
resId := *action.Extra
if resId < 0 || resId > len(m.conf.AltRes)-1 {
continue
}
m.host.ToggleResolution(m.active, resId)
} else {
m.host.ToggleResolution(m.active, 0)
}
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion internal/ctl/wall.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,15 @@ func (w *Wall) Input(input Input) {
case cfg.ActionIngameFocus:
w.host.FocusInstance(w.active)
case cfg.ActionIngameRes:
w.host.ToggleResolution(w.active)
if action.Extra != nil {
resId := *action.Extra
if resId < 0 || resId > len(w.conf.AltRes)-1 {
continue
}
w.host.ToggleResolution(w.active, resId)
} else {
w.host.ToggleResolution(w.active, 0)
}
}
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions internal/mc/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,11 @@ func (m *Manager) Focus(id int) {

// ToggleResolution switches the given instance between the normal and alternate
// resolution and returns whether or not it is now on the alternate resolution.
func (m *Manager) ToggleResolution(id int) bool {
func (m *Manager) ToggleResolution(id int, resId int) bool {
if m.instances[id].altRes {
m.setResolution(id, m.conf.NormalRes)
} else {
m.setResolution(id, m.conf.AltRes)
m.setResolution(id, &m.conf.AltRes[resId])
}
m.instances[id].altRes = !m.instances[id].altRes
m.Focus(id)
Expand Down
3 changes: 3 additions & 0 deletions internal/res/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ play_res = "1920x1080+0,0"

# An alternate resolution that can be toggled to while ingame. Delete this if
# you do not want to use e.g. thin or tall window.
# You can even declare this as a list of resolutions.
# Eg: alt_res = ["400x1080+810,0", "1920x300+0,390"]
alt_res = "400x1080+810,0"

# The delay section contains delays (in milliseconds) before performing various
Expand Down Expand Up @@ -82,6 +84,7 @@ wall_reset = ""
# - ingame_focus Focus active instance.
# - ingame_reset Reset active instance.
# - ingame_toggle_res Toggle the resolution for active instance.
# - ingame_toggle_res(n) Toggle the resolution N for active instance.
# - wall_focus Focus wall projector.
# - wall_reset_all Reset all unlocked instances.
# - wall_lock Lock hovered instance.
Expand Down

0 comments on commit 63f3da9

Please sign in to comment.