# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1593376465 0 # Node ID 663467f6eee441ce7b1c2f840ee7f466628a27f0 # Parent 97839ff3c9851377214416cea55e8d6f2ce313f1 Code cleanup: Add constants to header for dark mode, buffer sizes and Unicode support. Windows and OS/2 can both be built without Unicode support for legacy platforms and apps. Some new Windows features require Unicode (notifications, edge) and Unicode is buggy on OS/2. Can now check if Unicode is supported with the DW_FEATURE_UTF8_UNICODE feature test. Dark mode constants added DW_DARK_MODE_DISABLED/BASIC/FULL/FORCED. Win: Include dw.h in the WinToast glue for the constants, and improve safety in Edge glue. diff -r 97839ff3c985 -r 663467f6eee4 dw.h --- a/dw.h Sun Jun 28 05:39:08 2020 +0000 +++ b/dw.h Sun Jun 28 20:34:25 2020 +0000 @@ -1331,6 +1331,15 @@ typedef unsigned long DWTID; #endif +/* Some dark mode constants for supported platforms */ +#define DW_DARK_MODE_DISABLED 0 +#define DW_DARK_MODE_BASIC 1 +#define DW_DARK_MODE_FULL 2 +#define DW_DARK_MODE_FORCED 3 + +/* Application ID support lengths */ +#define _DW_APP_ID_SIZE 100 + /* Use at least the linux utsname limit to avoid gcc fortify warnings */ #define _DW_ENV_STRING_SIZE 65 @@ -1485,6 +1494,7 @@ DW_FEATURE_MDI, /* Supports Multiple Document Interface window frame */ DW_FEATURE_NOTEBOOK_STATUS_TEXT, /* Supports status text area on notebook/tabbed controls */ DW_FEATURE_NOTIFICATION, /* Supports sending system notifications */ + DW_FEATURE_UTF8_UNICODE, /* Supports UTF8 encoded Unicode text */ DW_FEATURE_MAX } DWFEATURE; diff -r 97839ff3c985 -r 663467f6eee4 dwtest.c --- a/dwtest.c Sun Jun 28 05:39:08 2020 +0000 +++ b/dwtest.c Sun Jun 28 20:34:25 2020 +0000 @@ -1781,6 +1781,7 @@ "Supports Multiple Document Interface window frame", "Supports status text area on notebook/tabbed controls", "Supports sending system notifications", + "Supports UTF8 encoded Unicode text", NULL }; /* @@ -1805,7 +1806,7 @@ dw_app_id_set("org.dbsoft.dwindows.dwtest", "Dynamic Windows Test"); /* Enable full dark mode on platforms that support it */ - dw_feature_set(DW_FEATURE_DARK_MODE, 2); + dw_feature_set(DW_FEATURE_DARK_MODE, DW_DARK_MODE_FULL); /* Initialize the Dynamic Windows engine */ dw_init(TRUE, argc, argv); diff -r 97839ff3c985 -r 663467f6eee4 gtk/dw.c --- a/gtk/dw.c Sun Jun 28 05:39:08 2020 +0000 +++ b/gtk/dw.c Sun Jun 28 20:34:25 2020 +0000 @@ -124,7 +124,7 @@ #endif char *_DWDefaultFont = NULL; static char _dw_share_path[PATH_MAX+1] = { 0 }; -static char _dw_app_id[101] = { 0 }; +static char _dw_app_id[_DW_APP_ID_SIZE+1] = { 0 }; #if GTK_MAJOR_VERSION < 2 static int _dw_file_active = 0; @@ -2052,7 +2052,7 @@ if(!_dw_app_id[0]) { /* If we have a binary name, use that for the Application ID instead. */ - snprintf(_dw_app_id, 100, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname); + snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname); } #endif } @@ -2129,7 +2129,7 @@ if(!_dw_app_id[0]) { /* Generate an Application ID based on the PID if all else fails. */ - snprintf(_dw_app_id, 100, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid()); + snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid()); } /* Initialize the application subsystem on supported versions... @@ -13336,7 +13336,7 @@ #if GLIB_CHECK_VERSION(2,28,0) if(g_application_id_is_valid(appid)) { - strncpy(_dw_app_id, appid, 100); + strncpy(_dw_app_id, appid, _DW_APP_ID_SIZE); return DW_ERROR_NONE; } return DW_ERROR_GENERAL; @@ -13899,6 +13899,7 @@ case DW_FEATURE_MDI: #endif case DW_FEATURE_CONTAINER_STRIPE: + case DW_FEATURE_UTF8_UNICODE: case DW_FEATURE_MLE_WORD_WRAP: return DW_FEATURE_ENABLED; default: @@ -13934,6 +13935,7 @@ case DW_FEATURE_MDI: #endif case DW_FEATURE_CONTAINER_STRIPE: + case DW_FEATURE_UTF8_UNICODE: case DW_FEATURE_MLE_WORD_WRAP: return DW_ERROR_GENERAL; /* These features are supported and configurable */ diff -r 97839ff3c985 -r 663467f6eee4 gtk3/dw.c --- a/gtk3/dw.c Sun Jun 28 05:39:08 2020 +0000 +++ b/gtk3/dw.c Sun Jun 28 20:34:25 2020 +0000 @@ -174,7 +174,7 @@ #endif char *_DWDefaultFont = NULL; static char _dw_share_path[PATH_MAX+1] = { 0 }; -static char _dw_app_id[101] = { 0 }; +static char _dw_app_id[_DW_APP_ID_SIZE+1] = { 0 }; typedef struct { @@ -2020,7 +2020,7 @@ if(!_dw_app_id[0]) { /* If we have a binary name, use that for the Application ID instead. */ - snprintf(_dw_app_id, 100, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname); + snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname); } #endif } @@ -2057,7 +2057,7 @@ if(!_dw_app_id[0]) { /* Generate an Application ID based on the PID if all else fails. */ - snprintf(_dw_app_id, 100, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid()); + snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid()); } /* Initialize the application subsystem on supported versions... @@ -11836,7 +11836,7 @@ #if GLIB_CHECK_VERSION(2,28,0) if(g_application_id_is_valid(appid)) { - strncpy(_dw_app_id, appid, 100); + strncpy(_dw_app_id, appid, _DW_APP_ID_SIZE); return DW_ERROR_NONE; } return DW_ERROR_GENERAL; @@ -12393,6 +12393,7 @@ #if !GTK_CHECK_VERSION(3,14,0) case DW_FEATURE_CONTAINER_STRIPE: #endif + case DW_FEATURE_UTF8_UNICODE: case DW_FEATURE_MLE_WORD_WRAP: return DW_FEATURE_ENABLED; default: @@ -12433,6 +12434,7 @@ #if !GTK_CHECK_VERSION(3,14,0) case DW_FEATURE_CONTAINER_STRIPE: #endif + case DW_FEATURE_UTF8_UNICODE: case DW_FEATURE_MLE_WORD_WRAP: return DW_ERROR_GENERAL; /* These features are supported and configurable */ diff -r 97839ff3c985 -r 663467f6eee4 mac/dw.m --- a/mac/dw.m Sun Jun 28 05:39:08 2020 +0000 +++ b/mac/dw.m Sun Jun 28 20:34:25 2020 +0000 @@ -443,7 +443,7 @@ pthread_key_t _dw_bg_color_key; int DWOSMajor, DWOSMinor, DWOSBuild; static char _dw_bundle_path[PATH_MAX+1] = { 0 }; -static char _dw_app_id[101]= {0}; +static char _dw_app_id[_DW_APP_ID_SIZE+1]= {0}; /* Create a default colors for a thread */ void _init_colors(void) @@ -4042,7 +4042,7 @@ */ int dw_app_id_set(const char *appid, const char *appname) { - strncpy(_dw_app_id, appid, 100); + strncpy(_dw_app_id, appid, _DW_APP_ID_SIZE); return DW_ERROR_NONE; } @@ -12139,7 +12139,7 @@ if(binname && (binname++) && !_dw_app_id[0]) { /* If we have a binary name, use that for the Application ID instead. */ - snprintf(_dw_app_id, 100, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname); + snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname); } if(app) { @@ -12239,7 +12239,7 @@ if(!_dw_app_id[0]) { /* Generate an Application ID based on the PID if all else fails. */ - snprintf(_dw_app_id, 100, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid()); + snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid()); } return 0; } @@ -12711,6 +12711,7 @@ case DW_FEATURE_CONTAINER_STRIPE: case DW_FEATURE_MLE_WORD_WRAP: case DW_FEATURE_MLE_AUTO_COMPLETE: + case DW_FEATURE_UTF8_UNICODE: return DW_FEATURE_ENABLED; #ifdef BUILDING_FOR_MOJAVE case DW_FEATURE_DARK_MODE: @@ -12727,7 +12728,7 @@ NSAppearanceName basicAppearance = [appearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; if([basicAppearance isEqualToString:NSAppearanceNameDarkAqua]) - return 3; + return DW_DARK_MODE_FORCED; if([basicAppearance isEqualToString:NSAppearanceNameAqua]) return DW_FEATURE_DISABLED; } @@ -12767,6 +12768,7 @@ case DW_FEATURE_CONTAINER_STRIPE: case DW_FEATURE_MLE_WORD_WRAP: case DW_FEATURE_MLE_AUTO_COMPLETE: + case DW_FEATURE_UTF8_UNICODE: return DW_ERROR_GENERAL; /* These features are supported and configurable */ #ifdef BUILDING_FOR_MOJAVE @@ -12780,10 +12782,10 @@ if(state == DW_FEATURE_DISABLED) [DWApp setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameAqua]]; /* Enabled lets the OS decide the mode */ - else if(state == DW_FEATURE_ENABLED || state == 2) + else if(state == DW_FEATURE_ENABLED || state == DW_DARK_MODE_FULL) [DWApp setAppearance:nil]; /* 2 forces dark mode aqua appearance */ - else if(state == 3) + else if(state == DW_DARK_MODE_FORCED) [DWApp setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameDarkAqua]]; else return DW_ERROR_GENERAL; diff -r 97839ff3c985 -r 663467f6eee4 os2/dw.c --- a/os2/dw.c Sun Jun 28 05:39:08 2020 +0000 +++ b/os2/dw.c Sun Jun 28 20:34:25 2020 +0000 @@ -13845,6 +13845,9 @@ { switch(feature) { +#ifdef UNICODE + case DW_FEATURE_UTF8_UNICODE: +#endif case DW_FEATURE_WINDOW_BORDER: case DW_FEATURE_MLE_WORD_WRAP: case DW_FEATURE_NOTEBOOK_STATUS_TEXT: @@ -13873,6 +13876,9 @@ switch(feature) { /* These features are supported but not configurable */ +#ifdef UNICODE + case DW_FEATURE_UTF8_UNICODE: +#endif case DW_FEATURE_WINDOW_BORDER: case DW_FEATURE_MLE_WORD_WRAP: case DW_FEATURE_NOTEBOOK_STATUS_TEXT: diff -r 97839ff3c985 -r 663467f6eee4 win/dw.c --- a/win/dw.c Sun Jun 28 05:39:08 2020 +0000 +++ b/win/dw.c Sun Jun 28 20:34:25 2020 +0000 @@ -278,8 +278,8 @@ */ static char _dw_alternate_temp_dir[MAX_PATH+1] = {0}; static char _dw_exec_dir[MAX_PATH+1] = {0}; -static char _dw_app_id[101]= {0}; -static char _dw_app_name[101]= {0}; +static char _dw_app_id[_DW_APP_ID_SIZE+1]= {0}; +static char _dw_app_name[_DW_APP_ID_SIZE+1]= {0}; int main(int argc, char *argv[]); @@ -4276,8 +4276,8 @@ if((pos++) && !_dw_app_id[0]) { /* If we have a binary name, use that for the Application ID instead. */ - _snprintf(_dw_app_id, 100, "%s.%s", DW_APP_DOMAIN_DEFAULT, pos); - strncpy(_dw_app_name, pos, 100); + _snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.%s", DW_APP_DOMAIN_DEFAULT, pos); + strncpy(_dw_app_name, pos, _DW_APP_ID_SIZE); } } } @@ -4434,17 +4434,17 @@ if(!_dw_app_id[0]) { /* Generate an Application ID based on the PID if all else fails. */ - _snprintf(_dw_app_id, 100, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid()); + _snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.pid.%d", DW_APP_DOMAIN_DEFAULT, getpid()); } if(!_dw_app_name[0]) { /* If we still don't have an app name, get the executable name */ - char fullpath[261] = {0}, *pos; - GetModuleFileNameA(DWInstance, fullpath, 260); + char fullpath[MAX_PATH+1] = {0}, *pos; + GetModuleFileNameA(DWInstance, fullpath, MAX_PATH); pos = strrchr(fullpath, '\\'); if(pos) pos++; - strncpy(_dw_app_name, pos ? pos : fullpath, 100); + strncpy(_dw_app_name, pos ? pos : fullpath, _DW_APP_ID_SIZE); } #if (defined(BUILD_DLL) || defined(BUILD_HTML)) @@ -12914,9 +12914,9 @@ */ int API dw_app_id_set(const char *appid, const char *appname) { - strncpy(_dw_app_id, appid, 100); + strncpy(_dw_app_id, appid, _DW_APP_ID_SIZE); if(appname) - strncpy(_dw_app_name, appname, 100); + strncpy(_dw_app_name, appname, _DW_APP_ID_SIZE); return DW_ERROR_NONE; } @@ -13378,6 +13378,9 @@ { switch(feature) { +#ifdef UNICODE + case DW_FEATURE_UTF8_UNICODE: +#endif #if (defined(BUILD_DLL) || defined(BUILD_HTML)) case DW_FEATURE_HTML: case DW_FEATURE_HTML_RESULT: @@ -13430,6 +13433,9 @@ switch(feature) { /* These features are supported but not configurable */ +#ifdef UNICODE + case DW_FEATURE_UTF8_UNICODE: +#endif #if (defined(BUILD_DLL) || defined(BUILD_HTML)) case DW_FEATURE_HTML: case DW_FEATURE_HTML_RESULT: diff -r 97839ff3c985 -r 663467f6eee4 win/edge.cpp --- a/win/edge.cpp Sun Jun 28 05:39:08 2020 +0000 +++ b/win/edge.cpp Sun Jun 28 20:34:25 2020 +0000 @@ -226,11 +226,12 @@ BOOL EdgeBrowser::Detect(LPWSTR AppID) { - WCHAR tempdir[MAX_PATH+1] = {0}; + // Combine two buffer lengths, ".WebView2\" (10) and a NULL + WCHAR tempdir[MAX_PATH+_DW_APP_ID_SIZE+11] = {0}; GetTempPathW(MAX_PATH, tempdir); wcscat(tempdir, AppID); - wcscat(tempdir, L"\\"); + wcscat(tempdir, L".WebView2\\"); CreateDirectoryW(tempdir, NULL); CreateCoreWebView2EnvironmentWithOptions(nullptr, tempdir, nullptr, diff -r 97839ff3c985 -r 663467f6eee4 win/wintoast.cpp --- a/win/wintoast.cpp Sun Jun 28 05:39:08 2020 +0000 +++ b/win/wintoast.cpp Sun Jun 28 20:34:25 2020 +0000 @@ -1,12 +1,12 @@ /* Simple WinToast forwarder from Dynamic Windows APIs */ +#include "dw.h" #include "wintoastlib.h" using namespace WinToastLib; extern "C" { LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2); - void dw_signal_disconnect_by_window(HWND window); } class DWHandler : public IWinToastHandler { @@ -118,9 +118,9 @@ handler->templ = templ; if(templ && WinToast::instance()->showToast(*templ, handler) >= 0) - return 0; // DW_ERROR_NONE + return DW_ERROR_NONE; } - return -1; // DW_ERROR_UNKNOWN + return DW_ERROR_UNKNOWN; } BOOL _dw_toast_is_compatible(void)