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

Add Mac Application Options

This commit is contained in:
Lea Anthony 2020-09-21 17:07:10 +10:00
parent eb68ba5120
commit 629e8f73f4
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
11 changed files with 128 additions and 75 deletions

View File

@ -2,6 +2,10 @@
"files.associations": { "files.associations": {
"ios": "c", "ios": "c",
"typeinfo": "c", "typeinfo": "c",
"sstream": "c" "sstream": "c",
"__functional_03": "c",
"functional": "c",
"__locale": "c",
"locale": "c"
} }
} }

View File

@ -9,6 +9,8 @@ package app
import ( import (
"os" "os"
"github.com/wailsapp/wails/v2/internal/appoptions"
) )
// App defines a Wails application structure // App defines a Wails application structure
@ -23,7 +25,7 @@ type App struct {
} }
// CreateApp returns a null application // CreateApp returns a null application
func CreateApp(options *Options) *App { func CreateApp(options *appoptions.Options) *App {
return &App{} return &App{}
} }

View File

@ -5,6 +5,7 @@ package app
import ( import (
"os" "os"
"github.com/wailsapp/wails/v2/internal/appoptions"
"github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/ffenestri" "github.com/wailsapp/wails/v2/internal/ffenestri"
"github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/logger"
@ -37,32 +38,16 @@ type App struct {
} }
// Create App // Create App
func CreateApp(options *Options) *App { func CreateApp(options *appoptions.Options) *App {
// Merge default options // Merge default options
options.mergeDefaults() options.MergeDefaults()
// Set up logger // Set up logger
myLogger := logger.New(os.Stdout) myLogger := logger.New(os.Stdout)
myLogger.SetLogLevel(logger.TRACE) myLogger.SetLogLevel(logger.TRACE)
window := ffenestri.NewApplicationWithConfig(&ffenestri.Config{ window := ffenestri.NewApplicationWithConfig(options, myLogger)
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)
result := &App{ result := &App{
window: window, window: window,

View File

@ -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,
}

View File

@ -0,0 +1,7 @@
package appoptions
// MacOptions ae options speific to Mas
type MacOptions struct {
TitlebarAppearsTransparent bool
HideTitle bool
}

View File

@ -1,4 +1,4 @@
package app package appoptions
// Options for creating the App // Options for creating the App
type Options struct { type Options struct {
@ -13,10 +13,12 @@ type Options struct {
MaxWidth int MaxWidth int
MaxHeight int MaxHeight int
StartHidden bool StartHidden bool
DevTools bool
Mac MacOptions
} }
// mergeDefaults will set the minimum default values for an application // MergeDefaults will set the minimum default values for an application
func (o *Options) mergeDefaults() { func (o *Options) MergeDefaults() {
// Create a default title // Create a default title
if len(o.Title) == 0 { if len(o.Title) == 0 {

View File

@ -5,6 +5,7 @@ import (
"strings" "strings"
"unsafe" "unsafe"
"github.com/wailsapp/wails/v2/internal/appoptions"
"github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/internal/messagedispatcher" "github.com/wailsapp/wails/v2/internal/messagedispatcher"
) )
@ -28,36 +29,36 @@ import "C"
// TODO: move to compile time. // TODO: move to compile time.
var DEBUG bool = true var DEBUG bool = true
// Config defines how our application should be configured // // Config defines how our application should be configured
type Config struct { // type Config struct {
Title string // Title string
Width int // Width int
Height int // Height int
MinWidth int // MinWidth int
MinHeight int // MinHeight int
MaxWidth int // MaxWidth int
MaxHeight int // MaxHeight int
DevTools bool // DevTools bool
Resizable bool // Resizable bool
Fullscreen bool // Fullscreen bool
Frameless bool // Frameless bool
StartHidden bool // StartHidden bool
} // }
var defaultConfig = &Config{ // var defaultConfig = &Config{
Title: "My Wails App", // Title: "My Wails App",
Width: 800, // Width: 800,
Height: 600, // Height: 600,
DevTools: true, // DevTools: true,
Resizable: true, // Resizable: true,
Fullscreen: false, // Fullscreen: false,
Frameless: false, // Frameless: false,
StartHidden: false, // StartHidden: false,
} // }
// Application is our main application object // Application is our main application object
type Application struct { type Application struct {
config *Config config *appoptions.Options
memory []unsafe.Pointer memory []unsafe.Pointer
// This is the main app pointer // This is the main app pointer
@ -82,7 +83,7 @@ func init() {
} }
// NewApplicationWithConfig creates a new application based on the given config // 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{ return &Application{
config: config, config: config,
logger: logger.CustomLogger("Ffenestri"), 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 // NewApplication creates a new Application with the default config
func NewApplication(logger *logger.Logger) *Application { func NewApplication(logger *logger.Logger) *Application {
return &Application{ return &Application{
config: defaultConfig, config: appoptions.Default,
logger: logger.CustomLogger("Ffenestri"), logger: logger.CustomLogger("Ffenestri"),
} }
} }
@ -130,7 +131,7 @@ func (a *Application) Run(incomingDispatcher Dispatcher, bindings string) error
title := a.string2CString(a.config.Title) title := a.string2CString(a.config.Title)
width := C.int(a.config.Width) width := C.int(a.config.Width)
height := C.int(a.config.Height) height := C.int(a.config.Height)
resizable := a.bool2Cint(a.config.Resizable) resizable := a.bool2Cint(!a.config.DisableResize)
devtools := a.bool2Cint(a.config.DevTools) devtools := a.bool2Cint(a.config.DevTools)
fullscreen := a.bool2Cint(a.config.Fullscreen) fullscreen := a.bool2Cint(a.config.Fullscreen)
startHidden := a.bool2Cint(a.config.StartHidden) startHidden := a.bool2Cint(a.config.StartHidden)
@ -167,6 +168,9 @@ func (a *Application) Run(incomingDispatcher Dispatcher, bindings string) error
// can access it // can access it
dispatcher = incomingDispatcher.RegisterClient(newClient(a)) dispatcher = incomingDispatcher.RegisterClient(newClient(a))
// Process platform settings
a.processPlatformSettings()
// Check we could initialise the application // Check we could initialise the application
if app != nil { if app != nil {
// Yes - Save memory reference and run app, cleaning up afterwards // Yes - Save memory reference and run app, cleaning up afterwards

View File

@ -72,16 +72,16 @@ BOOL yes(id self, SEL cmd)
// Debug works like sprintf but mutes if the global debug flag is true // Debug works like sprintf but mutes if the global debug flag is true
// Credit: https://stackoverflow.com/a/20639708 // Credit: https://stackoverflow.com/a/20639708
void Debug(char *message, ... ) { void Debug(const char *message, ... ) {
if ( debug ) { if ( debug ) {
char *temp = concat("TRACE | Ffenestri (C) | ", message); char *temp = concat("TRACE | Ffenestri (C) | ", message);
message = concat(temp, "\n"); message = concat(temp, "\n");
free(temp); free(temp);
va_list args; va_list args;
va_start(args, message); va_start(args, message);
vprintf(message, args); vprintf(message, args);
free(message); free((void*)message);
va_end(args); va_end(args);
} }
} }
@ -113,6 +113,8 @@ struct Application {
int frame; int frame;
int maximised; int maximised;
int minimised; int minimised;
int titlebarAppearsTransparent;
int hideTitle;
// User Data // User Data
char *HTML; char *HTML;
@ -128,15 +130,22 @@ struct Application {
}; };
void Hide(void *appPointer) { void TitlebarAppearsTransparent(struct Application* app) {
struct Application *app = (struct Application*) appPointer; 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( ON_MAIN_THREAD(
msg(app->application, s("hide:")) msg(app->application, s("hide:"))
) )
} }
void Show(void *appPointer) { void Show(struct Application *app) {
struct Application *app = (struct Application*) appPointer;
ON_MAIN_THREAD( ON_MAIN_THREAD(
msg(app->mainWindow, s("makeKeyAndOrderFront:"), NULL); msg(app->mainWindow, s("makeKeyAndOrderFront:"), NULL);
msg(app->application, s("activateIgnoringOtherApps:"), YES); msg(app->application, s("activateIgnoringOtherApps:"), YES);
@ -188,6 +197,10 @@ void* NewApplication(const char *title, int width, int height, int resizable, in
// Features // Features
result->frame = 1; result->frame = 1;
result->hideTitle = 0;
result->titlebarAppearsTransparent = 0;
printf("[l] setTitlebarAppearsTransparent %d\n", result->titlebarAppearsTransparent);
result->sendMessageToBackend = (ffenestriCallback) messageFromWindowCallback; result->sendMessageToBackend = (ffenestriCallback) messageFromWindowCallback;
@ -335,12 +348,8 @@ void SetSize(struct Application *app, int width, int height) {
// Get the rect for the window // Get the rect for the window
CGRect frame = GET_FRAME(app->mainWindow); 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 // 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.origin.y = (frame.origin.y + frame.size.height) - (float)height;
frame.size.width = (float)width; frame.size.width = (float)width;
frame.size.height = (float)height; frame.size.height = (float)height;
@ -357,11 +366,8 @@ void SetPosition(struct Application *app, int x, int y) {
CGRect screenFrame = GET_FRAME(screen); CGRect screenFrame = GET_FRAME(screen);
CGRect windowFrame = GET_FRAME(app->mainWindow); CGRect windowFrame = GET_FRAME(app->mainWindow);
dumpFrame("screenFrame", screenFrame);
dumpFrame("windowFrame before", windowFrame);
windowFrame.origin.x = screenFrame.origin.x + (float)x; windowFrame.origin.x = screenFrame.origin.x + (float)x;
windowFrame.origin.y = (screenFrame.origin.y + screenFrame.size.height) - windowFrame.size.height - (float)y; 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); 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:NSWindowZoomButton] setHidden:YES];
// [[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; // [[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
// [[window standardWindowButton:NSWindowCloseButton] 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);
} }

View File

@ -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)
// }
}

View File

@ -20,6 +20,9 @@ func main() {
Height: 620, Height: 620,
DisableResize: false, DisableResize: false,
Fullscreen: false, Fullscreen: false,
Mac: wails.MacOptions{
HideTitle: true,
},
}) })
// You can also use the simplified call: // You can also use the simplified call:

View File

@ -4,6 +4,7 @@ package wails
import ( import (
"github.com/wailsapp/wails/v2/internal/app" "github.com/wailsapp/wails/v2/internal/app"
"github.com/wailsapp/wails/v2/internal/appoptions"
"github.com/wailsapp/wails/v2/internal/runtime/goruntime" "github.com/wailsapp/wails/v2/internal/runtime/goruntime"
) )
@ -11,7 +12,10 @@ import (
type Runtime = goruntime.Runtime type Runtime = goruntime.Runtime
// Options is an alias for the app.Options struct // 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 // CreateAppWithOptions creates an application based on the given config
func CreateAppWithOptions(options *Options) *app.App { 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 // CreateApp creates an application based on the given title, width and height
func CreateApp(title string, width int, height int) *app.App { func CreateApp(title string, width int, height int) *app.App {
options := &app.Options{ options := &Options{
Title: title, Title: title,
Width: width, Width: width,
Height: height, Height: height,