diff --git a/v2/internal/ffenestri/effectstructs_windows.h b/v2/internal/ffenestri/effectstructs_windows.h new file mode 100644 index 00000000..8313c453 --- /dev/null +++ b/v2/internal/ffenestri/effectstructs_windows.h @@ -0,0 +1,64 @@ +// Credit: https://gist.github.com/ysc3839/b08d2bff1c7dacde529bed1d37e85ccf +#pragma once + +typedef enum _WINDOWCOMPOSITIONATTRIB +{ + WCA_UNDEFINED = 0, + WCA_NCRENDERING_ENABLED = 1, + WCA_NCRENDERING_POLICY = 2, + WCA_TRANSITIONS_FORCEDISABLED = 3, + WCA_ALLOW_NCPAINT = 4, + WCA_CAPTION_BUTTON_BOUNDS = 5, + WCA_NONCLIENT_RTL_LAYOUT = 6, + WCA_FORCE_ICONIC_REPRESENTATION = 7, + WCA_EXTENDED_FRAME_BOUNDS = 8, + WCA_HAS_ICONIC_BITMAP = 9, + WCA_THEME_ATTRIBUTES = 10, + WCA_NCRENDERING_EXILED = 11, + WCA_NCADORNMENTINFO = 12, + WCA_EXCLUDED_FROM_LIVEPREVIEW = 13, + WCA_VIDEO_OVERLAY_ACTIVE = 14, + WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15, + WCA_DISALLOW_PEEK = 16, + WCA_CLOAK = 17, + WCA_CLOAKED = 18, + WCA_ACCENT_POLICY = 19, + WCA_FREEZE_REPRESENTATION = 20, + WCA_EVER_UNCLOAKED = 21, + WCA_VISUAL_OWNER = 22, + WCA_HOLOGRAPHIC = 23, + WCA_EXCLUDED_FROM_DDA = 24, + WCA_PASSIVEUPDATEMODE = 25, + WCA_USEDARKMODECOLORS = 26, + WCA_LAST = 27 +} WINDOWCOMPOSITIONATTRIB; + +typedef struct _WINDOWCOMPOSITIONATTRIBDATA +{ + WINDOWCOMPOSITIONATTRIB Attrib; + PVOID pvData; + SIZE_T cbData; +} WINDOWCOMPOSITIONATTRIBDATA; + +typedef enum _ACCENT_STATE +{ + ACCENT_DISABLED = 0, + ACCENT_ENABLE_GRADIENT = 1, + ACCENT_ENABLE_TRANSPARENTGRADIENT = 2, + ACCENT_ENABLE_BLURBEHIND = 3, + ACCENT_ENABLE_ACRYLICBLURBEHIND = 4, // RS4 1803 + ACCENT_ENABLE_HOSTBACKDROP = 5, // RS5 1809 + ACCENT_INVALID_STATE = 6 +} ACCENT_STATE; + +typedef struct _ACCENT_POLICY +{ + ACCENT_STATE AccentState; + DWORD AccentFlags; + DWORD GradientColor; + DWORD AnimationId; +} ACCENT_POLICY; + +typedef BOOL (WINAPI *pfnGetWindowCompositionAttribute)(HWND, WINDOWCOMPOSITIONATTRIBDATA*); + +typedef BOOL (WINAPI *pfnSetWindowCompositionAttribute)(HWND, WINDOWCOMPOSITIONATTRIBDATA*); \ No newline at end of file diff --git a/v2/internal/ffenestri/ffenestri.go b/v2/internal/ffenestri/ffenestri.go index c84a417c..67b12210 100644 --- a/v2/internal/ffenestri/ffenestri.go +++ b/v2/internal/ffenestri/ffenestri.go @@ -19,7 +19,7 @@ import ( #cgo darwin CFLAGS: -DFFENESTRI_DARWIN=1 #cgo darwin LDFLAGS: -framework WebKit -lobjc -#cgo windows CPPFLAGS: -std=c++11 +#cgo windows CXXFLAGS: -std=c++11 #cgo windows,amd64 LDFLAGS: -L./windows/x64 -lwebview -lWebView2Loader -lgdi32 -lole32 -lShlwapi -luser32 -loleaut32 #include diff --git a/v2/internal/ffenestri/ffenestri.h b/v2/internal/ffenestri/ffenestri.h index 59e2c4ce..8df2090d 100644 --- a/v2/internal/ffenestri/ffenestri.h +++ b/v2/internal/ffenestri/ffenestri.h @@ -45,6 +45,8 @@ extern void DeleteTrayMenuByID(struct Application*, const char *id); extern void UpdateTrayMenuLabel(struct Application*, const char* JSON); extern void AddContextMenu(struct Application*, char *contextMenuJSON); extern void UpdateContextMenu(struct Application*, char *contextMenuJSON); +extern void WebviewIsTransparent(struct Application*); +extern void WindowBackgroundIsTranslucent(struct Application*); #ifdef __cplusplus } diff --git a/v2/internal/ffenestri/ffenestri_windows.cpp b/v2/internal/ffenestri/ffenestri_windows.cpp index 14096e05..49f6e46f 100644 --- a/v2/internal/ffenestri/ffenestri_windows.cpp +++ b/v2/internal/ffenestri/ffenestri_windows.cpp @@ -9,6 +9,7 @@ #include #include #include "windows/WebView2.h" +#include "effectstructs_windows.h" #include int debug = 0; @@ -56,6 +57,8 @@ struct Application *NewApplication(const char *title, int width, int height, int result->startHidden = startHidden; result->logLevel = logLevel; result->hideWindowOnClose = hideWindowOnClose; + result->webviewIsTranparent = false; + result->windowBackgroundIsTranslucent = false; // Min/Max Width/Height result->minWidth = 0; @@ -63,6 +66,12 @@ struct Application *NewApplication(const char *title, int width, int height, int result->maxWidth = 0; result->maxHeight = 0; + // Default colour + result->backgroundColour.R = 255; + result->backgroundColour.G = 255; + result->backgroundColour.B = 255; + result->backgroundColour.A = 255; + // Have a frame by default result->frame = 1; @@ -98,6 +107,23 @@ void performShutdown(struct Application *app) { messageFromWindowCallback("WC"); } +void enableTranslucentBackground(struct Application *app) { + HMODULE hUser = GetModuleHandleA("user32.dll"); + if (hUser) + { + pfnSetWindowCompositionAttribute setWindowCompositionAttribute = (pfnSetWindowCompositionAttribute)GetProcAddress(hUser, "SetWindowCompositionAttribute"); + if (setWindowCompositionAttribute) + { + ACCENT_POLICY accent = { ACCENT_ENABLE_BLURBEHIND, 0, 0, 0 }; + WINDOWCOMPOSITIONATTRIBDATA data; + data.Attrib = WCA_ACCENT_POLICY; + data.pvData = &accent; + data.cbData = sizeof(accent); + setWindowCompositionAttribute(app->window, &data); + } + } +} + LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { struct Application *app = (struct Application *)GetWindowLongPtr(hwnd, GWLP_USERDATA); @@ -334,6 +360,16 @@ void Run(struct Application* app, int argc, char **argv) { startVisibility = SW_HIDE; } + // TODO: Make configurable +// COREWEBVIEW2_COLOR wvColor; +// wvColor.A = 255; +// std::weak_ptr controller2 = app->webviewController->query(); +// controller2->put_DefaultBackgroundColor(wvColor); + + if( app->windowBackgroundIsTranslucent ) { + enableTranslucentBackground(app); + } + // private center() as we are on main thread center(app); ShowWindow(app->window, startVisibility); @@ -519,6 +555,7 @@ void SetPosition(struct Application* app, int x, int y) { } void Quit(struct Application* app) { + DestroyWindow(app->window); } @@ -548,6 +585,17 @@ void DisableFrame(struct Application* app) { app->frame = 0; } +// WebviewIsTransparent will make the webview transparent +// revealing the window underneath +void WebviewIsTransparent(struct Application *app) { + app->webviewIsTranparent = true; +} + +void WindowBackgroundIsTranslucent(struct Application *app) { + app->windowBackgroundIsTranslucent = true; +} + + void OpenDialog(struct Application* app, char *callbackID, char *title, char *filters, char *defaultFilename, char *defaultDir, int allowFiles, int allowDirs, int allowMultiple, int showHiddenFiles, int canCreateDirectories, int resolvesAliases, int treatPackagesAsDirectories) { } void SaveDialog(struct Application* app, char *callbackID, char *title, char *filters, char *defaultFilename, char *defaultDir, int showHiddenFiles, int canCreateDirectories, int treatPackagesAsDirectories) { diff --git a/v2/internal/ffenestri/ffenestri_windows.go b/v2/internal/ffenestri/ffenestri_windows.go index d1d0106e..e96bf68b 100644 --- a/v2/internal/ffenestri/ffenestri_windows.go +++ b/v2/internal/ffenestri/ffenestri_windows.go @@ -1,6 +1,63 @@ package ffenestri +import "C" + +/* + +#cgo windows CXXFLAGS: -std=c++11 +#cgo windows,amd64 LDFLAGS: -L./windows/x64 -lwebview -lWebView2Loader -lgdi32 -lole32 -lShlwapi -luser32 -loleaut32 + +#include "ffenestri.h" + +*/ +import "C" + func (a *Application) processPlatformSettings() error { + config := a.config.Windows + + // Check if the webview should be transparent + if config.WebviewIsTransparent { + C.WebviewIsTransparent(a.app) + } + + if config.WindowBackgroundIsTranslucent { + C.WindowBackgroundIsTranslucent(a.app) + } + + //// Process menu + ////applicationMenu := options.GetApplicationMenu(a.config) + //applicationMenu := a.menuManager.GetApplicationMenuJSON() + //if applicationMenu != "" { + // C.SetApplicationMenu(a.app, a.string2CString(applicationMenu)) + //} + // + //// Process tray + //trays, err := a.menuManager.GetTrayMenus() + //if err != nil { + // return err + //} + //if trays != nil { + // for _, tray := range trays { + // C.AddTrayMenu(a.app, a.string2CString(tray)) + // } + //} + // + //// Process context menus + //contextMenus, err := a.menuManager.GetContextMenus() + //if err != nil { + // return err + //} + //if contextMenus != nil { + // for _, contextMenu := range contextMenus { + // C.AddContextMenu(a.app, a.string2CString(contextMenu)) + // } + //} + // + //// Process URL Handlers + //if a.config.Mac.URLHandlers != nil { + // C.HasURLHandlers(a.app) + //} + return nil } diff --git a/v2/internal/ffenestri/ffenestri_windows.h b/v2/internal/ffenestri/ffenestri_windows.h index 23fa46a7..c7ad4a4c 100644 --- a/v2/internal/ffenestri/ffenestri_windows.h +++ b/v2/internal/ffenestri/ffenestri_windows.h @@ -42,6 +42,9 @@ struct Application{ LONG maxHeight; int frame; char *startupURL; + bool webviewIsTranparent; + bool windowBackgroundIsTranslucent; + COREWEBVIEW2_COLOR backgroundColour; // placeholders char* bindings; diff --git a/v2/internal/ffenestri/windows/x64/LICENSE b/v2/internal/ffenestri/windows/x64/LICENSE deleted file mode 100644 index a2083304..00000000 --- a/v2/internal/ffenestri/windows/x64/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Josh Turpen, Will Speak - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 9e4d3b89..5c4f9213 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -1,6 +1,7 @@ package options import ( + "github.com/wailsapp/wails/v2/pkg/options/windows" "log" "runtime" @@ -31,6 +32,7 @@ type App struct { ContextMenus []*menu.ContextMenu TrayMenus []*menu.TrayMenu Menu *menu.Menu + Windows *windows.Options Mac *mac.Options Logger logger.Logger `json:"-"` LogLevel logger.LogLevel diff --git a/v2/pkg/options/windows/windows.go b/v2/pkg/options/windows/windows.go new file mode 100644 index 00000000..5e39fda5 --- /dev/null +++ b/v2/pkg/options/windows/windows.go @@ -0,0 +1,7 @@ +package windows + +// Options are options specific to Mac +type Options struct { + WebviewIsTransparent bool + WindowBackgroundIsTranslucent bool +}