changeset 2127:663467f6eee4

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.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 28 Jun 2020 20:34:25 +0000
parents 97839ff3c985
children 17f5c1c199b4
files dw.h dwtest.c gtk/dw.c gtk3/dw.c mac/dw.m os2/dw.c win/dw.c win/edge.cpp win/wintoast.cpp
diffstat 9 files changed, 61 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- 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;
 
--- 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);
--- 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 */
--- 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 */
--- 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;
--- 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:
--- 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:
--- 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,
--- 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)