5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-08 00:41:00 +08:00

[WIP] refactor CGO methods

This commit is contained in:
Lea Anthony 2024-02-07 22:19:33 +11:00 committed by Travis McLane
parent 3d93c83920
commit 4cd4b46772
7 changed files with 211 additions and 321 deletions

View File

@ -34,7 +34,7 @@ type linuxApp struct {
theme string theme string
} }
func (l *linuxApp) GetFlags(options Options) map[string]any { func (a *linuxApp) GetFlags(options Options) map[string]any {
if options.Flags == nil { if options.Flags == nil {
options.Flags = make(map[string]any) options.Flags = make(map[string]any)
} }
@ -45,32 +45,28 @@ func getNativeApplication() *linuxApp {
return globalApplication.impl.(*linuxApp) return globalApplication.impl.(*linuxApp)
} }
func (l *linuxApp) hide() { func (a *linuxApp) hide() {
hideAllWindows(l.application) a.hideAllWindows()
} }
func (l *linuxApp) show() { func (a *linuxApp) show() {
showAllWindows(l.application) a.showAllWindows()
} }
func (l *linuxApp) on(eventID uint) { func (a *linuxApp) on(eventID uint) {
// TODO: Test register/unregister events // TODO: Test register/unregister events
//C.registerApplicationEvent(l.application, C.uint(eventID)) //C.registerApplicationEvent(l.application, C.uint(eventID))
} }
func (l *linuxApp) setIcon(icon []byte) { func (a *linuxApp) setIcon(icon []byte) {
log.Println("linuxApp.setIcon", "not implemented") log.Println("linuxApp.setIcon", "not implemented")
} }
func (l *linuxApp) name() string { func (a *linuxApp) name() string {
return appName() return appName()
} }
func (l *linuxApp) getCurrentWindowID() uint {
return getCurrentWindowID(l.application, l.windowMap)
}
type rnr struct { type rnr struct {
f func() f func()
} }
@ -79,7 +75,7 @@ func (r rnr) run() {
r.f() r.f()
} }
func (l *linuxApp) setApplicationMenu(menu *Menu) { func (a *linuxApp) setApplicationMenu(menu *Menu) {
// FIXME: How do we avoid putting a menu? // FIXME: How do we avoid putting a menu?
if menu == nil { if menu == nil {
// Create a default menu // Create a default menu
@ -88,55 +84,55 @@ func (l *linuxApp) setApplicationMenu(menu *Menu) {
} }
} }
func (l *linuxApp) run() error { func (a *linuxApp) run() error {
l.parent.On(events.Linux.ApplicationStartup, func(evt *Event) { a.parent.On(events.Linux.ApplicationStartup, func(evt *Event) {
fmt.Println("events.Linux.ApplicationStartup received!") fmt.Println("events.Linux.ApplicationStartup received!")
}) })
l.setupCommonEvents() a.setupCommonEvents()
l.monitorThemeChanges() a.monitorThemeChanges()
return appRun(l.application) return appRun(a.application)
} }
func (l *linuxApp) unregisterWindow(w windowPointer) { func (a *linuxApp) unregisterWindow(w windowPointer) {
l.windowMapLock.Lock() a.windowMapLock.Lock()
delete(l.windowMap, w) delete(a.windowMap, w)
l.windowMapLock.Unlock() a.windowMapLock.Unlock()
// If this was the last window... // If this was the last window...
if len(l.windowMap) == 0 && !l.parent.options.Linux.DisableQuitOnLastWindowClosed { if len(a.windowMap) == 0 && !a.parent.options.Linux.DisableQuitOnLastWindowClosed {
l.destroy() a.destroy()
} }
} }
func (l *linuxApp) destroy() { func (a *linuxApp) destroy() {
if !globalApplication.shouldQuit() { if !globalApplication.shouldQuit() {
return return
} }
globalApplication.cleanup() globalApplication.cleanup()
appDestroy(l.application) appDestroy(a.application)
} }
func (l *linuxApp) isOnMainThread() bool { func (a *linuxApp) isOnMainThread() bool {
return isOnMainThread() return isOnMainThread()
} }
// register our window to our parent mapping // register our window to our parent mapping
func (l *linuxApp) registerWindow(window pointer, id uint) { func (a *linuxApp) registerWindow(window pointer, id uint) {
l.windowMapLock.Lock() a.windowMapLock.Lock()
l.windowMap[windowPointer(window)] = id a.windowMap[windowPointer(window)] = id
l.windowMapLock.Unlock() a.windowMapLock.Unlock()
} }
func (l *linuxApp) isDarkMode() bool { func (a *linuxApp) isDarkMode() bool {
return strings.Contains(l.theme, "dark") return strings.Contains(a.theme, "dark")
} }
func (l *linuxApp) monitorThemeChanges() { func (a *linuxApp) monitorThemeChanges() {
go func() { go func() {
conn, err := dbus.ConnectSessionBus() conn, err := dbus.ConnectSessionBus()
if err != nil { if err != nil {
l.parent.info("[WARNING] Failed to connect to session bus; monitoring for theme changes will not function:", err) a.parent.info("[WARNING] Failed to connect to session bus; monitoring for theme changes will not function:", err)
return return
} }
defer conn.Close() defer conn.Close()
@ -169,10 +165,10 @@ func (l *linuxApp) monitorThemeChanges() {
continue continue
} }
if theme != l.theme { if theme != a.theme {
l.theme = theme a.theme = theme
event := newApplicationEvent(events.Common.ThemeChanged) event := newApplicationEvent(events.Common.ThemeChanged)
event.Context().setIsDarkMode(l.isDarkMode()) event.Context().setIsDarkMode(a.isDarkMode())
applicationEvents <- event applicationEvents <- event
} }

View File

@ -1,7 +1,7 @@
package application package application
func (l *linuxApp) showAboutDialog(title string, message string, icon []byte) { func (a *linuxApp) showAboutDialog(title string, message string, icon []byte) {
window := globalApplication.getWindowForID(l.getCurrentWindowID()) window := globalApplication.getWindowForID(a.getCurrentWindowID())
var parent uintptr var parent uintptr
if window != nil { if window != nil {
parent, _ = window.(*WebviewWindow).NativeWindowHandle() parent, _ = window.(*WebviewWindow).NativeWindowHandle()

View File

@ -9,11 +9,11 @@ var commonApplicationEventMap = map[events.ApplicationEventType]events.Applicati
events.Linux.SystemThemeChanged: events.Common.ThemeChanged, events.Linux.SystemThemeChanged: events.Common.ThemeChanged,
} }
func (l *linuxApp) setupCommonEvents() { func (a *linuxApp) setupCommonEvents() {
for sourceEvent, targetEvent := range commonApplicationEventMap { for sourceEvent, targetEvent := range commonApplicationEventMap {
sourceEvent := sourceEvent sourceEvent := sourceEvent
targetEvent := targetEvent targetEvent := targetEvent
l.parent.On(sourceEvent, func(event *Event) { a.parent.On(sourceEvent, func(event *Event) {
event.Id = uint(targetEvent) event.Id = uint(targetEvent)
applicationEvents <- event applicationEvents <- event
}) })

View File

@ -286,13 +286,13 @@ func appDestroy(application pointer) {
C.g_application_quit((*C.GApplication)(application)) C.g_application_quit((*C.GApplication)(application))
} }
func contextMenuShow(window pointer, menu pointer, data *ContextMenuData) { func (w *linuxWebviewWindow) contextMenuShow(menu pointer, data *ContextMenuData) {
geometry := C.GdkRectangle{ geometry := C.GdkRectangle{
x: C.int(data.X), x: C.int(data.X),
y: C.int(data.Y), y: C.int(data.Y),
} }
event := C.GdkEvent{} event := C.GdkEvent{}
gdkWindow := C.gtk_widget_get_window((*C.GtkWidget)(window)) gdkWindow := C.gtk_widget_get_window(w.gtkWidget())
C.gtk_menu_popup_at_rect( C.gtk_menu_popup_at_rect(
(*C.GtkMenu)(menu), (*C.GtkMenu)(menu),
gdkWindow, gdkWindow,
@ -303,13 +303,13 @@ func contextMenuShow(window pointer, menu pointer, data *ContextMenuData) {
) )
} }
func getCurrentWindowID(application pointer, windows map[windowPointer]uint) uint { func (a *linuxApp) getCurrentWindowID() uint {
// TODO: Add extra metadata to window and use it! // TODO: Add extra metadata to window and use it!
window := (*C.GtkWindow)(C.gtk_application_get_active_window((*C.GtkApplication)(application))) window := (*C.GtkWindow)(C.gtk_application_get_active_window((*C.GtkApplication)(a.application)))
if window == nil { if window == nil {
return uint(1) return uint(1)
} }
identifier, ok := windows[window] identifier, ok := a.windowMap[window]
if ok { if ok {
return identifier return identifier
} }
@ -317,9 +317,9 @@ func getCurrentWindowID(application pointer, windows map[windowPointer]uint) uin
return uint(1) return uint(1)
} }
func getWindows(application pointer) []pointer { func (a *linuxApp) getWindows() []pointer {
result := []pointer{} result := []pointer{}
windows := C.gtk_application_get_windows((*C.GtkApplication)(application)) windows := C.gtk_application_get_windows((*C.GtkApplication)(a.application))
for { for {
result = append(result, pointer(windows.data)) result = append(result, pointer(windows.data))
windows = windows.next windows = windows.next
@ -329,14 +329,14 @@ func getWindows(application pointer) []pointer {
} }
} }
func hideAllWindows(application pointer) { func (a *linuxApp) hideAllWindows() {
for _, window := range getWindows(application) { for _, window := range a.getWindows() {
C.gtk_widget_hide((*C.GtkWidget)(window)) C.gtk_widget_hide((*C.GtkWidget)(window))
} }
} }
func showAllWindows(application pointer) { func (a *linuxApp) showAllWindows() {
for _, window := range getWindows(application) { for _, window := range a.getWindows() {
C.gtk_window_present((*C.GtkWindow)(window)) C.gtk_window_present((*C.GtkWindow)(window))
} }
} }
@ -661,26 +661,27 @@ func widgetSetVisible(widget pointer, hidden bool) {
} }
} }
// window related functions func (w *linuxWebviewWindow) close() {
func windowClose(window pointer) { C.gtk_window_close((*C.GtkWindow)(w.window))
C.gtk_window_close((*C.GtkWindow)(window)) getNativeApplication().unregisterWindow(windowPointer(w.window))
} }
func windowEnableDND(id uint, webview pointer) { func (w *linuxWebviewWindow) enableDND() {
id := w.parent.id
dnd := C.CString("text/uri-list") dnd := C.CString("text/uri-list")
defer C.free(unsafe.Pointer(dnd)) defer C.free(unsafe.Pointer(dnd))
targetentry := C.gtk_target_entry_new(dnd, 0, C.guint(id)) targetentry := C.gtk_target_entry_new(dnd, 0, C.guint(id))
defer C.gtk_target_entry_free(targetentry) defer C.gtk_target_entry_free(targetentry)
C.gtk_drag_dest_set((*C.GtkWidget)(webview), C.GTK_DEST_DEFAULT_DROP, targetentry, 1, C.GDK_ACTION_COPY) C.gtk_drag_dest_set((*C.GtkWidget)(w.webview), C.GTK_DEST_DEFAULT_DROP, targetentry, 1, C.GDK_ACTION_COPY)
event := C.CString("drag-data-received") event := C.CString("drag-data-received")
defer C.free(unsafe.Pointer(event)) defer C.free(unsafe.Pointer(event))
windowId := C.uint(id) windowId := C.uint(id)
C.signal_connect(unsafe.Pointer(webview), event, C.onDragNDrop, unsafe.Pointer(C.gpointer(&windowId))) C.signal_connect(unsafe.Pointer(w.webview), event, C.onDragNDrop, unsafe.Pointer(C.gpointer(&windowId)))
} }
func windowExecJS(webview pointer, js string) { func (w *linuxWebviewWindow) execJS(js string) {
value := C.CString(js) value := C.CString(js)
C.webkit_web_view_evaluate_javascript((*C.WebKitWebView)(webview), C.webkit_web_view_evaluate_javascript((*C.WebKitWebView)(w.webview),
value, value,
C.long(len(js)), C.long(len(js)),
nil, nil,
@ -715,8 +716,8 @@ func windowGetCurrentMonitor(window pointer) *C.GdkMonitor {
return C.gdk_display_get_monitor_at_window(display, gdk_window) return C.gdk_display_get_monitor_at_window(display, gdk_window)
} }
func windowGetCurrentMonitorGeometry(window pointer) (x int, y int, width int, height int, scale int) { func (w *linuxWebviewWindow) getCurrentMonitorGeometry() (x int, y int, width int, height int, scale int) {
monitor := windowGetCurrentMonitor(window) monitor := windowGetCurrentMonitor(w.window)
if monitor == nil { if monitor == nil {
return -1, -1, -1, -1, 1 return -1, -1, -1, -1, 1
} }
@ -726,13 +727,6 @@ func windowGetCurrentMonitorGeometry(window pointer) (x int, y int, width int, h
return int(result.x), int(result.y), int(result.width), int(result.height), scale return int(result.x), int(result.y), int(result.width), int(result.height), scale
} }
func windowGetAbsolutePosition(window pointer) (int, int) {
var x C.int
var y C.int
C.gtk_window_get_position((*C.GtkWindow)(window), &x, &y)
return int(x), int(y)
}
func windowGetSize(window pointer) (int, int) { func windowGetSize(window pointer) (int, int) {
var windowWidth C.int var windowWidth C.int
var windowHeight C.int var windowHeight C.int
@ -740,11 +734,11 @@ func windowGetSize(window pointer) (int, int) {
return int(windowWidth), int(windowHeight) return int(windowWidth), int(windowHeight)
} }
func windowGetRelativePosition(window pointer) (int, int) { func (w *linuxWebviewWindow) relativePosition() (int, int) {
x, y := windowGetAbsolutePosition(window) x, y := w.absolutePosition()
// The position must be relative to the screen it is on // The position must be relative to the screen it is on
// We need to get the screen it is on // We need to get the screen it is on
monitor := windowGetCurrentMonitor(window) monitor := windowGetCurrentMonitor(w.window)
geometry := C.GdkRectangle{} geometry := C.GdkRectangle{}
C.gdk_monitor_get_geometry(monitor, &geometry) C.gdk_monitor_get_geometry(monitor, &geometry)
x = x - int(geometry.x) x = x - int(geometry.x)
@ -755,46 +749,52 @@ func windowGetRelativePosition(window pointer) (int, int) {
return x, y return x, y
} }
func windowHide(window pointer) { func (w *linuxWebviewWindow) gtkWidget() *C.GtkWidget {
C.gtk_widget_hide((*C.GtkWidget)(window)) return (*C.GtkWidget)(w.window)
} }
func windowIsFullscreen(window pointer) bool { func (w *linuxWebviewWindow) hide() {
gdkwindow := C.gtk_widget_get_window((*C.GtkWidget)(window)) // save position
state := C.gdk_window_get_state(gdkwindow) w.lastX, w.lastY = w.absolutePosition()
C.gtk_widget_hide(w.gtkWidget())
}
func (w *linuxWebviewWindow) isFullscreen() bool {
gdkWindow := C.gtk_widget_get_window((*C.GtkWidget)(w.window))
state := C.gdk_window_get_state(gdkWindow)
return state&C.GDK_WINDOW_STATE_FULLSCREEN > 0 return state&C.GDK_WINDOW_STATE_FULLSCREEN > 0
} }
func windowIsFocused(window pointer) bool { func (w *linuxWebviewWindow) isFocused() bool {
// returns true if window is focused // returns true if window is focused
return C.gtk_window_has_toplevel_focus((*C.GtkWindow)(window)) == 1 return C.gtk_window_has_toplevel_focus((*C.GtkWindow)(w.window)) == 1
} }
func windowIsMaximized(window pointer) bool { func (w *linuxWebviewWindow) isMaximised() bool {
gdkwindow := C.gtk_widget_get_window((*C.GtkWidget)(window)) gdkwindow := C.gtk_widget_get_window((*C.GtkWidget)(w.window))
state := C.gdk_window_get_state(gdkwindow) state := C.gdk_window_get_state(gdkwindow)
return state&C.GDK_WINDOW_STATE_MAXIMIZED > 0 && state&C.GDK_WINDOW_STATE_FULLSCREEN == 0 return state&C.GDK_WINDOW_STATE_MAXIMIZED > 0 && state&C.GDK_WINDOW_STATE_FULLSCREEN == 0
} }
func windowIsMinimized(window pointer) bool { func (w *linuxWebviewWindow) isMinimised() bool {
gdkwindow := C.gtk_widget_get_window((*C.GtkWidget)(window)) gdkwindow := C.gtk_widget_get_window((*C.GtkWidget)(w.window))
state := C.gdk_window_get_state(gdkwindow) state := C.gdk_window_get_state(gdkwindow)
return state&C.GDK_WINDOW_STATE_ICONIFIED > 0 return state&C.GDK_WINDOW_STATE_ICONIFIED > 0
} }
func windowIsVisible(window pointer) bool { func (w *linuxWebviewWindow) isVisible() bool {
if C.gtk_widget_is_visible((*C.GtkWidget)(window)) == 1 { if C.gtk_widget_is_visible(w.gtkWidget()) == 1 {
return true return true
} }
return false return false
} }
func windowMaximize(window pointer) { func (w *linuxWebviewWindow) maximise() {
C.gtk_window_maximize((*C.GtkWindow)(window)) C.gtk_window_maximize((*C.GtkWindow)(w.window))
} }
func windowMinimize(window pointer) { func (w *linuxWebviewWindow) minimise() {
C.gtk_window_iconify((*C.GtkWindow)(window)) C.gtk_window_iconify((*C.GtkWindow)(w.window))
} }
func windowNew(application pointer, menu pointer, windowId uint, gpuPolicy WebviewGpuPolicy) (window, webview, vbox pointer) { func windowNew(application pointer, menu pointer, windowId uint, gpuPolicy WebviewGpuPolicy) (window, webview, vbox pointer) {
@ -849,26 +849,24 @@ func windowNewWebview(parentId uint, gpuPolicy WebviewGpuPolicy) pointer {
return pointer(webView) return pointer(webView)
} }
func windowPresent(window pointer) { func (w *linuxWebviewWindow) present() {
C.gtk_window_present((*C.GtkWindow)(window)) C.gtk_window_present((*C.GtkWindow)(w.window))
// gtk_window_unminimize ((*C.GtkWindow)(w.window)) /// gtk4 // gtk_window_unminimize ((*C.GtkWindow)(w.window)) /// gtk4
} }
func windowReload(webview pointer, address string) { func (w *linuxWebviewWindow) setSize(width, height int) {
uri := C.CString(address)
C.webkit_web_view_load_uri((*C.WebKitWebView)(webview), uri)
C.free(unsafe.Pointer(uri))
}
func windowResize(window pointer, width, height int) {
C.gtk_window_resize( C.gtk_window_resize(
(*C.GtkWindow)(window), w.gtkWindow(),
C.gint(width), C.gint(width),
C.gint(height)) C.gint(height))
} }
func windowShow(window pointer) { func (w *linuxWebviewWindow) show() {
C.gtk_widget_show_all((*C.GtkWidget)(window)) if w.gtkWidget() == nil {
return
}
C.gtk_widget_show_all(w.gtkWidget())
w.setAbsolutePosition(w.lastX, w.lastY)
} }
func windowIgnoreMouseEvents(window pointer, webview pointer, ignore bool) { func windowIgnoreMouseEvents(window pointer, webview pointer, ignore bool) {
@ -881,15 +879,27 @@ func windowIgnoreMouseEvents(window pointer, webview pointer, ignore bool) {
C.webkit_web_view_set_editable((*C.WebKitWebView)(webview), C.gboolean(enable)) C.webkit_web_view_set_editable((*C.WebKitWebView)(webview), C.gboolean(enable))
} }
func windowSetBackgroundColour(vbox, webview pointer, colour RGBA) { func (w *linuxWebviewWindow) webKitWebView() *C.WebKitWebView {
return (*C.WebKitWebView)(w.webview)
}
func (w *linuxWebviewWindow) setBorderless(borderless bool) {
C.gtk_window_set_decorated(w.gtkWindow(), gtkBool(!borderless))
}
func (w *linuxWebviewWindow) setResizable(resizable bool) {
C.gtk_window_set_resizable(w.gtkWindow(), gtkBool(resizable))
}
func (w *linuxWebviewWindow) setBackgroundColour(colour RGBA) {
rgba := C.GdkRGBA{C.double(colour.Red) / 255.0, C.double(colour.Green) / 255.0, C.double(colour.Blue) / 255.0, C.double(colour.Alpha) / 255.0} rgba := C.GdkRGBA{C.double(colour.Red) / 255.0, C.double(colour.Green) / 255.0, C.double(colour.Blue) / 255.0, C.double(colour.Alpha) / 255.0}
C.webkit_web_view_set_background_color((*C.WebKitWebView)(webview), &rgba) C.webkit_web_view_set_background_color((*C.WebKitWebView)(w.webview), &rgba)
colour.Alpha = 255 colour.Alpha = 255
cssStr := C.CString(fmt.Sprintf("#webview-box {background-color: rgba(%d, %d, %d, %1.1f);}", colour.Red, colour.Green, colour.Blue, float32(colour.Alpha)/255.0)) cssStr := C.CString(fmt.Sprintf("#webview-box {background-color: rgba(%d, %d, %d, %1.1f);}", colour.Red, colour.Green, colour.Blue, float32(colour.Alpha)/255.0))
provider := C.gtk_css_provider_new() provider := C.gtk_css_provider_new()
C.gtk_style_context_add_provider( C.gtk_style_context_add_provider(
C.gtk_widget_get_style_context((*C.GtkWidget)(vbox)), C.gtk_widget_get_style_context((*C.GtkWidget)(w.vbox)),
(*C.GtkStyleProvider)(unsafe.Pointer(provider)), (*C.GtkStyleProvider)(unsafe.Pointer(provider)),
C.GTK_STYLE_PROVIDER_PRIORITY_USER) C.GTK_STYLE_PROVIDER_PRIORITY_USER)
C.g_object_unref(C.gpointer(provider)) C.g_object_unref(C.gpointer(provider))
@ -907,14 +917,14 @@ func windowSetGeometryHints(window pointer, minWidth, minHeight, maxWidth, maxHe
C.gtk_window_set_geometry_hints((*C.GtkWindow)(window), nil, &size, C.GDK_HINT_MAX_SIZE|C.GDK_HINT_MIN_SIZE) C.gtk_window_set_geometry_hints((*C.GtkWindow)(window), nil, &size, C.GDK_HINT_MAX_SIZE|C.GDK_HINT_MIN_SIZE)
} }
func windowSetFrameless(window pointer, frameless bool) { func (w *linuxWebviewWindow) setFrameless(frameless bool) {
C.gtk_window_set_decorated((*C.GtkWindow)(window), gtkBool(!frameless)) C.gtk_window_set_decorated(w.gtkWindow(), gtkBool(!frameless))
// TODO: Deal with transparency for the titlebar if possible when !frameless // TODO: Deal with transparency for the titlebar if possible when !frameless
// Perhaps we just make it undecorated and add a menu bar inside? // Perhaps we just make it undecorated and add a menu bar inside?
} }
// TODO: confirm this is working properly // TODO: confirm this is working properly
func windowSetHTML(webview pointer, html string) { func (w *linuxWebviewWindow) setHTML(html string) {
cHTML := C.CString(html) cHTML := C.CString(html)
uri := C.CString("wails://") uri := C.CString("wails://")
empty := C.CString("") empty := C.CString("")
@ -922,39 +932,41 @@ func windowSetHTML(webview pointer, html string) {
defer C.free(unsafe.Pointer(uri)) defer C.free(unsafe.Pointer(uri))
defer C.free(unsafe.Pointer(empty)) defer C.free(unsafe.Pointer(empty))
C.webkit_web_view_load_alternate_html( C.webkit_web_view_load_alternate_html(
(*C.WebKitWebView)(webview), w.webKitWebView(),
cHTML, cHTML,
uri, uri,
empty) empty)
} }
func windowSetKeepAbove(window pointer, alwaysOnTop bool) { func (w *linuxWebviewWindow) setAlwaysOnTop(alwaysOnTop bool) {
C.gtk_window_set_keep_above((*C.GtkWindow)(window), gtkBool(alwaysOnTop)) C.gtk_window_set_keep_above((*C.GtkWindow)(w.window), gtkBool(alwaysOnTop))
} }
func windowSetResizable(window pointer, resizable bool) { func (w *linuxWebviewWindow) setTitle(title string) {
C.gtk_window_set_resizable((*C.GtkWindow)(window), gtkBool(resizable)) if !w.parent.options.Frameless {
}
func windowSetTitle(window pointer, title string) {
cTitle := C.CString(title) cTitle := C.CString(title)
C.gtk_window_set_title((*C.GtkWindow)(window), cTitle) C.gtk_window_set_title(w.gtkWindow(), cTitle)
C.free(unsafe.Pointer(cTitle)) C.free(unsafe.Pointer(cTitle))
}
func windowSetTransparent(window pointer) {
screen := C.gtk_widget_get_screen((*C.GtkWidget)(window))
visual := C.gdk_screen_get_rgba_visual(screen)
if visual != nil && C.gdk_screen_is_composited(screen) == C.int(1) {
C.gtk_widget_set_app_paintable((*C.GtkWidget)(window), C.gboolean(1))
C.gtk_widget_set_visual((*C.GtkWidget)(window), visual)
} }
} }
func windowSetURL(webview pointer, uri string) { func (w *linuxWebviewWindow) gtkWindow() *C.GtkWindow {
return (*C.GtkWindow)(w.window)
}
func (w *linuxWebviewWindow) setTransparent() {
screen := C.gtk_widget_get_screen(w.gtkWidget())
visual := C.gdk_screen_get_rgba_visual(screen)
if visual != nil && C.gdk_screen_is_composited(screen) == C.int(1) {
C.gtk_widget_set_app_paintable(w.gtkWidget(), C.gboolean(1))
C.gtk_widget_set_visual(w.gtkWidget(), visual)
}
}
func (w *linuxWebviewWindow) setURL(uri string) {
target := C.CString(uri) target := C.CString(uri)
C.webkit_web_view_load_uri((*C.WebKitWebView)(webview), target) C.webkit_web_view_load_uri((*C.WebKitWebView)(w.webview), target)
C.free(unsafe.Pointer(target)) C.free(unsafe.Pointer(target))
} }
@ -983,22 +995,23 @@ func handleLoadChanged(webview *C.WebKitWebView, event C.WebKitLoadEvent, data C
} }
} }
func windowSetupSignalHandlers(windowId uint, window, webview pointer, emit func(e events.WindowEventType)) { func (w *linuxWebviewWindow) setupSignalHandlers(emit func(e events.WindowEventType)) {
c := NewCalloc() c := NewCalloc()
defer c.Free() defer c.Free()
winID := unsafe.Pointer(uintptr(C.uint(windowId))) winID := unsafe.Pointer(uintptr(C.uint(w.parent.ID())))
// Set up the window close event // Set up the window close event
C.signal_connect(unsafe.Pointer(window), c.String("delete-event"), C.handleDeleteEvent, winID) wv := unsafe.Pointer(w.webview)
C.signal_connect(unsafe.Pointer(webview), c.String("load-changed"), C.handleLoadChanged, winID) C.signal_connect(unsafe.Pointer(w.window), c.String("delete-event"), C.handleDeleteEvent, winID)
C.signal_connect(wv, c.String("load-changed"), C.handleLoadChanged, winID)
contentManager := C.webkit_web_view_get_user_content_manager((*C.WebKitWebView)(webview)) contentManager := C.webkit_web_view_get_user_content_manager(w.webKitWebView())
C.signal_connect(unsafe.Pointer(contentManager), c.String("script-message-received::external"), C.sendMessageToBackend, nil) C.signal_connect(unsafe.Pointer(contentManager), c.String("script-message-received::external"), C.sendMessageToBackend, nil)
C.signal_connect(unsafe.Pointer(webview), c.String("button-press-event"), C.onButtonEvent, winID) C.signal_connect(wv, c.String("button-press-event"), C.onButtonEvent, winID)
C.signal_connect(unsafe.Pointer(webview), c.String("button-release-event"), C.onButtonEvent, winID) C.signal_connect(wv, c.String("button-release-event"), C.onButtonEvent, winID)
C.signal_connect(unsafe.Pointer(webview), c.String("key-press-event"), C.onKeyPressEvent, winID) C.signal_connect(wv, c.String("key-press-event"), C.onKeyPressEvent, winID)
} }
func windowShowDevTools(webview pointer) { func windowShowDevTools(webview pointer) {
@ -1006,13 +1019,14 @@ func windowShowDevTools(webview pointer) {
C.webkit_web_inspector_show(inspector) C.webkit_web_inspector_show(inspector)
} }
func windowStartDrag(window pointer, button uint, xroot int, yroot int, dragTime uint32) { func (w *linuxWebviewWindow) startDrag() error {
C.gtk_window_begin_move_drag( C.gtk_window_begin_move_drag(
(*C.GtkWindow)(window), (*C.GtkWindow)(w.window),
C.int(button), C.int(w.drag.MouseButton),
C.int(xroot), C.int(w.drag.XRoot),
C.int(yroot), C.int(w.drag.YRoot),
C.uint32_t(dragTime)) C.uint32_t(w.drag.DragTime))
return nil
} }
func windowToggleDevTools(webview pointer) { func windowToggleDevTools(webview pointer) {
@ -1027,37 +1041,56 @@ func windowToggleDevTools(webview pointer) {
C.webkit_settings_set_enable_developer_extras(settings, enabled) C.webkit_settings_set_enable_developer_extras(settings, enabled)
} }
func windowUnfullscreen(window pointer) { func (w *linuxWebviewWindow) unfullscreen() {
C.gtk_window_unfullscreen((*C.GtkWindow)(window)) C.gtk_window_unfullscreen((*C.GtkWindow)(w.window))
w.unmaximise()
} }
func windowUnmaximize(window pointer) { func (w *linuxWebviewWindow) unmaximise() {
C.gtk_window_unmaximize((*C.GtkWindow)(window)) C.gtk_window_unmaximize((*C.GtkWindow)(w.window))
} }
func windowZoom(webview pointer) float64 { func (w *linuxWebviewWindow) getZoom() float64 {
return float64(C.webkit_web_view_get_zoom_level((*C.WebKitWebView)(webview))) return float64(C.webkit_web_view_get_zoom_level(w.webKitWebView()))
} }
// FIXME: ZoomIn/Out is assumed to be incorrect! func (w *linuxWebviewWindow) zoomIn() {
func windowZoomIn(webview pointer) { // FIXME: ZoomIn/Out is assumed to be incorrect!
ZoomInFactor := 1.10 ZoomInFactor := 1.10
windowZoomSet(webview, windowZoom(webview)*ZoomInFactor) w.setZoom(w.getZoom() * ZoomInFactor)
}
func windowZoomOut(webview pointer) {
ZoomOutFactor := -1.10
windowZoomSet(webview, windowZoom(webview)*ZoomOutFactor)
} }
func windowZoomSet(webview pointer, zoom float64) { func (w *linuxWebviewWindow) zoomOut() {
ZoomInFactor := -1.10
w.setZoom(w.getZoom() * ZoomInFactor)
}
func (w *linuxWebviewWindow) zoomReset() {
w.setZoom(1.0)
}
func (w *linuxWebviewWindow) reload() {
uri := C.CString("wails://")
C.webkit_web_view_load_uri((*C.WebKitWebView)(w.webview), uri)
C.free(unsafe.Pointer(uri))
}
func (w *linuxWebviewWindow) setZoom(zoom float64) {
if zoom < 1 { // 1.0 is the smallest allowable if zoom < 1 { // 1.0 is the smallest allowable
zoom = 1 zoom = 1
} }
C.webkit_web_view_set_zoom_level((*C.WebKitWebView)(webview), C.double(zoom)) C.webkit_web_view_set_zoom_level(w.webKitWebView(), C.double(zoom))
} }
func windowMove(window pointer, x, y int) { func (w *linuxWebviewWindow) move(x, y int) {
C.gtk_window_move((*C.GtkWindow)(window), C.int(x), C.int(y)) C.gtk_window_move((*C.GtkWindow)(w.window), C.int(x), C.int(y))
}
func (w *linuxWebviewWindow) absolutePosition() (int, int) {
var x C.int
var y C.int
C.gtk_window_get_position((*C.GtkWindow)(w.window), &x, &y)
return int(x), int(y)
} }
// FIXME Change this to reflect mouse button! // FIXME Change this to reflect mouse button!

View File

@ -2,7 +2,7 @@
package application package application
func (l *linuxApp) dispatchOnMainThread(id uint) { func (a *linuxApp) dispatchOnMainThread(id uint) {
dispatchOnMainThread(id) dispatchOnMainThread(id)
} }

View File

@ -7,17 +7,17 @@ import (
"sync" "sync"
) )
func (l *linuxApp) getPrimaryScreen() (*Screen, error) { func (a *linuxApp) getPrimaryScreen() (*Screen, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }
func (l *linuxApp) getScreens() ([]*Screen, error) { func (a *linuxApp) getScreens() ([]*Screen, error) {
var wg sync.WaitGroup var wg sync.WaitGroup
var screens []*Screen var screens []*Screen
var err error var err error
wg.Add(1) wg.Add(1)
InvokeSync(func() { InvokeSync(func() {
screens, err = getScreens(l.application) screens, err = getScreens(a.application)
wg.Done() wg.Done()
}) })
wg.Wait() wg.Wait()

View File

@ -9,6 +9,7 @@ import (
"github.com/wailsapp/wails/v3/internal/capabilities" "github.com/wailsapp/wails/v3/internal/capabilities"
"github.com/wailsapp/wails/v3/internal/runtime" "github.com/wailsapp/wails/v3/internal/runtime"
"github.com/wailsapp/wails/v3/pkg/events" "github.com/wailsapp/wails/v3/pkg/events"
"math"
) )
var showDevTools = func(window pointer) {} var showDevTools = func(window pointer) {}
@ -41,26 +42,17 @@ var (
registered bool = false // avoid 'already registered message' about 'wails://' registered bool = false // avoid 'already registered message' about 'wails://'
) )
func (w *linuxWebviewWindow) startDrag() error {
windowStartDrag(w.window, w.drag.MouseButton, w.drag.XRoot, w.drag.YRoot, w.drag.DragTime)
return nil
}
func (w *linuxWebviewWindow) endDrag(button uint, x, y int) { func (w *linuxWebviewWindow) endDrag(button uint, x, y int) {
w.drag.XRoot = 0.0 w.drag.XRoot = 0.0
w.drag.YRoot = 0.0 w.drag.YRoot = 0.0
w.drag.DragTime = 0 w.drag.DragTime = 0
} }
func (w *linuxWebviewWindow) enableDND() {
windowEnableDND(w.parent.id, w.webview)
}
func (w *linuxWebviewWindow) connectSignals() { func (w *linuxWebviewWindow) connectSignals() {
cb := func(e events.WindowEventType) { cb := func(e events.WindowEventType) {
w.parent.emit(e) w.parent.emit(e)
} }
windowSetupSignalHandlers(w.parent.id, w.window, w.webview, cb) w.setupSignalHandlers(cb)
} }
func (w *linuxWebviewWindow) openContextMenu(menu *Menu, data *ContextMenuData) { func (w *linuxWebviewWindow) openContextMenu(menu *Menu, data *ContextMenuData) {
@ -74,23 +66,11 @@ func (w *linuxWebviewWindow) openContextMenu(menu *Menu, data *ContextMenuData)
} }
native := ctxMenu.menu.impl.(*linuxMenu).native native := ctxMenu.menu.impl.(*linuxMenu).native
contextMenuShow(w.window, native, data) w.contextMenuShow(native, data)
}
func (w *linuxWebviewWindow) getZoom() float64 {
return windowZoom(w.webview)
}
func (w *linuxWebviewWindow) setZoom(zoom float64) {
windowZoomSet(w.webview, zoom)
}
func (w *linuxWebviewWindow) setFrameless(frameless bool) {
windowSetFrameless(w.window, frameless)
} }
func (w *linuxWebviewWindow) getScreen() (*Screen, error) { func (w *linuxWebviewWindow) getScreen() (*Screen, error) {
mx, my, width, height, scale := windowGetCurrentMonitorGeometry(w.window) mx, my, width, height, scale := w.getCurrentMonitorGeometry()
return &Screen{ return &Screen{
ID: fmt.Sprintf("%d", w.id), // A unique identifier for the display ID: fmt.Sprintf("%d", w.id), // A unique identifier for the display
Name: w.parent.Name(), // The name of the display Name: w.parent.Name(), // The name of the display
@ -106,47 +86,27 @@ func (w *linuxWebviewWindow) getScreen() (*Screen, error) {
} }
func (w *linuxWebviewWindow) focus() { func (w *linuxWebviewWindow) focus() {
windowPresent(w.window) w.present()
}
func (w *linuxWebviewWindow) show() {
windowShow(w.window)
w.setAbsolutePosition(w.lastX, w.lastY)
}
func (w *linuxWebviewWindow) hide() {
// save position
w.lastX, w.lastY = windowGetAbsolutePosition(w.window)
windowHide(w.window)
} }
func (w *linuxWebviewWindow) isNormal() bool { func (w *linuxWebviewWindow) isNormal() bool {
return !w.isMinimised() && !w.isMaximised() && !w.isFullscreen() return !w.isMinimised() && !w.isMaximised() && !w.isFullscreen()
} }
func (w *linuxWebviewWindow) isVisible() bool {
return windowIsVisible(w.window)
}
func (w *linuxWebviewWindow) setFullscreenButtonEnabled(enabled bool) { func (w *linuxWebviewWindow) setFullscreenButtonEnabled(enabled bool) {
// C.setFullscreenButtonEnabled(w.nsWindow, C.bool(enabled)) // C.setFullscreenButtonEnabled(w.nsWindow, C.bool(enabled))
fmt.Println("setFullscreenButtonEnabled - not implemented") fmt.Println("setFullscreenButtonEnabled - not implemented")
} }
func (w *linuxWebviewWindow) disableSizeConstraints() { func (w *linuxWebviewWindow) disableSizeConstraints() {
x, y, width, height, scale := windowGetCurrentMonitorGeometry(w.window) x, y, width, height, scale := w.getCurrentMonitorGeometry()
w.setMinMaxSize(x, y, width*scale, height*scale) w.setMinMaxSize(x, y, width*scale, height*scale)
} }
func (w *linuxWebviewWindow) unfullscreen() {
windowUnfullscreen(w.window)
w.unmaximise()
}
func (w *linuxWebviewWindow) fullscreen() { func (w *linuxWebviewWindow) fullscreen() {
w.maximise() w.maximise()
//w.lastWidth, w.lastHeight = w.size() //w.lastWidth, w.lastHeight = w.size()
x, y, width, height, scale := windowGetCurrentMonitorGeometry(w.window) x, y, width, height, scale := w.getCurrentMonitorGeometry()
if x == -1 && y == -1 && width == -1 && height == -1 { if x == -1 && y == -1 && width == -1 && height == -1 {
return return
} }
@ -157,19 +117,7 @@ func (w *linuxWebviewWindow) fullscreen() {
} }
func (w *linuxWebviewWindow) unminimise() { func (w *linuxWebviewWindow) unminimise() {
windowPresent(w.window) w.present()
}
func (w *linuxWebviewWindow) unmaximise() {
windowUnmaximize(w.window)
}
func (w *linuxWebviewWindow) maximise() {
windowMaximize(w.window)
}
func (w *linuxWebviewWindow) minimise() {
windowMinimize(w.window)
} }
func (w *linuxWebviewWindow) flash(enabled bool) { func (w *linuxWebviewWindow) flash(enabled bool) {
@ -189,59 +137,22 @@ func (w *linuxWebviewWindow) windowZoom() {
w.zoom() // FIXME> This should be removed w.zoom() // FIXME> This should be removed
} }
func (w *linuxWebviewWindow) close() {
windowClose(w.window)
getNativeApplication().unregisterWindow(windowPointer(w.window))
}
func (w *linuxWebviewWindow) zoomIn() {
windowZoomIn(w.webview)
}
func (w *linuxWebviewWindow) zoomOut() {
windowZoomOut(w.webview)
}
func (w *linuxWebviewWindow) zoomReset() {
windowZoomSet(w.webview, 1.0)
}
func (w *linuxWebviewWindow) reload() {
windowReload(w.webview, "wails://")
}
func (w *linuxWebviewWindow) forceReload() { func (w *linuxWebviewWindow) forceReload() {
w.reload() w.reload()
} }
func (w *linuxWebviewWindow) center() { func (w *linuxWebviewWindow) center() {
x, y, width, height, _ := windowGetCurrentMonitorGeometry(w.window) x, y, width, height, _ := w.getCurrentMonitorGeometry()
if x == -1 && y == -1 && width == -1 && height == -1 { if x == -1 && y == -1 && width == -1 && height == -1 {
return return
} }
windowWidth, windowHeight := windowGetSize(w.window) windowWidth, windowHeight := windowGetSize(w.window)
newX := ((width - int(windowWidth)) / 2) + x newX := ((width - windowWidth) / 2) + x
newY := ((height - int(windowHeight)) / 2) + y newY := ((height - windowHeight) / 2) + y
// Place the window at the center of the monitor // Place the window at the center of the monitor
windowMove(w.window, newX, newY) w.move(newX, newY)
}
func (w *linuxWebviewWindow) isMinimised() bool {
return windowIsMinimized(w.window)
}
func (w *linuxWebviewWindow) isMaximised() bool {
return windowIsMaximized(w.window)
}
func (w *linuxWebviewWindow) isFocused() bool {
return windowIsFocused(w.window)
}
func (w *linuxWebviewWindow) isFullscreen() bool {
return windowIsFullscreen(w.window)
} }
func (w *linuxWebviewWindow) restore() { func (w *linuxWebviewWindow) restore() {
@ -249,18 +160,6 @@ func (w *linuxWebviewWindow) restore() {
// FIXME: never called! - remove from webviewImpl interface // FIXME: never called! - remove from webviewImpl interface
} }
func (w *linuxWebviewWindow) execJS(js string) {
windowExecJS(w.webview, js)
}
func (w *linuxWebviewWindow) setURL(uri string) {
windowSetURL(w.webview, uri)
}
func (w *linuxWebviewWindow) setAlwaysOnTop(alwaysOnTop bool) {
windowSetKeepAbove(w.window, alwaysOnTop)
}
func newWindowImpl(parent *WebviewWindow) *linuxWebviewWindow { func newWindowImpl(parent *WebviewWindow) *linuxWebviewWindow {
// (*C.struct__GtkWidget)(m.native) // (*C.struct__GtkWidget)(m.native)
//var menubar *C.struct__GtkWidget //var menubar *C.struct__GtkWidget
@ -272,16 +171,6 @@ func newWindowImpl(parent *WebviewWindow) *linuxWebviewWindow {
return result return result
} }
func (w *linuxWebviewWindow) setTitle(title string) {
if !w.parent.options.Frameless {
windowSetTitle(w.window, title)
}
}
func (w *linuxWebviewWindow) setSize(width, height int) {
windowResize(w.window, width, height)
}
func (w *linuxWebviewWindow) setMinMaxSize(minWidth, minHeight, maxWidth, maxHeight int) { func (w *linuxWebviewWindow) setMinMaxSize(minWidth, minHeight, maxWidth, maxHeight int) {
if minWidth == 0 { if minWidth == 0 {
minWidth = -1 minWidth = -1
@ -290,10 +179,10 @@ func (w *linuxWebviewWindow) setMinMaxSize(minWidth, minHeight, maxWidth, maxHei
minHeight = -1 minHeight = -1
} }
if maxWidth == 0 { if maxWidth == 0 {
maxWidth = -1 maxWidth = math.MaxInt
} }
if maxHeight == 0 { if maxHeight == 0 {
maxHeight = -1 maxHeight = math.MaxInt
} }
windowSetGeometryHints(w.window, minWidth, minHeight, maxWidth, maxHeight) windowSetGeometryHints(w.window, minWidth, minHeight, maxWidth, maxHeight)
} }
@ -306,10 +195,6 @@ func (w *linuxWebviewWindow) setMaxSize(width, height int) {
w.setMinMaxSize(w.parent.options.MinWidth, w.parent.options.MinHeight, width, height) w.setMinMaxSize(w.parent.options.MinWidth, w.parent.options.MinHeight, width, height)
} }
func (w *linuxWebviewWindow) setResizable(resizable bool) {
windowSetResizable(w.window, resizable)
}
func (w *linuxWebviewWindow) showDevTools() { func (w *linuxWebviewWindow) showDevTools() {
windowShowDevTools(w.webview) windowShowDevTools(w.webview)
} }
@ -323,8 +208,8 @@ func (w *linuxWebviewWindow) size() (int, int) {
} }
func (w *linuxWebviewWindow) setRelativePosition(x, y int) { func (w *linuxWebviewWindow) setRelativePosition(x, y int) {
mx, my, _, _, _ := windowGetCurrentMonitorGeometry(w.window) mx, my, _, _, _ := w.getCurrentMonitorGeometry()
windowMove(w.window, x+mx, y+my) w.move(x+mx, y+my)
} }
func (w *linuxWebviewWindow) width() int { func (w *linuxWebviewWindow) width() int {
@ -339,13 +224,7 @@ func (w *linuxWebviewWindow) height() int {
func (w *linuxWebviewWindow) setAbsolutePosition(x int, y int) { func (w *linuxWebviewWindow) setAbsolutePosition(x int, y int) {
// Set the window's absolute position // Set the window's absolute position
windowMove(w.window, x, y) w.move(x, y)
}
func (w *linuxWebviewWindow) absolutePosition() (int, int) {
var x, y int
x, y = windowGetAbsolutePosition(w.window)
return x, y
} }
func (w *linuxWebviewWindow) run() { func (w *linuxWebviewWindow) run() {
@ -459,20 +338,6 @@ func (w *linuxWebviewWindow) run() {
} }
} }
func (w *linuxWebviewWindow) setTransparent() {
windowSetTransparent(w.window)
}
func (w *linuxWebviewWindow) setBackgroundColour(colour RGBA) {
windowSetBackgroundColour(w.vbox, w.webview, colour)
}
func (w *linuxWebviewWindow) relativePosition() (int, int) {
var x, y int
x, y = windowGetRelativePosition(w.window)
return x, y
}
func (w *linuxWebviewWindow) destroy() { func (w *linuxWebviewWindow) destroy() {
w.parent.markAsDestroyed() w.parent.markAsDestroyed()
// Free menu // Free menu
@ -487,10 +352,6 @@ func (w *linuxWebviewWindow) setEnabled(enabled bool) {
widgetSetSensitive(w.window, enabled) widgetSetSensitive(w.window, enabled)
} }
func (w *linuxWebviewWindow) setHTML(html string) {
windowSetHTML(w.webview, html)
}
func (w *linuxWebviewWindow) startResize(border string) error { func (w *linuxWebviewWindow) startResize(border string) error {
// FIXME: what do we need to do here? // FIXME: what do we need to do here?
return nil return nil