fix: use structured logging for debug/info methods (#4767)

* fix: use structured logging for debug/info methods

The debug() and info() methods were using fmt.Sprintf() which expects
printf-style format directives, but callers were using slog-style
key-value pairs. Changed to pass args directly to Logger.Debug/Info
which properly handles structured logging.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: add changelog entries for build fixes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove temporary debug print statements from mobile merge

Remove emoji debug logs (🔴, 🟢, 🟠, 🔵, 🔥) that were accidentally left in
from the iOS/Android mobile platform support merge. These were development
debugging statements that should not have been included in the final code.

Files cleaned:
- application.go
- application_debug.go
- init_android.go
- init_ios.go
- mainthread_android.go
- mainthread_ios.go
- webview_window.go
- webview_window_ios.go

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add changelog entries for debug cleanup and breaking change

- Add breaking change note: production builds are now default
- Add entry for debug print statement removal

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: convert remaining printf-style debug calls to slog-style

Convert three debug() calls that were still using printf-style format
strings to slog-style structured logging (key-value pairs):

- systemtray_windows.go: ShellNotifyIcon show/hide failures
- application_darwin.go: window lookup failure

This addresses CodeRabbit review feedback and ensures consistency
with the refactored debug() method.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: convert all printf-style info() calls to slog-style

Convert remaining info() calls that were using printf-style format
strings to slog-style structured logging (key-value pairs):

- application_ios.go: iOS log messages and HandleJSMessage calls
- webview_window_windows.go: WM_SYSKEYDOWN logging
- application.go: handleWindowMessage and handleWebViewRequest logging

Also removed debug fmt.Printf statements from handleWebViewRequest.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add build tag to main.m to prevent Go from compiling it on non-iOS platforms

Go's toolchain tries to process .m (Objective-C) files when they're in a
directory with Go files. Adding a //go:build ios tag tells Go to only
process this file when building for iOS, matching how darwin .m files
handle this (e.g., //go:build darwin && !ios).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: remove orphaned wails-mimetype-migration submodule reference

The iOS merge added a submodule reference without a corresponding
.gitmodules file, causing Cloudflare and other CI systems to fail
with "No url found for submodule path" errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: auto-disable DMA-BUF renderer on Wayland with NVIDIA to prevent crashes

WebKitGTK has a known issue with the DMA-BUF renderer on NVIDIA proprietary
drivers running Wayland, causing "Error 71 (Protocol error)" crashes.

This fix automatically detects NVIDIA GPUs (via /sys/module/nvidia) and sets
WEBKIT_DISABLE_DMABUF_RENDERER=1 when running on Wayland.

Also removes leftover debug print statements from mobile platform merge.

See: https://bugs.webkit.org/show_bug.cgi?id=262607

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add NVIDIA driver info to wails3 doctor on Linux

Shows NVIDIA driver version and srcversion in doctor output to help
diagnose Wayland/NVIDIA compatibility issues.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Lea Anthony 2025-12-12 09:03:11 +11:00 committed by GitHub
commit c4b614cb10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 74 additions and 93 deletions

View file

@ -17,12 +17,18 @@ After processing, the content will be moved to the main changelog and this file
## Added
<!-- New features, capabilities, or enhancements -->
- Add NVIDIA driver version info to `wails3 doctor` output on Linux by @leaanthony
## Changed
<!-- Changes in existing functionality -->
- **BREAKING**: Production builds are now the default. To create dev builds, set `DEV=true` in your Taskfiles. Generate a new project for examples by @leaanthony
## Fixed
- Fix default `config.yml` would run `wails3 dev` with a production build by @mbaklor
- Fix iOS service stubs causing build failures due to non-existent package import by @leaanthony
- Fix structured logging in debug/info methods causing "no formatting directives" errors by @leaanthony
- Remove temporary debug print statements accidentally included from mobile platform merge by @leaanthony
- Fix WebKitGTK crash on Wayland with NVIDIA GPUs (Error 71 Protocol error) by auto-disabling DMA-BUF renderer by @leaanthony
<!-- Bug fixes -->
## Deprecated

View file

@ -133,11 +133,6 @@ func (a *AssetServer) processWebViewRequestInternal(r webview.Request) {
req.Header = header
// Debug iOS headers
if strings.Contains(uri, "wails://") {
fmt.Printf("🔍 iOS Request: URI=%s Headers=%v\n", uri, header)
}
if req.RemoteAddr == "" {
// 192.0.2.0/24 is "TEST-NET" in RFC 5737
req.RemoteAddr = "192.0.2.1:1234"
@ -160,7 +155,6 @@ func (a *AssetServer) processWebViewRequestInternal(r webview.Request) {
// iOS uses "localhost" while other platforms might use different hosts
// Skip host check for iOS requests from wails:// scheme
if expectedHost := a.ExpectedWebViewHost; expectedHost != "" && expectedHost != req.Host && !strings.HasPrefix(uri, "wails://") {
fmt.Printf("🔴 HOST MISMATCH: Expected='%s' Got='%s' URI=%s\n", expectedHost, req.Host, uri)
a.webviewRequestErrorHandler(uri, rw, fmt.Errorf("expected host '%s' in request, but was '%s'", expectedHost, req.Host))
return
}

View file

@ -1,3 +1,4 @@
//go:build ios
// Minimal bootstrap: delegate comes from Go archive (WailsAppDelegate)
#import <UIKit/UIKit.h>
#include <stdio.h>

View file

@ -3,15 +3,38 @@
package doctor
import (
"os"
"strings"
"github.com/wailsapp/wails/v3/internal/doctor/packagemanager"
"github.com/wailsapp/wails/v3/internal/operatingsystem"
)
func getInfo() (map[string]string, bool) {
result := make(map[string]string)
// Check for NVIDIA driver
result["NVIDIA Driver"] = getNvidiaDriverInfo()
return result, true
}
func getNvidiaDriverInfo() string {
version, err := os.ReadFile("/sys/module/nvidia/version")
if err != nil {
return "N/A"
}
versionStr := strings.TrimSpace(string(version))
srcVersion, err := os.ReadFile("/sys/module/nvidia/srcversion")
if err != nil {
return versionStr
}
return versionStr + " (" + strings.TrimSpace(string(srcVersion)) + ")"
}
func checkPlatformDependencies(result map[string]string, ok *bool) {
info, _ := operatingsystem.Info()

View file

@ -472,7 +472,6 @@ func (a *App) handleFatalError(err error) {
}
func (a *App) init() {
fmt.Println("🟠 [application.go] START App.init()")
a.ctx, a.cancel = context.WithCancel(context.Background())
a.applicationEventHooks = make(map[uint][]*eventHook)
a.applicationEventListeners = make(map[uint][]*EventListener)
@ -485,7 +484,6 @@ func (a *App) init() {
a.wailsEventListeners = make([]WailsEventListener, 0)
// Initialize managers
fmt.Println("🟠 [application.go] Initializing managers...")
a.Window = newWindowManager(a)
a.ContextMenu = newContextMenuManager(a)
a.KeyBinding = newKeyBindingManager(a)
@ -497,7 +495,6 @@ func (a *App) init() {
a.Screen = newScreenManager(a)
a.Clipboard = newClipboardManager(a)
a.SystemTray = newSystemTrayManager(a)
fmt.Println("🟠 [application.go] END App.init()")
}
func (a *App) Capabilities() capabilities.Capabilities {
@ -519,31 +516,21 @@ func (a *App) GetPID() int {
}
func (a *App) info(message string, args ...any) {
if a.Logger != nil {
go func() {
defer handlePanic()
// Avoid slog BADKEY by formatting printf-style messages ourselves
if len(args) > 0 {
a.Logger.Info(fmt.Sprintf(message, args...))
} else {
a.Logger.Info(message)
}
}()
}
if a.Logger != nil {
go func() {
defer handlePanic()
a.Logger.Info(message, args...)
}()
}
}
func (a *App) debug(message string, args ...any) {
if a.Logger != nil {
go func() {
defer handlePanic()
// Avoid slog BADKEY by formatting printf-style messages ourselves
if len(args) > 0 {
a.Logger.Debug(fmt.Sprintf(message, args...))
} else {
a.Logger.Debug(message)
}
}()
}
if a.Logger != nil {
go func() {
defer handlePanic()
a.Logger.Debug(message, args...)
}()
}
}
func (a *App) fatal(message string, args ...any) {
@ -560,12 +547,10 @@ func (a *App) error(message string, args ...any) {
}
func (a *App) Run() error {
fmt.Println("🟠 [application.go] START App.Run()")
a.runLock.Lock()
// Prevent double invocations.
if a.starting || a.running {
a.runLock.Unlock()
fmt.Println("🟠 [application.go] App already starting/running")
return errors.New("application is running or a previous run has failed")
}
// Block further service registrations.
@ -576,17 +561,12 @@ func (a *App) Run() error {
defer a.cancel()
// Call post-create hooks
fmt.Println("🟠 [application.go] About to call preRun()")
err := a.preRun()
if err != nil {
fmt.Printf("🟠 [application.go] preRun() failed: %v\n", err)
return err
}
fmt.Println("🟠 [application.go] preRun() completed")
fmt.Println("🟠 [application.go] About to call newPlatformApp()")
a.impl = newPlatformApp(a)
fmt.Println("🟠 [application.go] newPlatformApp() completed")
// Ensure services are shut down in case of failures.
defer a.shutdownServices()
@ -770,7 +750,7 @@ func (a *App) handleWindowMessage(event *windowMessage) {
}
a.windowsLock.RUnlock()
a.info("handleWindowMessage: Looking for window ID %d, available IDs: %v", event.windowId, ids)
a.info("handleWindowMessage: Looking for window", "windowId", event.windowId, "availableIDs", ids)
if !ok {
a.warning("WebviewWindow #%d not found", event.windowId)
@ -778,7 +758,7 @@ func (a *App) handleWindowMessage(event *windowMessage) {
}
// Check if the message starts with "wails:"
if strings.HasPrefix(event.message, "wails:") {
a.info("handleWindowMessage: Processing wails message: %s", event.message)
a.info("handleWindowMessage: Processing wails message", "message", event.message)
window.HandleMessage(event.message)
} else {
if a.options.RawMessageHandler != nil {
@ -791,12 +771,10 @@ func (a *App) handleWebViewRequest(request *webViewAssetRequest) {
defer handlePanic()
// Log that we're processing the request
url, _ := request.Request.URL()
a.info(" handleWebViewRequest: Processing request for URL: %s", url)
fmt.Printf(" handleWebViewRequest: About to call ServeWebViewRequest for: %s\n", url)
a.info("handleWebViewRequest: Processing request", "url", url)
// IMPORTANT: pass the wrapper request so our injected headers (x-wails-window-id/name) are used
a.assets.ServeWebViewRequest(request)
a.info(" handleWebViewRequest: Request processing complete for: %s", url)
fmt.Printf(" handleWebViewRequest: Request complete for: %s\n", url)
a.info("handleWebViewRequest: Request processing complete", "url", url)
}
func (a *App) handleWindowEvent(event *windowEvent) {
@ -910,10 +888,8 @@ func SaveFileDialog() *SaveFileDialogStruct {
}
func (a *App) dispatchOnMainThread(fn func()) {
fmt.Println("🟠 [application.go] dispatchOnMainThread() called")
// If we are on the main thread, just call the function
if a.impl.isOnMainThread() {
fmt.Println("🟠 [application.go] Already on main thread, executing directly")
fn()
return
}
@ -922,7 +898,6 @@ func (a *App) dispatchOnMainThread(fn func()) {
id := generateFunctionStoreID()
mainThreadFunctionStore[id] = fn
mainThreadFunctionStoreLock.Unlock()
fmt.Printf("🟠 [application.go] Dispatching function with ID %d to main thread\n", id)
// Call platform specific dispatch function
a.impl.dispatchOnMainThread(id)
}

View file

@ -363,7 +363,7 @@ func processMessage(windowID C.uint, message *C.char, origin *C.char, isMainFram
func processURLRequest(windowID C.uint, wkUrlSchemeTask unsafe.Pointer) {
window, ok := globalApplication.Window.GetByID(uint(windowID))
if !ok || window == nil {
globalApplication.debug("could not find window with id: %d", windowID)
globalApplication.debug("could not find window with id", "windowID", windowID)
return
}

View file

@ -3,7 +3,6 @@
package application
import (
"fmt"
"github.com/go-git/go-git/v5"
"github.com/samber/lo"
"github.com/wailsapp/wails/v3/internal/version"
@ -30,14 +29,11 @@ func init() {
// We use this to patch the application to production mode.
func newApplication(options Options) *App {
fmt.Println("🟣 [application_debug.go] START newApplication()")
result := &App{
isDebugMode: true,
options: options,
}
fmt.Println("🟣 [application_debug.go] About to call result.init()")
result.init()
fmt.Println("🟣 [application_debug.go] END newApplication() - App created")
return result
}

View file

@ -98,7 +98,7 @@ func LogInfo(source *C.char, message *C.char) {
iosConsoleLogf("info", "[iOS-%s] %s", goSource, goMessage)
if globalApplication != nil && globalApplication.Logger != nil {
globalApplication.info("[iOS-%s] %s", goSource, goMessage)
globalApplication.info("iOS log", "source", goSource, "message", goMessage)
}
}
@ -375,7 +375,7 @@ func HandleJSMessage(windowID C.uint, message *C.char) {
}
if globalApplication != nil {
globalApplication.info("[HandleJSMessage] Received '%s' from client", name)
globalApplication.info("HandleJSMessage received from client", "name", name)
}
windowMessageBuffer <- &windowMessage{
windowId: uint(windowID),
@ -386,7 +386,7 @@ func HandleJSMessage(windowID C.uint, message *C.char) {
// Fallback for structured payloads without a "name" field
if name, ok := msgData["message"].(string); ok && name != "" {
if globalApplication != nil {
globalApplication.info("[HandleJSMessage] Received raw message field '%s' from client", name)
globalApplication.info("HandleJSMessage received raw message field from client", "name", name)
}
windowMessageBuffer <- &windowMessage{
windowId: uint(windowID),
@ -404,7 +404,7 @@ func HandleJSMessage(windowID C.uint, message *C.char) {
// If not JSON or JSON without name/message, treat the entire payload as a string event
if msg != "" {
if globalApplication != nil {
globalApplication.info("[HandleJSMessage] Received raw '%s' from client", msg)
globalApplication.info("HandleJSMessage received raw message from client", "message", msg)
}
windowMessageBuffer <- &windowMessage{
windowId: uint(windowID),

View file

@ -34,6 +34,24 @@ func init() {
(os.Getenv("XDG_SESSION_TYPE") == "" || os.Getenv("XDG_SESSION_TYPE") == "unspecified" || os.Getenv("XDG_SESSION_TYPE") == "x11") {
_ = os.Setenv("GDK_BACKEND", "x11")
}
// Disable DMA-BUF renderer on Wayland with NVIDIA to prevent "Error 71 (Protocol error)" crashes.
// This is a known WebKitGTK issue with NVIDIA proprietary drivers on Wayland.
// See: https://bugs.webkit.org/show_bug.cgi?id=262607
if os.Getenv("WEBKIT_DISABLE_DMABUF_RENDERER") == "" &&
os.Getenv("XDG_SESSION_TYPE") == "wayland" &&
isNVIDIAGPU() {
_ = os.Setenv("WEBKIT_DISABLE_DMABUF_RENDERER", "1")
}
}
// isNVIDIAGPU checks if an NVIDIA GPU is present by looking for the nvidia kernel module.
func isNVIDIAGPU() bool {
// Check if nvidia module is loaded (most reliable for proprietary driver)
if _, err := os.Stat("/sys/module/nvidia"); err == nil {
return true
}
return false
}
type linuxApp struct {

View file

@ -2,12 +2,8 @@
package application
import "fmt"
func init() {
fmt.Println("🤖 [init_android.go] START init()")
// On Android, we don't call runtime.LockOSThread()
// The Android runtime handles thread management via JNI
// and calling LockOSThread can interfere with the JNI environment
fmt.Println("🤖 [init_android.go] END init() - no LockOSThread on Android")
}

View file

@ -2,12 +2,8 @@
package application
import "fmt"
func init() {
fmt.Println("🔵 [init_ios.go] START init()")
// On iOS, we don't call runtime.LockOSThread()
// The iOS runtime handles thread management differently
// and calling LockOSThread can interfere with signal handling
fmt.Println("🔵 [init_ios.go] END init() - no LockOSThread on iOS")
}
}

View file

@ -2,8 +2,6 @@
package application
import "fmt"
// isOnMainThread returns whether the current goroutine is on the main thread
func (a *androidApp) isOnMainThread() bool {
// On Android, Go runs in its own thread separate from the UI thread
@ -13,14 +11,12 @@ func (a *androidApp) isOnMainThread() bool {
// dispatchOnMainThread executes a function on the Android main/UI thread
func (a *androidApp) dispatchOnMainThread(id uint) {
fmt.Printf("🤖 [mainthread_android.go] dispatchOnMainThread(id=%d)\n", id)
// TODO: Implement via JNI callback to Activity.runOnUiThread()
// For now, execute the callback directly
mainThreadFunctionStoreLock.RLock()
fn := mainThreadFunctionStore[id]
if fn == nil {
mainThreadFunctionStoreLock.RUnlock()
fmt.Printf("🤖 [mainthread_android.go] ERROR: dispatchOnMainThread called with invalid id: %d\n", id)
return
}
delete(mainThreadFunctionStore, id)

View file

@ -21,20 +21,17 @@ static bool onMainThread() {
}
*/
import "C"
import "fmt"
func (a *iosApp) isOnMainThread() bool {
return bool(C.onMainThread())
}
func (a *iosApp) dispatchOnMainThread(id uint) {
fmt.Printf("🔵 [mainthread_ios.go] dispatchOnMainThread(id=%d)\n", id)
C.dispatchOnMainThread(C.uint(id))
}
//export dispatchOnMainThreadCallback
func dispatchOnMainThreadCallback(callbackID C.uint) {
fmt.Printf("🔵 [mainthread_ios.go] dispatchOnMainThreadCallback(id=%d)\n", callbackID)
mainThreadFunctionStoreLock.RLock()
id := uint(callbackID)
fn := mainThreadFunctionStore[id]

View file

@ -570,7 +570,7 @@ func (s *windowsSystemTray) Show() {
nid.DwStateMask = w32.NIS_HIDDEN
nid.DwState = 0
if !w32.ShellNotifyIcon(w32.NIM_MODIFY, &nid) {
globalApplication.debug("ShellNotifyIcon NIM_MODIFY show failed: %v", syscall.GetLastError())
globalApplication.debug("ShellNotifyIcon NIM_MODIFY show failed", "error", syscall.GetLastError())
}
}
@ -584,7 +584,7 @@ func (s *windowsSystemTray) Hide() {
nid.DwStateMask = w32.NIS_HIDDEN
nid.DwState = w32.NIS_HIDDEN
if !w32.ShellNotifyIcon(w32.NIM_MODIFY, &nid) {
globalApplication.debug("ShellNotifyIcon NIM_MODIFY hide failed: %v", syscall.GetLastError())
globalApplication.debug("ShellNotifyIcon NIM_MODIFY hide failed", "error", syscall.GetLastError())
}
}

View file

@ -570,16 +570,13 @@ func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) Window {
// ExecJS executes the given javascript in the context of the window.
func (w *WebviewWindow) ExecJS(js string) {
if w.impl == nil || w.isDestroyed() {
fmt.Println("🔴 [ExecJS] Window impl is nil or destroyed")
return
}
if w.runtimeLoaded {
fmt.Println("🟢 [ExecJS] Runtime loaded, executing JS immediately")
InvokeSync(func() {
w.impl.execJS(js)
})
} else {
fmt.Printf("🟠 [ExecJS] Runtime NOT loaded yet, queuing JS (queue size: %d)\n", len(w.pendingJS)+1)
w.pendingJS = append(w.pendingJS, js)
}
}
@ -726,12 +723,10 @@ func (w *WebviewWindow) HandleMessage(message string) {
}
}
case message == "wails:runtime:ready":
fmt.Printf("🟢 [WebviewWindow] Runtime ready! Pending JS count: %d\n", len(w.pendingJS))
w.emit(events.Common.WindowRuntimeReady)
w.runtimeLoaded = true
w.SetResizable(!w.options.DisableResize)
for i, js := range w.pendingJS {
fmt.Printf("🟢 [WebviewWindow] Executing pending JS %d/%d\n", i+1, len(w.pendingJS))
for _, js := range w.pendingJS {
w.ExecJS(js)
}
w.pendingJS = nil
@ -1182,9 +1177,7 @@ func (w *WebviewWindow) SetFrameless(frameless bool) Window {
}
func (w *WebviewWindow) DispatchWailsEvent(event *CustomEvent) {
fmt.Printf("🔵 [WebviewWindow.DispatchWailsEvent] Dispatching to frontend: %s\n", event.Name)
msg := fmt.Sprintf("_wails.dispatchWailsEvent(%s);", event.ToJSON())
fmt.Printf("🔵 [WebviewWindow.DispatchWailsEvent] JS command: %s\n", msg)
w.ExecJS(msg)
}
@ -1242,7 +1235,6 @@ func (w *WebviewWindow) HandleDragAndDropMessage(filenames []string, dropZone *D
)
for _, listener := range listeners {
if listener == nil {
fmt.Println("[DragDropDebug] HandleDragAndDropMessage: Skipping nil listener")
continue
}
listener.callback(thisEvent)

View file

@ -16,7 +16,6 @@ void ios_window_set_background_color(void* viewController, unsigned char r, unsi
*/
import "C"
import (
"fmt"
"unsafe"
)
@ -203,29 +202,22 @@ func (w *iosWebviewWindow) setParent(_ *WebviewWindow) error {
}
func (w *iosWebviewWindow) run() {
fmt.Printf("🔥 iosWebviewWindow.run() called! nativeHandle: %v\n", w.nativeHandle)
// Create the native WebView when the window runs
if w.nativeHandle == nil {
// Get the Wails window ID from the parent
wailsID := w.parent.ID()
fmt.Printf("🔥 Creating native WebView with Wails ID: %d\n", wailsID)
// Create the native WebView with the Wails window ID
w.nativeHandle = C.ios_create_webview_with_id(C.uint(wailsID))
if w.nativeHandle != nil {
// Store the window ID (should match what we passed in)
w.windowID = uint32(wailsID)
fmt.Printf("🔥 Native WebView created successfully! Handle: %v\n", w.nativeHandle)
// Apply initial background colour if set (default white otherwise)
rgba := w.parent.options.BackgroundColour
C.ios_window_set_background_color(
w.nativeHandle,
C.uchar(rgba.Red), C.uchar(rgba.Green), C.uchar(rgba.Blue), C.uchar(rgba.Alpha),
)
} else {
fmt.Printf("🔴 FAILED to create native WebView!\n")
}
} else {
fmt.Printf("🔥 Native WebView already exists!\n")
}
}

View file

@ -1478,7 +1478,7 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
}
}
case w32.WM_SYSKEYDOWN:
globalApplication.info("w32.WM_SYSKEYDOWN: %v", uint(wparam))
globalApplication.info("w32.WM_SYSKEYDOWN", "wparam", uint(wparam))
w.parent.emit(events.Windows.WindowKeyDown)
if w.processKeyBinding(uint(wparam)) {
return 0

@ -1 +0,0 @@
Subproject commit b7f2d4a43bc526b12fd3af162e572294f62db8e1