From 629e8f73f4fbce803aebe5bbe796553c55f8cb9c Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 21 Sep 2020 17:07:10 +1000 Subject: [PATCH] Add Mac Application Options --- v2/.vscode/settings.json | 6 ++- v2/internal/app/default.go | 4 +- v2/internal/app/desktop.go | 23 ++------ v2/internal/appoptions/default.go | 9 ++++ v2/internal/appoptions/mac.go | 7 +++ v2/internal/{app => appoptions}/options.go | 8 +-- v2/internal/ffenestri/ffenestri.go | 62 ++++++++++++---------- v2/internal/ffenestri/ffenestri_darwin.c | 51 +++++++++++------- v2/internal/ffenestri/ffenestri_darwin.go | 22 ++++++++ v2/test/runtime/main.go | 3 ++ v2/wails.go | 8 ++- 11 files changed, 128 insertions(+), 75 deletions(-) create mode 100644 v2/internal/appoptions/default.go create mode 100644 v2/internal/appoptions/mac.go rename v2/internal/{app => appoptions}/options.go (74%) create mode 100644 v2/internal/ffenestri/ffenestri_darwin.go diff --git a/v2/.vscode/settings.json b/v2/.vscode/settings.json index b918676db..e6b0705f5 100644 --- a/v2/.vscode/settings.json +++ b/v2/.vscode/settings.json @@ -2,6 +2,10 @@ "files.associations": { "ios": "c", "typeinfo": "c", - "sstream": "c" + "sstream": "c", + "__functional_03": "c", + "functional": "c", + "__locale": "c", + "locale": "c" } } \ No newline at end of file diff --git a/v2/internal/app/default.go b/v2/internal/app/default.go index 1fcf357d5..354888479 100644 --- a/v2/internal/app/default.go +++ b/v2/internal/app/default.go @@ -9,6 +9,8 @@ package app import ( "os" + + "github.com/wailsapp/wails/v2/internal/appoptions" ) // App defines a Wails application structure @@ -23,7 +25,7 @@ type App struct { } // CreateApp returns a null application -func CreateApp(options *Options) *App { +func CreateApp(options *appoptions.Options) *App { return &App{} } diff --git a/v2/internal/app/desktop.go b/v2/internal/app/desktop.go index c0a6e13f6..5f2495115 100644 --- a/v2/internal/app/desktop.go +++ b/v2/internal/app/desktop.go @@ -5,6 +5,7 @@ package app import ( "os" + "github.com/wailsapp/wails/v2/internal/appoptions" "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/ffenestri" "github.com/wailsapp/wails/v2/internal/logger" @@ -37,32 +38,16 @@ type App struct { } // Create App -func CreateApp(options *Options) *App { +func CreateApp(options *appoptions.Options) *App { // Merge default options - options.mergeDefaults() + options.MergeDefaults() // Set up logger myLogger := logger.New(os.Stdout) myLogger.SetLogLevel(logger.TRACE) - window := ffenestri.NewApplicationWithConfig(&ffenestri.Config{ - Title: options.Title, - Width: options.Width, - Height: options.Height, - MinWidth: options.MinWidth, - MinHeight: options.MinHeight, - MaxWidth: options.MaxWidth, - MaxHeight: options.MaxHeight, - Frameless: options.Frameless, - StartHidden: options.StartHidden, - - // This should be controlled by the compile time flags... - DevTools: true, - - Resizable: !options.DisableResize, - Fullscreen: options.Fullscreen, - }, myLogger) + window := ffenestri.NewApplicationWithConfig(options, myLogger) result := &App{ window: window, diff --git a/v2/internal/appoptions/default.go b/v2/internal/appoptions/default.go new file mode 100644 index 000000000..d7753307a --- /dev/null +++ b/v2/internal/appoptions/default.go @@ -0,0 +1,9 @@ +package appoptions + +// Default options for creating the App +var Default = &Options{ + Title: "My Wails App", + Width: 1024, + Height: 768, + DevTools: true, +} diff --git a/v2/internal/appoptions/mac.go b/v2/internal/appoptions/mac.go new file mode 100644 index 000000000..95292eb8d --- /dev/null +++ b/v2/internal/appoptions/mac.go @@ -0,0 +1,7 @@ +package appoptions + +// MacOptions ae options speific to Mas +type MacOptions struct { + TitlebarAppearsTransparent bool + HideTitle bool +} diff --git a/v2/internal/app/options.go b/v2/internal/appoptions/options.go similarity index 74% rename from v2/internal/app/options.go rename to v2/internal/appoptions/options.go index 20c81f941..4105578c9 100644 --- a/v2/internal/app/options.go +++ b/v2/internal/appoptions/options.go @@ -1,4 +1,4 @@ -package app +package appoptions // Options for creating the App type Options struct { @@ -13,10 +13,12 @@ type Options struct { MaxWidth int MaxHeight int StartHidden bool + DevTools bool + Mac MacOptions } -// mergeDefaults will set the minimum default values for an application -func (o *Options) mergeDefaults() { +// MergeDefaults will set the minimum default values for an application +func (o *Options) MergeDefaults() { // Create a default title if len(o.Title) == 0 { diff --git a/v2/internal/ffenestri/ffenestri.go b/v2/internal/ffenestri/ffenestri.go index 2fddc3af7..f355e0985 100644 --- a/v2/internal/ffenestri/ffenestri.go +++ b/v2/internal/ffenestri/ffenestri.go @@ -5,6 +5,7 @@ import ( "strings" "unsafe" + "github.com/wailsapp/wails/v2/internal/appoptions" "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/messagedispatcher" ) @@ -28,36 +29,36 @@ import "C" // TODO: move to compile time. var DEBUG bool = true -// Config defines how our application should be configured -type Config struct { - Title string - Width int - Height int - MinWidth int - MinHeight int - MaxWidth int - MaxHeight int - DevTools bool - Resizable bool - Fullscreen bool - Frameless bool - StartHidden bool -} +// // Config defines how our application should be configured +// type Config struct { +// Title string +// Width int +// Height int +// MinWidth int +// MinHeight int +// MaxWidth int +// MaxHeight int +// DevTools bool +// Resizable bool +// Fullscreen bool +// Frameless bool +// StartHidden bool +// } -var defaultConfig = &Config{ - Title: "My Wails App", - Width: 800, - Height: 600, - DevTools: true, - Resizable: true, - Fullscreen: false, - Frameless: false, - StartHidden: false, -} +// var defaultConfig = &Config{ +// Title: "My Wails App", +// Width: 800, +// Height: 600, +// DevTools: true, +// Resizable: true, +// Fullscreen: false, +// Frameless: false, +// StartHidden: false, +// } // Application is our main application object type Application struct { - config *Config + config *appoptions.Options memory []unsafe.Pointer // This is the main app pointer @@ -82,7 +83,7 @@ func init() { } // NewApplicationWithConfig creates a new application based on the given config -func NewApplicationWithConfig(config *Config, logger *logger.Logger) *Application { +func NewApplicationWithConfig(config *appoptions.Options, logger *logger.Logger) *Application { return &Application{ config: config, logger: logger.CustomLogger("Ffenestri"), @@ -92,7 +93,7 @@ func NewApplicationWithConfig(config *Config, logger *logger.Logger) *Applicatio // NewApplication creates a new Application with the default config func NewApplication(logger *logger.Logger) *Application { return &Application{ - config: defaultConfig, + config: appoptions.Default, logger: logger.CustomLogger("Ffenestri"), } } @@ -130,7 +131,7 @@ func (a *Application) Run(incomingDispatcher Dispatcher, bindings string) error title := a.string2CString(a.config.Title) width := C.int(a.config.Width) height := C.int(a.config.Height) - resizable := a.bool2Cint(a.config.Resizable) + resizable := a.bool2Cint(!a.config.DisableResize) devtools := a.bool2Cint(a.config.DevTools) fullscreen := a.bool2Cint(a.config.Fullscreen) startHidden := a.bool2Cint(a.config.StartHidden) @@ -167,6 +168,9 @@ func (a *Application) Run(incomingDispatcher Dispatcher, bindings string) error // can access it dispatcher = incomingDispatcher.RegisterClient(newClient(a)) + // Process platform settings + a.processPlatformSettings() + // Check we could initialise the application if app != nil { // Yes - Save memory reference and run app, cleaning up afterwards diff --git a/v2/internal/ffenestri/ffenestri_darwin.c b/v2/internal/ffenestri/ffenestri_darwin.c index 9a0bd30d4..c4b1bc540 100644 --- a/v2/internal/ffenestri/ffenestri_darwin.c +++ b/v2/internal/ffenestri/ffenestri_darwin.c @@ -72,16 +72,16 @@ BOOL yes(id self, SEL cmd) // Debug works like sprintf but mutes if the global debug flag is true // Credit: https://stackoverflow.com/a/20639708 -void Debug(char *message, ... ) { +void Debug(const char *message, ... ) { if ( debug ) { - char *temp = concat("TRACE | Ffenestri (C) | ", message); - message = concat(temp, "\n"); - free(temp); - va_list args; - va_start(args, message); - vprintf(message, args); - free(message); - va_end(args); + char *temp = concat("TRACE | Ffenestri (C) | ", message); + message = concat(temp, "\n"); + free(temp); + va_list args; + va_start(args, message); + vprintf(message, args); + free((void*)message); + va_end(args); } } @@ -113,6 +113,8 @@ struct Application { int frame; int maximised; int minimised; + int titlebarAppearsTransparent; + int hideTitle; // User Data char *HTML; @@ -128,15 +130,22 @@ struct Application { }; -void Hide(void *appPointer) { - struct Application *app = (struct Application*) appPointer; +void TitlebarAppearsTransparent(struct Application* app) { + app->titlebarAppearsTransparent = 1; + Debug("[x] setTitlebarAppearsTransparent %d", app->titlebarAppearsTransparent? YES:NO); +} + +void HideTitle(struct Application *app) { + app->hideTitle = 1; +} + +void Hide(struct Application *app) { ON_MAIN_THREAD( msg(app->application, s("hide:")) ) } -void Show(void *appPointer) { - struct Application *app = (struct Application*) appPointer; +void Show(struct Application *app) { ON_MAIN_THREAD( msg(app->mainWindow, s("makeKeyAndOrderFront:"), NULL); msg(app->application, s("activateIgnoringOtherApps:"), YES); @@ -188,6 +197,10 @@ void* NewApplication(const char *title, int width, int height, int resizable, in // Features result->frame = 1; + result->hideTitle = 0; + + result->titlebarAppearsTransparent = 0; + printf("[l] setTitlebarAppearsTransparent %d\n", result->titlebarAppearsTransparent); result->sendMessageToBackend = (ffenestriCallback) messageFromWindowCallback; @@ -335,12 +348,8 @@ void SetSize(struct Application *app, int width, int height) { // Get the rect for the window CGRect frame = GET_FRAME(app->mainWindow); - // Get the rect for the current screen - // CGRect visibleFrame = GET_FRAME(screen); // Credit: https://github.com/patr0nus/DeskGap/blob/73c0ac9f2c73f55b6e81f64f6673a7962b5719cd/lib/src/platform/mac/util/NSScreen%2BGeometry.m - // dumpFrame("visibleFrame", visibleFrame); - dumpFrame("before", frame); frame.origin.y = (frame.origin.y + frame.size.height) - (float)height; frame.size.width = (float)width; frame.size.height = (float)height; @@ -357,11 +366,8 @@ void SetPosition(struct Application *app, int x, int y) { CGRect screenFrame = GET_FRAME(screen); CGRect windowFrame = GET_FRAME(app->mainWindow); - dumpFrame("screenFrame", screenFrame); - dumpFrame("windowFrame before", windowFrame); windowFrame.origin.x = screenFrame.origin.x + (float)x; windowFrame.origin.y = (screenFrame.origin.y + screenFrame.size.height) - windowFrame.size.height - (float)y; - dumpFrame("windowFrame after", windowFrame); msg(app->mainWindow, s("setFrame:display:animate:"), windowFrame, 1, 0); ) } @@ -731,6 +737,11 @@ void Run(void *applicationPointer, int argc, char **argv) { // [[window standardWindowButton:NSWindowZoomButton] setHidden:YES]; // [[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; // [[window standardWindowButton:NSWindowCloseButton] setHidden:YES]; + } else { + Debug("setTitlebarAppearsTransparent %d", app->titlebarAppearsTransparent ? YES :NO); + // msg(mainWindow, s("setTitlebarAppearsTransparent:"), app->titlebarAppearsTransparent ? YES : NO); + msg(app->mainWindow, s("setTitleVisibility:"), app->hideTitle); + } diff --git a/v2/internal/ffenestri/ffenestri_darwin.go b/v2/internal/ffenestri/ffenestri_darwin.go new file mode 100644 index 000000000..98081e0dd --- /dev/null +++ b/v2/internal/ffenestri/ffenestri_darwin.go @@ -0,0 +1,22 @@ +package ffenestri + +/* +#cgo darwin CFLAGS: -DFFENESTRI_DARWIN=1 +#cgo darwin LDFLAGS: -framework WebKit -lobjc + +extern void TitlebarAppearsTransparent(void *); +extern void HideTitle(void *); +*/ +import "C" + +func (a *Application) processPlatformSettings() { + + // HideTitle + if a.config.Mac.HideTitle { + C.HideTitle(a.app) + } + + // if a.config.Mac.TitlebarAppearsTransparent { + // C.TitlebarAppearsTransparent(a.app) + // } +} diff --git a/v2/test/runtime/main.go b/v2/test/runtime/main.go index 5378295a9..72758e974 100644 --- a/v2/test/runtime/main.go +++ b/v2/test/runtime/main.go @@ -20,6 +20,9 @@ func main() { Height: 620, DisableResize: false, Fullscreen: false, + Mac: wails.MacOptions{ + HideTitle: true, + }, }) // You can also use the simplified call: diff --git a/v2/wails.go b/v2/wails.go index 57dc3bd1b..6a50a6958 100644 --- a/v2/wails.go +++ b/v2/wails.go @@ -4,6 +4,7 @@ package wails import ( "github.com/wailsapp/wails/v2/internal/app" + "github.com/wailsapp/wails/v2/internal/appoptions" "github.com/wailsapp/wails/v2/internal/runtime/goruntime" ) @@ -11,7 +12,10 @@ import ( type Runtime = goruntime.Runtime // Options is an alias for the app.Options struct -type Options = app.Options +type Options = appoptions.Options + +// MacOptions are Mac specific options +type MacOptions = appoptions.MacOptions // CreateAppWithOptions creates an application based on the given config func CreateAppWithOptions(options *Options) *app.App { @@ -21,7 +25,7 @@ func CreateAppWithOptions(options *Options) *app.App { // CreateApp creates an application based on the given title, width and height func CreateApp(title string, width int, height int) *app.App { - options := &app.Options{ + options := &Options{ Title: title, Width: width, Height: height,