[geany/geany] eb267d: For native win32 dialogs, pump main window loop a bit
Matthew Brush
git-noreply at xxxxx
Sun Aug 3 03:29:02 UTC 2014
Branch: refs/heads/master
Author: Matthew Brush <matt at geany.org>
Committer: Matthew Brush <matt at geany.org>
Date: Sun, 03 Aug 2014 03:29:02 UTC
Commit: eb267d30cbe1fe603d315d7f165bdff7ed574b2c
https://github.com/geany/geany/commit/eb267d30cbe1fe603d315d7f165bdff7ed574b2c
Log Message:
-----------
For native win32 dialogs, pump main window loop a bit
Mostly gets rid of re-drawing issues, however is not great.
Modified Paths:
--------------
src/win32.c
Modified: src/win32.c
87 lines changed, 80 insertions(+), 7 deletions(-)
===================================================================
@@ -83,6 +83,71 @@ static gboolean CreateChildProcess(geany_win32_spawn *gw_spawn, TCHAR *szCmdline
static VOID ReadFromPipe(HANDLE hRead, HANDLE hWrite, HANDLE hFile, GError **error);
+static UINT_PTR dialog_timer = 0;
+
+
+VOID CALLBACK
+win32_dialog_update_main_window(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ gint i;
+ for (i = 0; i < 4 && gtk_events_pending(); i++)
+ gtk_main_iteration();
+ dialog_timer = 0;
+}
+
+
+VOID CALLBACK win32_dialog_timer_expired(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime)
+{
+ while (gtk_events_pending())
+ gtk_main_iteration();
+}
+
+
+/* This function is called for OPENFILENAME lpfnHook function and it establishes
+ * a timer that is reset each time which will update the main window loop eventually */
+UINT_PTR CALLBACK win32_dialog_explorer_hook_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_WINDOWPOSCHANGED:
+ case WM_MOVE:
+ case WM_SIZE:
+ case WM_THEMECHANGED:
+ {
+ if (dialog_timer != 0)
+ KillTimer(dlg, dialog_timer);
+ dialog_timer = SetTimer(dlg, 0, 33 /* around 30fps */, win32_dialog_update_main_window);
+ }
+ }
+ return 0; /* always let the default proc handle it */
+}
+
+
+/* This function is called for old-school win32 dialogs that accept a proper
+ * lpfnHook function for all messages. It doesn't use a timer but instead checks
+ * GTK+ events pending and clamps to some arbitrary limit to prevent freeze-ups. */
+UINT_PTR CALLBACK win32_dialog_hook_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_WINDOWPOSCHANGED:
+ case WM_MOVE:
+ case WM_SIZE:
+ case WM_THEMECHANGED:
+ {
+ /* Pump the main window loop a bit, but not enough to lock-up.
+ * The typical `while(gtk_events_pending()) gtk_main_iteration();`
+ * loop causes the entire operating system to lock-up. */
+ guint i;
+ for (i = 0; i < 4 && gtk_events_pending(); i++)
+ gtk_main_iteration();
+ break;
+ }
+ }
+ return 0; /* always let the default proc handle it */
+}
+
+
static wchar_t *get_file_filters(void)
{
gchar *string;
@@ -206,6 +271,7 @@ static wchar_t *get_dir_for_path(const gchar *utf8_filename)
* folder when the dialog is initialised. Yeah, I like Windows. */
INT CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData)
{
+ win32_dialog_hook_proc(hwnd, uMsg, lp, pData);
switch (uMsg)
{
case BFFM_INITIALIZED:
@@ -309,7 +375,8 @@ gchar *win32_show_project_open_dialog(GtkWidget *parent, const gchar *title,
of.lpstrFileTitle = NULL;
of.lpstrTitle = w_title;
of.lpstrDefExt = L"";
- of.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_HIDEREADONLY;
+ of.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_ENABLEHOOK;
+ of.lpfnHook = win32_dialog_explorer_hook_proc;
if (! allow_new_file)
of.Flags |= OFN_FILEMUSTEXIST;
@@ -371,7 +438,8 @@ gboolean win32_show_document_open_dialog(GtkWindow *parent, const gchar *title,
of.lpstrFileTitle = NULL;
of.lpstrTitle = w_title;
of.lpstrDefExt = L"";
- of.Flags = OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST | OFN_EXPLORER;
+ of.Flags = OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK;
+ of.lpfnHook = win32_dialog_explorer_hook_proc;
retval = GetOpenFileNameW(&of);
@@ -464,7 +532,8 @@ gchar *win32_show_document_save_as_dialog(GtkWindow *parent, const gchar *title,
of.lpstrFileTitle = NULL;
of.lpstrTitle = w_title;
of.lpstrDefExt = L"";
- of.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER;
+ of.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLEHOOK;
+ of.lpfnHook = win32_dialog_explorer_hook_proc;
retval = GetSaveFileNameW(&of);
if (! retval)
@@ -516,7 +585,8 @@ gchar *win32_show_file_dialog(GtkWindow *parent, const gchar *title, const gchar
of.lpstrFileTitle = NULL;
of.lpstrTitle = w_title;
of.lpstrDefExt = L"";
- of.Flags = OFN_FILEMUSTEXIST | OFN_EXPLORER;
+ of.Flags = OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK;
+ of.lpfnHook = win32_dialog_explorer_hook_proc;
retval = GetOpenFileNameW(&of);
if (! retval)
@@ -551,7 +621,8 @@ void win32_show_font_dialog(void)
cf.hwndOwner = GDK_WINDOW_HWND(gtk_widget_get_window(main_widgets.window));
cf.lpLogFont = &lf;
/* support CF_APPLY? */
- cf.Flags = CF_NOSCRIPTSEL | CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
+ cf.Flags = CF_NOSCRIPTSEL | CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_ENABLEHOOK;
+ cf.lpfnHook = win32_dialog_hook_proc;
retval = ChooseFont(&cf);
@@ -578,7 +649,8 @@ void win32_show_color_dialog(const gchar *colour)
cc.hwndOwner = GDK_WINDOW_HWND(gtk_widget_get_window(main_widgets.window));
cc.lpCustColors = (LPDWORD) acr_cust_clr;
cc.rgbResult = (colour != NULL) ? utils_parse_color_to_bgr(colour) : 0;
- cc.Flags = CC_FULLOPEN | CC_RGBINIT;
+ cc.Flags = CC_FULLOPEN | CC_RGBINIT | CC_ENABLEHOOK;
+ cc.lpfnHook = win32_dialog_hook_proc;
if (ChooseColor(&cc))
{
@@ -636,7 +708,8 @@ void win32_show_pref_file_dialog(GtkEntry *item)
of.lpstrInitialDir = NULL;
of.lpstrTitle = NULL;
of.lpstrDefExt = L"exe";
- of.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER;
+ of.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK;
+ of.lpfnHook = win32_dialog_explorer_hook_proc;
retval = GetOpenFileNameW(&of);
if (!retval)
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list