layout,io/input: move disabling events from layout.Context to input.Source

The fix for #605 moved the disabling of event delivery from Source
to Context to enable disabled Contexts to still react to commands
(invalidate, focus etc.). However, that change in turn caused #641 where
the exported Context.Source field would no longer know not to deliver
events.

This change partially reverts the fix for #605 by moving disabledness
back to Source, fixing #641. Disabled Sources are left capable of
executing commands, thus keeping #605 fixed.

Thanks to Chris et al for keeping the use-cases straight enough for me
to come up with this (hopefully final) fix.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
Fixes: https://todo.sr.ht/~eliasnaur/gio/641
References: https://todo.sr.ht/~eliasnaur/gio/605
This commit is contained in:
Elias Naur
2025-03-24 08:45:51 +01:00
parent 72a72a2bc2
commit fff2375470
2 changed files with 18 additions and 24 deletions
+17 -8
View File
@@ -62,7 +62,8 @@ type Router struct {
// Source implements the interface between a Router and user interface widgets. // Source implements the interface between a Router and user interface widgets.
// The zero-value Source is disabled. // The zero-value Source is disabled.
type Source struct { type Source struct {
r *Router r *Router
disabled bool
} }
// Command represents a request such as moving the focus, or initiating a clipboard read. // Command represents a request such as moving the focus, or initiating a clipboard read.
@@ -171,30 +172,38 @@ func (q *Router) Source() Source {
// Execute a command. // Execute a command.
func (s Source) Execute(c Command) { func (s Source) Execute(c Command) {
if !s.enabled() { if !s.Enabled() {
return return
} }
s.r.execute(c) s.r.execute(c)
} }
// enabled reports whether the source is enabled. Only enabled // Disabled returns a copy of this source that don't deliver any events.
// Sources deliver events and respond to commands. func (s Source) Disabled() Source {
func (s Source) enabled() bool { s2 := s
return s.r != nil s2.disabled = true
return s2
}
// Enabled reports whether the source is enabled. Only enabled
// Sources deliver events.
func (s Source) Enabled() bool {
return s.r != nil && !s.disabled
} }
// Focused reports whether tag is focused, according to the most recent // Focused reports whether tag is focused, according to the most recent
// [key.FocusEvent] delivered. // [key.FocusEvent] delivered.
func (s Source) Focused(tag event.Tag) bool { func (s Source) Focused(tag event.Tag) bool {
if !s.enabled() { if !s.Enabled() {
return false return false
} }
return s.r.state().keyState.focus == tag return s.r.state().keyState.focus == tag
} }
// Event returns the next event that matches at least one of filters. // Event returns the next event that matches at least one of filters.
// If the source is disabled, no events will be reported.
func (s Source) Event(filters ...event.Filter) (event.Event, bool) { func (s Source) Event(filters ...event.Filter) (event.Event, bool) {
if !s.enabled() { if !s.Enabled() {
return nil, false return nil, false
} }
return s.r.Event(filters...) return s.r.Event(filters...)
+1 -16
View File
@@ -5,7 +5,6 @@ package layout
import ( import (
"time" "time"
"gioui.org/io/event"
"gioui.org/io/input" "gioui.org/io/input"
"gioui.org/io/system" "gioui.org/io/system"
"gioui.org/op" "gioui.org/op"
@@ -29,7 +28,6 @@ type Context struct {
// Interested users must look up and populate these values manually. // Interested users must look up and populate these values manually.
Locale system.Locale Locale system.Locale
disabled bool
input.Source input.Source
*op.Ops *op.Ops
} }
@@ -44,21 +42,8 @@ func (c Context) Sp(v unit.Sp) int {
return c.Metric.Sp(v) return c.Metric.Sp(v)
} }
func (c Context) Event(filters ...event.Filter) (event.Event, bool) {
if c.disabled {
return nil, false
}
return c.Source.Event(filters...)
}
// Enabled reports whether this context is enabled. Disabled contexts
// don't report events.
func (c Context) Enabled() bool {
return !c.disabled
}
// Disabled returns a copy of this context that don't deliver any events. // Disabled returns a copy of this context that don't deliver any events.
func (c Context) Disabled() Context { func (c Context) Disabled() Context {
c.disabled = true c.Source = c.Source.Disabled()
return c return c
} }