diff --git a/v3/examples/events/assets/index.html b/v3/examples/events/assets/index.html
index d8e0906e..a64a42c3 100644
--- a/v3/examples/events/assets/index.html
+++ b/v3/examples/events/assets/index.html
@@ -3,6 +3,7 @@
Title
+
diff --git a/v3/examples/window/main.go b/v3/examples/window/main.go
index 9c0e390f..41fc4660 100644
--- a/v3/examples/window/main.go
+++ b/v3/examples/window/main.go
@@ -24,7 +24,7 @@ func main() {
ApplicationShouldTerminateAfterLastWindowClosed: false,
},
})
- app.On(events.Mac.ApplicationDidFinishLaunching, func(event *application.Event) {
+ app.On(events.Common.ApplicationStarted, func(event *application.Event) {
log.Println("ApplicationDidFinishLaunching")
})
diff --git a/v3/pkg/application/application_linux.go b/v3/pkg/application/application_linux.go
index 4272cd5c..c3b54673 100644
--- a/v3/pkg/application/application_linux.go
+++ b/v3/pkg/application/application_linux.go
@@ -35,7 +35,7 @@ type linuxApp struct {
theme string
}
-func (m *linuxApp) GetFlags(options Options) map[string]any {
+func (l *linuxApp) GetFlags(options Options) map[string]any {
if options.Flags == nil {
options.Flags = make(map[string]any)
}
@@ -46,30 +46,30 @@ func getNativeApplication() *linuxApp {
return globalApplication.impl.(*linuxApp)
}
-func (m *linuxApp) hide() {
- hideAllWindows(m.application)
+func (l *linuxApp) hide() {
+ hideAllWindows(l.application)
}
-func (m *linuxApp) show() {
- showAllWindows(m.application)
+func (l *linuxApp) show() {
+ showAllWindows(l.application)
}
-func (m *linuxApp) on(eventID uint) {
+func (l *linuxApp) on(eventID uint) {
// TODO: What do we need to do here?
log.Println("linuxApp.on()", eventID)
}
-func (m *linuxApp) setIcon(icon []byte) {
+func (l *linuxApp) setIcon(icon []byte) {
log.Println("linuxApp.setIcon", "not implemented")
}
-func (m *linuxApp) name() string {
+func (l *linuxApp) name() string {
return appName()
}
-func (m *linuxApp) getCurrentWindowID() uint {
- return getCurrentWindowID(m.application, m.windows)
+func (l *linuxApp) getCurrentWindowID() uint {
+ return getCurrentWindowID(l.application, l.windows)
}
type rnr struct {
@@ -80,9 +80,9 @@ func (r rnr) run() {
r.f()
}
-func (m *linuxApp) getApplicationMenu() pointer {
- if m.applicationMenu != nilPointer {
- return m.applicationMenu
+func (l *linuxApp) getApplicationMenu() pointer {
+ if l.applicationMenu != nilPointer {
+ return l.applicationMenu
}
menu := globalApplication.ApplicationMenu
@@ -90,12 +90,12 @@ func (m *linuxApp) getApplicationMenu() pointer {
InvokeSync(func() {
menu.Update()
})
- m.applicationMenu = (menu.impl).(*linuxMenu).native
+ l.applicationMenu = (menu.impl).(*linuxMenu).native
}
- return m.applicationMenu
+ return l.applicationMenu
}
-func (m *linuxApp) setApplicationMenu(menu *Menu) {
+func (l *linuxApp) setApplicationMenu(menu *Menu) {
// FIXME: How do we avoid putting a menu?
if menu == nil {
// Create a default menu
@@ -104,46 +104,44 @@ func (m *linuxApp) setApplicationMenu(menu *Menu) {
}
}
-func (m *linuxApp) run() error {
+func (l *linuxApp) run() error {
- // Add a hook to the ApplicationDidFinishLaunching event
- // FIXME: add Wails specific events - i.e. Shouldn't platform specific ones be translated to Wails events?
- m.parent.On(events.Mac.ApplicationDidFinishLaunching, func(evt *Event) {
- // Do we need to do anything now?
- fmt.Println("events.Mac.ApplicationDidFinishLaunching received!")
+ l.parent.On(events.Linux.ApplicationStartup, func(evt *Event) {
+ fmt.Println("events.Linux.ApplicationStartup received!")
})
- m.monitorThemeChanges()
- return appRun(m.application)
+ l.setupCommonEvents()
+ l.monitorThemeChanges()
+ return appRun(l.application)
}
-func (m *linuxApp) destroy() {
+func (l *linuxApp) destroy() {
if !globalApplication.shouldQuit() {
return
}
globalApplication.cleanup()
- appDestroy(m.application)
+ appDestroy(l.application)
}
-func (m *linuxApp) isOnMainThread() bool {
+func (l *linuxApp) isOnMainThread() bool {
return isOnMainThread()
}
// register our window to our parent mapping
-func (m *linuxApp) registerWindow(window pointer, id uint) {
- m.windowsLock.Lock()
- m.windows[windowPointer(window)] = id
- m.windowsLock.Unlock()
+func (l *linuxApp) registerWindow(window pointer, id uint) {
+ l.windowsLock.Lock()
+ l.windows[windowPointer(window)] = id
+ l.windowsLock.Unlock()
}
-func (m *linuxApp) isDarkMode() bool {
- return strings.Contains(m.theme, "dark")
+func (l *linuxApp) isDarkMode() bool {
+ return strings.Contains(l.theme, "dark")
}
-func (m *linuxApp) monitorThemeChanges() {
+func (l *linuxApp) monitorThemeChanges() {
go func() {
conn, err := dbus.ConnectSessionBus()
if err != nil {
- m.parent.info("[WARNING] Failed to connect to session bus; monitoring for theme changes will not function:", err)
+ l.parent.info("[WARNING] Failed to connect to session bus; monitoring for theme changes will not function:", err)
return
}
defer conn.Close()
@@ -176,10 +174,10 @@ func (m *linuxApp) monitorThemeChanges() {
continue
}
- if theme != m.theme {
- m.theme = theme
+ if theme != l.theme {
+ l.theme = theme
event := newApplicationEvent(events.Common.ThemeChanged)
- event.Context().setIsDarkMode(m.isDarkMode())
+ event.Context().setIsDarkMode(l.isDarkMode())
applicationEvents <- event
}
diff --git a/v3/pkg/application/dialogs_linux.go b/v3/pkg/application/dialogs_linux.go
index 4943766f..49499dda 100644
--- a/v3/pkg/application/dialogs_linux.go
+++ b/v3/pkg/application/dialogs_linux.go
@@ -1,7 +1,7 @@
package application
-func (m *linuxApp) showAboutDialog(title string, message string, icon []byte) {
- window := globalApplication.getWindowForID(m.getCurrentWindowID())
+func (l *linuxApp) showAboutDialog(title string, message string, icon []byte) {
+ window := globalApplication.getWindowForID(l.getCurrentWindowID())
var parent uintptr
if window != nil {
parent, _ = window.(*WebviewWindow).NativeWindowHandle()
diff --git a/v3/pkg/application/events_common_linux.go b/v3/pkg/application/events_common_linux.go
new file mode 100644
index 00000000..530ac156
--- /dev/null
+++ b/v3/pkg/application/events_common_linux.go
@@ -0,0 +1,21 @@
+//go:build linux
+
+package application
+
+import "github.com/wailsapp/wails/v3/pkg/events"
+
+var commonApplicationEventMap = map[events.ApplicationEventType]events.ApplicationEventType{
+ events.Linux.ApplicationStartup: events.Common.ApplicationStarted,
+ events.Linux.SystemThemeChanged: events.Common.ThemeChanged,
+}
+
+func (l *linuxApp) setupCommonEvents() {
+ for sourceEvent, targetEvent := range commonApplicationEventMap {
+ sourceEvent := sourceEvent
+ targetEvent := targetEvent
+ l.parent.On(sourceEvent, func(event *Event) {
+ event.Id = uint(targetEvent)
+ applicationEvents <- event
+ })
+ }
+}
diff --git a/v3/pkg/application/linux_cgo.go b/v3/pkg/application/linux_cgo.go
index 36db3d50..379af254 100644
--- a/v3/pkg/application/linux_cgo.go
+++ b/v3/pkg/application/linux_cgo.go
@@ -206,7 +206,36 @@ func dispatchOnMainThreadCallback(callbackID C.uint) {
//export activateLinux
func activateLinux(data pointer) {
- // NOOP: Callback for now
+ processApplicationEvent(C.uint(events.Linux.ApplicationStartup), data)
+}
+
+//export processApplicationEvent
+func processApplicationEvent(eventID C.uint, data pointer) {
+ event := newApplicationEvent(events.ApplicationEventType(eventID))
+
+ //if data != nil {
+ // dataCStrJSON := C.serializationNSDictionary(data)
+ // if dataCStrJSON != nil {
+ // defer C.free(unsafe.Pointer(dataCStrJSON))
+ //
+ // dataJSON := C.GoString(dataCStrJSON)
+ // var result map[string]any
+ // err := json.Unmarshal([]byte(dataJSON), &result)
+ //
+ // if err != nil {
+ // panic(err)
+ // }
+ //
+ // event.Context().setData(result)
+ // }
+ //}
+
+ switch event.Id {
+ case uint(events.Linux.SystemThemeChanged):
+ isDark := globalApplication.IsDarkMode()
+ event.Context().setIsDarkMode(isDark)
+ }
+ applicationEvents <- event
}
func isOnMainThread() bool {
@@ -236,17 +265,12 @@ func appNew(name string) pointer {
func appRun(app pointer) error {
application := (*C.GApplication)(app)
+ //TODO: Only set this if we configure it to do so
C.g_application_hold(application) // allows it to run without a window
signal := C.CString("activate")
defer C.free(unsafe.Pointer(signal))
- C.g_signal_connect_data(
- C.gpointer(application),
- signal,
- C.GCallback(C.activateLinux),
- nil,
- nil,
- 0)
+ C.signal_connect(unsafe.Pointer(application), signal, C.activateLinux, nil)
status := C.g_application_run(application, 0, nil)
C.g_application_release(application)
C.g_object_unref(C.gpointer(app))
diff --git a/v3/pkg/application/mainthread_linux.go b/v3/pkg/application/mainthread_linux.go
index 572b081b..2a5ff3e2 100644
--- a/v3/pkg/application/mainthread_linux.go
+++ b/v3/pkg/application/mainthread_linux.go
@@ -2,7 +2,7 @@
package application
-func (m *linuxApp) dispatchOnMainThread(id uint) {
+func (l *linuxApp) dispatchOnMainThread(id uint) {
dispatchOnMainThread(id)
}
diff --git a/v3/pkg/application/screen_linux.go b/v3/pkg/application/screen_linux.go
index 36411045..526752ac 100644
--- a/v3/pkg/application/screen_linux.go
+++ b/v3/pkg/application/screen_linux.go
@@ -7,17 +7,17 @@ import (
"sync"
)
-func (m *linuxApp) getPrimaryScreen() (*Screen, error) {
+func (l *linuxApp) getPrimaryScreen() (*Screen, error) {
return nil, fmt.Errorf("not implemented")
}
-func (m *linuxApp) getScreens() ([]*Screen, error) {
+func (l *linuxApp) getScreens() ([]*Screen, error) {
var wg sync.WaitGroup
var screens []*Screen
var err error
wg.Add(1)
InvokeSync(func() {
- screens, err = getScreens(m.application)
+ screens, err = getScreens(l.application)
wg.Done()
})
wg.Wait()
diff --git a/v3/pkg/application/webview_window_linux.go b/v3/pkg/application/webview_window_linux.go
index 1f36059e..5314ea6b 100644
--- a/v3/pkg/application/webview_window_linux.go
+++ b/v3/pkg/application/webview_window_linux.go
@@ -259,11 +259,12 @@ func (w *linuxWebviewWindow) setAlwaysOnTop(alwaysOnTop bool) {
func newWindowImpl(parent *WebviewWindow) *linuxWebviewWindow {
// (*C.struct__GtkWidget)(m.native)
//var menubar *C.struct__GtkWidget
- return &linuxWebviewWindow{
+ result := &linuxWebviewWindow{
application: getNativeApplication().application,
parent: parent,
// menubar: menubar,
}
+ return result
}
func (w *linuxWebviewWindow) setTitle(title string) {
@@ -405,9 +406,7 @@ func (w *linuxWebviewWindow) run() {
}
w.setURL(startURL)
- // We need to wait for the HTML to load before we can execute the javascript
- // FIXME: What event is this? DomReady?
- w.parent.On(events.Mac.WebViewDidFinishNavigation, func(_ *WindowEvent) {
+ w.parent.On(events.Linux.WindowLoadChanged, func(_ *WindowEvent) {
if w.parent.options.JS != "" {
w.execJS(w.parent.options.JS)
}
@@ -416,6 +415,9 @@ func (w *linuxWebviewWindow) run() {
w.execJS(js)
}
})
+ w.parent.On(events.Linux.WindowDeleteEvent, func(e *WindowEvent) {
+ w.parent.emit(events.Common.WindowClosing)
+ })
w.parent.RegisterHook(events.Linux.WindowLoadChanged, func(e *WindowEvent) {
w.execJS(runtime.Core())
})