5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-21 19:39:29 +08:00
This commit is contained in:
Lea Anthony 2020-12-20 21:00:32 +11:00
parent a8995c5377
commit 937f0f77c2
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
4 changed files with 76 additions and 94 deletions

View File

@ -78,7 +78,6 @@
// References to assets // References to assets
extern const unsigned char *assets[]; extern const unsigned char *assets[];
extern const unsigned char runtime; extern const unsigned char runtime;
extern const char *icon[];
// Tray icon // Tray icon
extern const unsigned int trayIconLength; extern const unsigned int trayIconLength;
@ -120,19 +119,13 @@ void dispatch(dispatchMethod func) {
dispatch_async(dispatch_get_main_queue(), func); dispatch_async(dispatch_get_main_queue(), func);
} }
// App Delegate
typedef struct AppDel {
Class isa;
id window;
} AppDelegate;
// Credit: https://stackoverflow.com/a/8465083 // Credit: https://stackoverflow.com/a/8465083
char* concat(const char *string1, const char *string2) char* concat(const char *string1, const char *string2)
{ {
const size_t len1 = strlen(string1); const size_t len1 = strlen(string1);
const size_t len2 = strlen(string2); const size_t len2 = strlen(string2);
char *result = malloc(len1 + len2 + 1); char *result = malloc(len1 + len2 + 1);
memcpy(result, string1, len1); strcpy(result, string1);
memcpy(result + len1, string2, len2 + 1); memcpy(result + len1, string2, len2 + 1);
return result; return result;
} }
@ -181,8 +174,6 @@ struct Application {
id mouseEvent; id mouseEvent;
id mouseDownMonitor; id mouseDownMonitor;
id mouseUpMonitor; id mouseUpMonitor;
id vibrancyLayer;
// Window Data // Window Data
const char *title; const char *title;
@ -208,7 +199,6 @@ struct Application {
int frame; int frame;
int startHidden; int startHidden;
int maximised; int maximised;
int minimised;
int titlebarAppearsTransparent; int titlebarAppearsTransparent;
int hideTitle; int hideTitle;
int hideTitleBar; int hideTitleBar;
@ -219,7 +209,6 @@ struct Application {
// Menu // Menu
const char *menuAsJSON; const char *menuAsJSON;
id menubar;
JsonNode *processedMenu; JsonNode *processedMenu;
// Tray // Tray
@ -231,18 +220,12 @@ struct Application {
const char *contextMenusAsJSON; const char *contextMenusAsJSON;
JsonNode *processedContextMenus; JsonNode *processedContextMenus;
// User Data
char *HTML;
// Callback // Callback
ffenestriCallback sendMessageToBackend; ffenestriCallback sendMessageToBackend;
// Bindings // Bindings
const char *bindings; const char *bindings;
// Lock - used for sync operations (Should we be using g_mutex?)
int lock;
}; };
// 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
@ -328,29 +311,26 @@ void showContextMenu(struct Application *app, const char *contextMenuID) {
return; return;
} }
printf("contextMenuID = %s\n", contextMenuID);
// Look for the context menu for this ID // Look for the context menu for this ID
id contextMenu = (id)hashmap_get(&contextMenuMap, (char*)contextMenuID, strlen(contextMenuID)); id contextMenu = (id)hashmap_get(&contextMenuMap, (char*)contextMenuID, strlen(contextMenuID));
printf("CONTEXT MENU = %p\n", contextMenu); if( contextMenu == NULL ) {
printf("No context menu called '%s'. Available:", contextMenuID);
dumpHashmap("contextMenuMap", &contextMenuMap);
// Free menu id
MEMFREE(contextMenuID);
return;
}
// Free menu id // Free menu id
MEMFREE(contextMenuID); MEMFREE(contextMenuID);
if( contextMenu == NULL ) {
printf("\n\n\n\n\n\n\n");
dumpHashmap("contextMenuMap", &contextMenuMap);
return;
}
// Grab the content view and show the menu // Grab the content view and show the menu
id contentView = msg(app->mainWindow, s("contentView")); id contentView = msg(app->mainWindow, s("contentView"));
printf("contentView = %p\n", contentView);
// Get the triggering event // Get the triggering event
id menuEvent = msg(app->mainWindow, s("currentEvent")); id menuEvent = msg(app->mainWindow, s("currentEvent"));
printf("menuEvent = %p\n", menuEvent);
// Show popup // Show popup
msg(c("NSMenu"), s("popUpContextMenu:withEvent:forView:"), contextMenu, menuEvent, contentView); msg(c("NSMenu"), s("popUpContextMenu:withEvent:forView:"), contextMenu, menuEvent, contentView);
@ -383,7 +363,7 @@ void Show(struct Application *app) {
); );
} }
void SetWindowBackgroundIsTranslucent(struct Application *app) { void WindowBackgroundIsTranslucent(struct Application *app) {
app->windowBackgroundIsTranslucent = 1; app->windowBackgroundIsTranslucent = 1;
} }
@ -417,7 +397,7 @@ void messageHandler(id self, SEL cmd, id contentController, id message) {
const char *contextMenuMessage = cstr(msg(message, s("body"))); const char *contextMenuMessage = cstr(msg(message, s("body")));
if( contextMenuMessage == NULL ) { if( contextMenuMessage == NULL ) {
printf("EMPTY CONTEXT MENU MESSAGE!!\n"); Debug(app, "EMPTY CONTEXT MENU MESSAGE!!\n");
return; return;
} }
@ -468,10 +448,10 @@ void messageHandler(id self, SEL cmd, id contentController, id message) {
} }
// Creates a JSON message for the given menuItemID and data // Creates a JSON message for the given menuItemID and data
const char* createContextMenuMessage(const char *menuItemID, const char *contextMenuData) { const char* createContextMenuMessage(const char *menuItemID, const char *givenContextMenuData) {
JsonNode *jsonObject = json_mkobject(); JsonNode *jsonObject = json_mkobject();
json_append_member(jsonObject, "menuItemID", json_mkstring(menuItemID)); json_append_member(jsonObject, "menuItemID", json_mkstring(menuItemID));
json_append_member(jsonObject, "data", json_mkstring(contextMenuData)); json_append_member(jsonObject, "data", json_mkstring(givenContextMenuData));
const char *result = json_encode(jsonObject); const char *result = json_encode(jsonObject);
json_delete(jsonObject); json_delete(jsonObject);
return result; return result;
@ -685,7 +665,6 @@ void closeWindow(id self, SEL cmd, id sender) {
void willFinishLaunching(id self, SEL cmd, id sender) { void willFinishLaunching(id self, SEL cmd, id sender) {
struct Application *app = (struct Application *) objc_getAssociatedObject(self, "application"); struct Application *app = (struct Application *) objc_getAssociatedObject(self, "application");
printf("\n\n\n\n\n\n\n\n\n\n\n\nI AM HERE!!!!!!!\n\n\n\n\n\n\n\n\n\n\n");
} }
bool isDarkMode(struct Application *app) { bool isDarkMode(struct Application *app) {
@ -786,9 +765,7 @@ void* NewApplication(const char *title, int width, int height, int resizable, in
result->resizable = resizable; result->resizable = resizable;
result->devtools = devtools; result->devtools = devtools;
result->fullscreen = fullscreen; result->fullscreen = fullscreen;
result->lock = 0;
result->maximised = 0; result->maximised = 0;
result->minimised = 0;
result->startHidden = startHidden; result->startHidden = startHidden;
result->decorations = 0; result->decorations = 0;
result->logLevel = logLevel; result->logLevel = logLevel;
@ -825,7 +802,6 @@ void* NewApplication(const char *title, int width, int height, int resizable, in
contextMenuData = NULL; contextMenuData = NULL;
// Window Appearance // Window Appearance
result->vibrancyLayer = NULL;
result->titlebarAppearsTransparent = 0; result->titlebarAppearsTransparent = 0;
result->webviewIsTranparent = 0; result->webviewIsTranparent = 0;
@ -839,6 +815,11 @@ int freeHashmapItem(void *const context, struct hashmap_element_s *const e) {
return -1; return -1;
} }
int freeNSMenu(void *const context, struct hashmap_element_s *const e) {
msg(e->data, s("dealloc"));
return -1;
}
void destroyMenu(struct Application *app) { void destroyMenu(struct Application *app) {
// Free menu item hashmap // Free menu item hashmap
@ -854,16 +835,16 @@ void destroyMenu(struct Application *app) {
//Free radio groups hashmap //Free radio groups hashmap
hashmap_destroy(&radioGroupMapForApplicationMenu); hashmap_destroy(&radioGroupMapForApplicationMenu);
// Release the menu json if we have it
if ( app->menuAsJSON != NULL ) {
MEMFREE(app->menuAsJSON);
}
// Release processed menu // Release processed menu
if( app->processedMenu != NULL) { if( app->processedMenu != NULL) {
json_delete(app->processedMenu); json_delete(app->processedMenu);
app->processedMenu = NULL; app->processedMenu = NULL;
} }
// Remove the current Menu
id menubar = msg(msg(c("NSApplication"), s("sharedApplication")), s("mainMenu"));
Debug(app, "Destroying menubar: %p", menubar);
msg(menubar, s("dealloc"));
} }
void destroyContextMenus(struct Application *app) { void destroyContextMenus(struct Application *app) {
@ -886,6 +867,13 @@ void destroyContextMenus(struct Application *app) {
//Free radio groups hashmap //Free radio groups hashmap
hashmap_destroy(&radioGroupMapForContextMenus); hashmap_destroy(&radioGroupMapForContextMenus);
// Free context menus
if( hashmap_num_entries(&contextMenuMap) > 0 ) {
if (0!=hashmap_iterate_pairs(&contextMenuMap, freeNSMenu, NULL)) {
Fatal(app, "failed to deallocate hashmap entries!");
}
}
//Free context menu map //Free context menu map
hashmap_destroy(&contextMenuMap); hashmap_destroy(&contextMenuMap);
@ -895,9 +883,6 @@ void destroyContextMenus(struct Application *app) {
app->processedContextMenus = NULL; app->processedContextMenus = NULL;
} }
// Release the menu json
MEMFREE(app->contextMenusAsJSON);
} }
@ -921,15 +906,15 @@ void destroyTray(struct Application *app) {
//Free radio groups hashmap //Free radio groups hashmap
hashmap_destroy(&radioGroupMapForTrayMenu); hashmap_destroy(&radioGroupMapForTrayMenu);
// Release the menu json
MEMFREE(app->trayMenuAsJSON);
// Release processed tray // Release processed tray
if( app->processedTrayMenu != NULL) { if( app->processedTrayMenu != NULL) {
json_delete(app->processedTrayMenu); json_delete(app->processedTrayMenu);
app->processedTrayMenu = NULL; app->processedTrayMenu = NULL;
} }
// Destroy app status item
msg(app->statusItem, s("dealloc"));
} }
void DestroyApplication(struct Application *app) { void DestroyApplication(struct Application *app) {
@ -1157,7 +1142,7 @@ void OpenDialog(struct Application *app, char *callbackID, char *title, char *fi
id urls = msg(dialog, s("URLs")); id urls = msg(dialog, s("URLs"));
// Iterate over all the selected files // Iterate over all the selected files
int noOfResults = (int)msg(urls, s("count")); long noOfResults = (long)msg(urls, s("count"));
for( int index = 0; index < noOfResults; index++ ) { for( int index = 0; index < noOfResults; index++ ) {
// Extract the filename // Extract the filename
@ -1343,9 +1328,6 @@ void makeWindowBackgroundTranslucent(struct Application *app) {
msg(effectView, s("setBlendingMode:"), NSVisualEffectBlendingModeBehindWindow); msg(effectView, s("setBlendingMode:"), NSVisualEffectBlendingModeBehindWindow);
msg(effectView, s("setState:"), NSVisualEffectStateActive); msg(effectView, s("setState:"), NSVisualEffectStateActive);
msg(contentView, s("addSubview:positioned:relativeTo:"), effectView, NSWindowBelow, NULL); msg(contentView, s("addSubview:positioned:relativeTo:"), effectView, NSWindowBelow, NULL);
app->vibrancyLayer = effectView;
Debug(app, "effectView: %p", effectView);
} }
void enableBoolConfig(id config, const char *setting) { void enableBoolConfig(id config, const char *setting) {
@ -1497,7 +1479,7 @@ id createMenu(id title) {
id menu = ALLOC("NSMenu"); id menu = ALLOC("NSMenu");
msg(menu, s("initWithTitle:"), title); msg(menu, s("initWithTitle:"), title);
msg(menu, s("setAutoenablesItems:"), NO); msg(menu, s("setAutoenablesItems:"), NO);
msg(menu, s("autorelease")); // msg(menu, s("autorelease"));
return menu; return menu;
} }
@ -2003,6 +1985,9 @@ struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction, const char
if ( modifiersList != NULL ) { if ( modifiersList != NULL ) {
// Allocate an array of strings // Allocate an array of strings
int noOfModifiers = json_array_length(modifiersList); int noOfModifiers = json_array_length(modifiersList);
// Do we have any?
if (noOfModifiers > 0) {
modifiers = malloc(sizeof(const char *) * (noOfModifiers + 1)); modifiers = malloc(sizeof(const char *) * (noOfModifiers + 1));
JsonNode *modifier; JsonNode *modifier;
int count = 0; int count = 0;
@ -2016,6 +2001,7 @@ struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction, const char
modifiers[count] = NULL; modifiers[count] = NULL;
} }
} }
}
// Get the Type // Get the Type
@ -2110,15 +2096,10 @@ struct hashmap_s *radioGroupMap) {
// Copy the memberList // Copy the memberList
char *newMemberList = (char *)malloc(arrayLength); char *newMemberList = (char *)malloc(arrayLength);
memcpy(newMemberList, memberList, arrayLength); memcpy(newMemberList, memberList, arrayLength);
// dumpMemberList("newMemberList", newMemberList);
// printf("Address of newMemberList = %p\n", newMemberList);
// add group to each member of group // add group to each member of group
hashmap_put(radioGroupMap, member->string_, strlen(member->string_), newMemberList); hashmap_put(radioGroupMap, member->string_, strlen(member->string_), newMemberList);
} }
// dumpHashmap("radioGroupMap", &radioGroupMap);
} }
void parseMenuData(struct Application *app) { void parseMenuData(struct Application *app) {
@ -2177,11 +2158,6 @@ void UpdateMenu(struct Application *app, const char *menuAsJSON) {
Debug(app, "Menu is now: %s", menuAsJSON); Debug(app, "Menu is now: %s", menuAsJSON);
ON_MAIN_THREAD ( ON_MAIN_THREAD (
// Remove the current Menu
id menubar = msg(msg(c("NSApplication"), s("sharedApplication")), s("mainMenu"));
Debug(app, "Got menubar: %p", menubar);
msg(menubar, s("removeAllItems"));
// Free up memory // Free up memory
destroyMenu(app); destroyMenu(app);
@ -2229,14 +2205,12 @@ void parseContextMenus(struct Application *app) {
json_foreach(contextMenu, contextMenuItems) { json_foreach(contextMenu, contextMenuItems) {
// Create a new menu // Create a new menu
id menu = createMenu(str("")); id menu = createMenu(str(""));
printf("Context menu NSMenu pointer = %p\n", menu);
// parse the menu // parse the menu
parseMenu(app, menu, contextMenu, &menuItemMapForContextMenus, parseMenu(app, menu, contextMenu, &menuItemMapForContextMenus,
"checkboxMenuCallbackForContextMenus:", "radioMenuCallbackForContextMenus:", "menuCallbackForContextMenus:"); "checkboxMenuCallbackForContextMenus:", "radioMenuCallbackForContextMenus:", "menuCallbackForContextMenus:");
// Store the item in the context menu map // Store the item in the context menu map
printf("Putting context menu %p with key '%s' in contextMenuMap %p\n", menu, contextMenu->key, &contextMenuMap);
hashmap_put(&contextMenuMap, (char*)contextMenu->key, strlen(contextMenu->key), menu); hashmap_put(&contextMenuMap, (char*)contextMenu->key, strlen(contextMenu->key), menu);
} }

View File

@ -4,19 +4,8 @@ package ffenestri
#cgo darwin CFLAGS: -DFFENESTRI_DARWIN=1 #cgo darwin CFLAGS: -DFFENESTRI_DARWIN=1
#cgo darwin LDFLAGS: -framework WebKit -lobjc #cgo darwin LDFLAGS: -framework WebKit -lobjc
extern void TitlebarAppearsTransparent(void *); #include "ffenestri_darwin.h"
extern void HideTitle(void *);
extern void HideTitleBar(void *);
extern void FullSizeContent(void *);
extern void UseToolbar(void *);
extern void HideToolbarSeparator(void *);
extern void DisableFrame(void *);
extern void SetAppearance(void *, const char *);
extern void WebviewIsTransparent(void *);
extern void SetWindowBackgroundIsTranslucent(void *);
extern void SetMenu(void *, const char *);
extern void SetTray(void *, const char *);
extern void SetContextMenus(void *, const char *);
*/ */
import "C" import "C"
import ( import (
@ -70,7 +59,7 @@ func (a *Application) processPlatformSettings() error {
// Check if window should be translucent // Check if window should be translucent
if mac.WindowBackgroundIsTranslucent { if mac.WindowBackgroundIsTranslucent {
C.SetWindowBackgroundIsTranslucent(a.app) C.WindowBackgroundIsTranslucent(a.app)
} }
// Process menu // Process menu

View File

@ -0,0 +1,19 @@
#ifndef FFENESTRI_DARWIN_H
#define FFENESTRI_DARWIN_H
extern void TitlebarAppearsTransparent(void *);
extern void HideTitle(void *);
extern void HideTitleBar(void *);
extern void FullSizeContent(void *);
extern void UseToolbar(void *);
extern void HideToolbarSeparator(void *);
extern void DisableFrame(void *);
extern void SetAppearance(void *, const char *);
extern void WebviewIsTransparent(void *);
extern void WindowBackgroundIsTranslucent(void *);
extern void SetMenu(void *, const char *);
extern void SetTray(void *, const char *);
extern void SetContextMenus(void *, const char *);
#endif

View File

@ -19,7 +19,7 @@ func main() {
MinHeight: 600, MinHeight: 600,
//Tray: menu.NewMenuFromItems(menu.AppMenu()), //Tray: menu.NewMenuFromItems(menu.AppMenu()),
//Menu: menu.NewMenuFromItems(menu.AppMenu()), //Menu: menu.NewMenuFromItems(menu.AppMenu()),
StartHidden: true, //StartHidden: true,
ContextMenus: createContextMenus(), ContextMenus: createContextMenus(),
Mac: &mac.Options{ Mac: &mac.Options{
WebviewIsTransparent: true, WebviewIsTransparent: true,