Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for global hotkeys + example #228

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
* eol=lf

*.cmd eol=crlf
*.bat eol=crlf

*.syso binary
*.gif binary
*.png binary
*.jpg binary
*.ico binary
*.zip binary
*.ttf binary
*.otf binary
*.woff binary
*.eot binary
*.pdf binary
50 changes: 50 additions & 0 deletions examples/globalhotkey/globalhotkey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"github.com/lxn/walk"
. "github.com/lxn/walk/declarative"
)

func main() {

var (
e error
winMain *walk.MainWindow
label *walk.Label
)

winMain, e = walk.NewMainWindow()
if e != nil { panic(e) }

// Define hotkey handler
winMain.Hotkey().Attach(func(hkid int) {
label.SetText("")
switch hkid {
case 1:
label.SetText("Global hotkey 1 pressed: Ctrl+Alt+X")
case 2:
label.SetText("Global hotkey 2 pressed: Alt+Shift+D")
}
})

// Register hotkeys globally
walk.RegisterGlobalHotKey(winMain, 1, walk.Shortcut{Modifiers: walk.ModControl | walk.ModAlt, Key: walk.KeyX})
walk.RegisterGlobalHotKey(winMain, 2, walk.Shortcut{Modifiers: walk.ModShift | walk.ModAlt, Key: walk.KeyD})

MainWindow {
AssignTo: &winMain,
Size: Size{400, 120},
Layout: VBox{},
Children: []Widget {
Label {
Text: "Focus on another window and press Ctrl+Alt+X or Alt+Shift+D",
},
Label {
AssignTo: &label,
Text: "-",
Font: Font{PointSize: 12},
},
},
}.Run()

}
14 changes: 14 additions & 0 deletions examples/globalhotkey/globalhotkey.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
Binary file added examples/globalhotkey/rsrc.syso
Binary file not shown.
32 changes: 32 additions & 0 deletions globalhotkey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build windows

package walk

import (
"github.com/lxn/win"
)

func RegisterGlobalHotKey(owner Form, hkid int, hKey Shortcut) bool {
var ownerHWnd win.HWND

if owner != nil {
ownerHWnd = owner.Handle()
}

var modifiers uint
if hKey.Modifiers & ModAlt != 0 {
modifiers |= 1
}
if hKey.Modifiers & ModControl != 0 {
modifiers |= 2
}
if hKey.Modifiers & ModShift != 0 {
modifiers |= 4
}
// https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms646309.aspx
return win.RegisterHotKey(ownerHWnd, hkid, modifiers, uint(hKey.Key))
}
45 changes: 45 additions & 0 deletions hotkeyevent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2011 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build windows

package walk

type HotkeyEventHandler func(hkid int)

type HotkeyEvent struct {
handlers []HotkeyEventHandler
}

func (e *HotkeyEvent) Attach(handler HotkeyEventHandler) int {
for i, h := range e.handlers {
if h == nil {
e.handlers[i] = handler
return i
}
}

e.handlers = append(e.handlers, handler)
return len(e.handlers) - 1
}

func (e *HotkeyEvent) Detach(handle int) {
e.handlers[handle] = nil
}

type HotkeyEventPublisher struct {
event HotkeyEvent
}

func (p *HotkeyEventPublisher) Event() *HotkeyEvent {
return &p.event
}

func (p *HotkeyEventPublisher) Publish(hkid int) {
for _, handler := range p.event.handlers {
if handler != nil {
handler(hkid)
}
}
}
20 changes: 19 additions & 1 deletion window.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,11 @@ type Window interface {
// events for the Window.
KeyUp() *KeyEvent

// MaxSize returns the maximum allowed outer size for the Window, including
// Hotkey returns a *HotkeyEvent that you can attach to for handling global
// hotkey events for the Window.
Hotkey() *HotkeyEvent

// MaxSize returns the maximum allowed outer Size for the Window, including
// decorations.
//
// For child windows, this is only relevant when the parent of the Window
Expand Down Expand Up @@ -419,6 +423,7 @@ type WindowBase struct {
keyDownPublisher KeyEventPublisher
keyPressPublisher KeyEventPublisher
keyUpPublisher KeyEventPublisher
hotkeyPublisher HotkeyEventPublisher
mouseDownPublisher MouseEventPublisher
mouseUpPublisher MouseEventPublisher
mouseMovePublisher MouseEventPublisher
Expand Down Expand Up @@ -2004,6 +2009,12 @@ func (wb *WindowBase) KeyUp() *KeyEvent {
return wb.keyUpPublisher.Event()
}

// Hotkey returns a *HotkeyEvent that you can attach to for handling global
// hotkey events for the *WindowBase.
func (wb *WindowBase) Hotkey() *HotkeyEvent {
return wb.hotkeyPublisher.Event()
}

// DropFiles returns a *DropFilesEvent that you can attach to for handling
// drop file events for the *WindowBase.
func (wb *WindowBase) DropFiles() *DropFilesEvent {
Expand Down Expand Up @@ -2216,6 +2227,10 @@ func (wb *WindowBase) handleKeyUp(wParam, lParam uintptr) {
wb.keyUpPublisher.Publish(Key(wParam))
}

func (wb *WindowBase) handleHotkey(wParam, lParam uintptr) {
wb.hotkeyPublisher.Publish(int(wParam))
}

func (wb *WindowBase) backgroundEffective() (Brush, Window) {
wnd := wb.window
bg := wnd.Background()
Expand Down Expand Up @@ -2460,6 +2475,9 @@ func (wb *WindowBase) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr)
case win.WM_KEYUP:
wb.handleKeyUp(wParam, lParam)

case win.WM_HOTKEY:
wb.handleHotkey(wParam, lParam)

case win.WM_DROPFILES:
wb.dropFilesPublisher.Publish(win.HDROP(wParam))

Expand Down