mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 18:05:35 +00:00
app: [macOS] propagate unhandled key shortcuts
By propagation, we restore the system behaviour for shortcuts the program don't want, for example the system beep. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+49
-22
@@ -354,9 +354,14 @@ type window struct {
|
|||||||
config Config
|
config Config
|
||||||
|
|
||||||
keysDown map[key.Name]struct{}
|
keysDown map[key.Name]struct{}
|
||||||
// doCommandBySelectorCalled tracks whether a call to
|
// cmdKeys is for storing the current key event while
|
||||||
// interpretKeys resulted in a callback.
|
// waiting for a doCommandBySelector.
|
||||||
doCommandBySelectorCalled bool
|
cmdKeys cmdKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
type cmdKeys struct {
|
||||||
|
eventStr string
|
||||||
|
eventMods key.Modifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
// launched is closed when applicationDidFinishLaunching is called.
|
// launched is closed when applicationDidFinishLaunching is called.
|
||||||
@@ -558,47 +563,64 @@ func (w *window) runOnMain(f func()) {
|
|||||||
//export gio_onKeys
|
//export gio_onKeys
|
||||||
func gio_onKeys(h C.uintptr_t, event C.CFTypeRef, cstr C.CFTypeRef, ti C.double, mods C.NSUInteger, keyDown C.bool) {
|
func gio_onKeys(h C.uintptr_t, event C.CFTypeRef, cstr C.CFTypeRef, ti C.double, mods C.NSUInteger, keyDown C.bool) {
|
||||||
w := windowFor(h)
|
w := windowFor(h)
|
||||||
|
if w.keysDown == nil {
|
||||||
|
w.keysDown = make(map[key.Name]struct{})
|
||||||
|
}
|
||||||
str := nsstringToString(cstr)
|
str := nsstringToString(cstr)
|
||||||
kmods := convertMods(mods)
|
kmods := convertMods(mods)
|
||||||
ks := key.Release
|
ks := key.Release
|
||||||
if keyDown {
|
if keyDown {
|
||||||
ks = key.Press
|
ks = key.Press
|
||||||
w.doCommandBySelectorCalled = false
|
w.cmdKeys.eventStr = str
|
||||||
|
w.cmdKeys.eventMods = kmods
|
||||||
C.interpretKeyEvents(w.view, event)
|
C.interpretKeyEvents(w.view, event)
|
||||||
}
|
}
|
||||||
for _, k := range str {
|
for _, k := range str {
|
||||||
if n, ok := convertKey(k); ok {
|
if n, ok := convertKey(k); ok {
|
||||||
|
ke := key.Event{
|
||||||
|
Name: n,
|
||||||
|
Modifiers: kmods,
|
||||||
|
State: ks,
|
||||||
|
}
|
||||||
if keyDown {
|
if keyDown {
|
||||||
if !w.doCommandBySelectorCalled {
|
w.keysDown[ke.Name] = struct{}{}
|
||||||
if _, isCmd := convertCommandKey(k); isCmd {
|
if _, isCmd := convertCommandKey(k); isCmd || kmods.Contain(key.ModCommand) {
|
||||||
// doCommandBySelector was not called,
|
// doCommandBySelector already processed the event.
|
||||||
// so this event was swallowed by an IME.
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if w.keysDown == nil {
|
|
||||||
w.keysDown = make(map[key.Name]struct{})
|
|
||||||
}
|
|
||||||
w.keysDown[n] = struct{}{}
|
|
||||||
} else {
|
} else {
|
||||||
if _, pressed := w.keysDown[n]; !pressed {
|
if _, pressed := w.keysDown[n]; !pressed {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
delete(w.keysDown, n)
|
delete(w.keysDown, n)
|
||||||
}
|
}
|
||||||
w.ProcessEvent(key.Event{
|
w.ProcessEvent(ke)
|
||||||
Name: n,
|
|
||||||
Modifiers: kmods,
|
|
||||||
State: ks,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onCommandBySelector
|
//export gio_onCommandBySelector
|
||||||
func gio_onCommandBySelector(h C.uintptr_t) {
|
func gio_onCommandBySelector(h C.uintptr_t) C.bool {
|
||||||
w := windowFor(h)
|
w := windowFor(h)
|
||||||
w.doCommandBySelectorCalled = true
|
ev := w.cmdKeys
|
||||||
|
w.cmdKeys = cmdKeys{}
|
||||||
|
handled := false
|
||||||
|
for _, k := range ev.eventStr {
|
||||||
|
n, ok := convertCommandKey(k)
|
||||||
|
if !ok && ev.eventMods.Contain(key.ModCommand) {
|
||||||
|
n, ok = convertKey(k)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ke := key.Event{
|
||||||
|
Name: n,
|
||||||
|
Modifiers: ev.eventMods,
|
||||||
|
State: key.Press,
|
||||||
|
}
|
||||||
|
handled = w.processEvent(ke) || handled
|
||||||
|
}
|
||||||
|
return C.bool(handled)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onFlagsChanged
|
//export gio_onFlagsChanged
|
||||||
@@ -905,8 +927,13 @@ func (w *window) draw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) ProcessEvent(e event.Event) {
|
func (w *window) ProcessEvent(e event.Event) {
|
||||||
w.w.ProcessEvent(e)
|
w.processEvent(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *window) processEvent(e event.Event) bool {
|
||||||
|
handled := w.w.ProcessEvent(e)
|
||||||
w.loop.FlushEvents()
|
w.loop.FlushEvents()
|
||||||
|
return handled
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) Event() event.Event {
|
func (w *window) Event() event.Event {
|
||||||
|
|||||||
+3
-1
@@ -147,7 +147,9 @@ static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFl
|
|||||||
gio_onText(self.handle, (__bridge CFTypeRef)string);
|
gio_onText(self.handle, (__bridge CFTypeRef)string);
|
||||||
}
|
}
|
||||||
- (void)doCommandBySelector:(SEL)action {
|
- (void)doCommandBySelector:(SEL)action {
|
||||||
gio_onCommandBySelector(self.handle);
|
if (!gio_onCommandBySelector(self.handle)) {
|
||||||
|
[super doCommandBySelector:action];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
- (BOOL)hasMarkedText {
|
- (BOOL)hasMarkedText {
|
||||||
int res = gio_hasMarkedText(self.handle);
|
int res = gio_hasMarkedText(self.handle);
|
||||||
|
|||||||
Reference in New Issue
Block a user