diff --git a/v2/internal/frontend/desktop/linux/frontend.go b/v2/internal/frontend/desktop/linux/frontend.go index dce5b2531..b07fe9866 100644 --- a/v2/internal/frontend/desktop/linux/frontend.go +++ b/v2/internal/frontend/desktop/linux/frontend.go @@ -21,6 +21,7 @@ import ( "os" "runtime" "strconv" + "strings" "text/template" "unsafe" @@ -183,10 +184,16 @@ func (f *Frontend) WindowSetTitle(title string) { } func (f *Frontend) WindowFullscreen() { + if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false { + f.ExecJS("window.wails.flags.enableResize = false;") + } f.mainWindow.Fullscreen() } func (f *Frontend) WindowUnfullscreen() { + if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false { + f.ExecJS("window.wails.flags.enableResize = true;") + } f.mainWindow.UnFullscreen() } @@ -289,6 +296,17 @@ func (f *Frontend) Notify(name string, data ...interface{}) { f.mainWindow.ExecJS(`window.wails.EventsNotify('` + template.JSEscapeString(string(payload)) + `');`) } +var edgeMap = map[string]uintptr{ + "n-resize": C.GDK_WINDOW_EDGE_NORTH, + "ne-resize": C.GDK_WINDOW_EDGE_NORTH_EAST, + "e-resize": C.GDK_WINDOW_EDGE_EAST, + "se-resize": C.GDK_WINDOW_EDGE_SOUTH_EAST, + "s-resize": C.GDK_WINDOW_EDGE_SOUTH, + "sw-resize": C.GDK_WINDOW_EDGE_SOUTH_WEST, + "w-resize": C.GDK_WINDOW_EDGE_WEST, + "nw-resize": C.GDK_WINDOW_EDGE_NORTH_WEST, +} + func (f *Frontend) processMessage(message string) { if message == "DomReady" { if f.frontendOptions.OnDomReady != nil { @@ -304,9 +322,29 @@ func (f *Frontend) processMessage(message string) { return } + if strings.HasPrefix(message, "resize:") { + if !f.mainWindow.IsFullScreen() { + sl := strings.Split(message, ":") + if len(sl) != 2 { + f.logger.Info("Unknown message returned from dispatcher: %+v", message) + return + } + edge := edgeMap[sl[1]] + err := f.startResize(edge) + if err != nil { + f.logger.Error(err.Error()) + } + } + return + } + if message == "runtime:ready" { cmd := fmt.Sprintf("window.wails.setCSSDragProperties('%s', '%s');", f.frontendOptions.CSSDragProperty, f.frontendOptions.CSSDragValue) f.ExecJS(cmd) + + if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false { + f.ExecJS("window.wails.flags.enableResize = true;") + } return } @@ -339,6 +377,11 @@ func (f *Frontend) startDrag() { f.mainWindow.StartDrag() } +func (f *Frontend) startResize(edge uintptr) error { + f.mainWindow.StartResize(edge) + return nil +} + func (f *Frontend) ExecJS(js string) { f.mainWindow.ExecJS(js) } diff --git a/v2/internal/frontend/desktop/linux/window.go b/v2/internal/frontend/desktop/linux/window.go index ef6ecafb6..1f119e526 100644 --- a/v2/internal/frontend/desktop/linux/window.go +++ b/v2/internal/frontend/desktop/linux/window.go @@ -159,11 +159,12 @@ ulong setupInvokeSignal(void* contentManager) { return g_signal_connect((WebKitUserContentManager*)contentManager, "script-message-received::external", G_CALLBACK(sendMessageToBackend), NULL); } -// These are the x,y & time of the last mouse down event +// These are the x,y,time & button of the last mouse down event // It's used for window dragging float xroot = 0.0f; float yroot = 0.0f; int dragTime = -1; +uint mouseButton = 0; bool contextMenuDisabled = false; gboolean buttonPress(GtkWidget *widget, GdkEventButton *event, void* dummy) @@ -173,7 +174,7 @@ gboolean buttonPress(GtkWidget *widget, GdkEventButton *event, void* dummy) dragTime = -1; return FALSE; } - + mouseButton = event->button; if( event->button == 3 && contextMenuDisabled ) { return TRUE; } @@ -256,7 +257,7 @@ static gboolean startDrag(gpointer data) { return G_SOURCE_REMOVE; } - gtk_window_begin_move_drag(options->mainwindow, 1, xroot, yroot, dragTime); + gtk_window_begin_move_drag(options->mainwindow, mouseButton, xroot, yroot, dragTime); free(data); return G_SOURCE_REMOVE; @@ -269,6 +270,36 @@ static void StartDrag(void *webview, GtkWindow* mainwindow) { ExecuteOnMainThread(startDrag, (gpointer)data); } +typedef struct ResizeOptions { + void *webview; + GtkWindow* mainwindow; + GdkWindowEdge edge; +} ResizeOptions; + +static gboolean startResize(gpointer data) { + ResizeOptions* options = (ResizeOptions*)data; + + // Ignore non-toplevel widgets + GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(options->webview)); + if (!GTK_IS_WINDOW(window)) { + free(data); + return G_SOURCE_REMOVE; + } + + gtk_window_begin_resize_drag(options->mainwindow, options->edge, 1, xroot, yroot, dragTime); + free(data); + + return G_SOURCE_REMOVE; +} + +static void StartResize(void *webview, GtkWindow* mainwindow, GdkWindowEdge edge) { + ResizeOptions* data = malloc(sizeof(ResizeOptions)); + data->webview = webview; + data->mainwindow = mainwindow; + data->edge = edge; + ExecuteOnMainThread(startResize, (gpointer)data); +} + typedef struct JSCallback { void* webview; char* script; @@ -895,6 +926,10 @@ func (w *Window) StartDrag() { C.StartDrag(w.webview, w.asGTKWindow()) } +func (w *Window) StartResize(edge uintptr) { + C.StartResize(w.webview, w.asGTKWindow(), C.GdkWindowEdge(edge)) +} + func (w *Window) Quit() { C.gtk_main_quit() }