From a4ade77653b9e456aacbc369fc6cec6b776ac484 Mon Sep 17 00:00:00 2001 From: Scott Talbert Date: Wed, 28 Dec 2016 12:12:03 -0500 Subject: [PATCH 1/3] Fix unresizable windows on HiDPI displays (#1402630) Fix rendering of check and radio buttons on GTK+ 3.20+ (#1405841) --- ...3-3.0.2-check-radio-button-rendering.patch | 256 ++++++++++++++++++ wxGTK3-3.0.2-unresizable-windows-hidpi.patch | 29 ++ wxGTK3.spec | 14 +- 3 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 wxGTK3-3.0.2-check-radio-button-rendering.patch create mode 100644 wxGTK3-3.0.2-unresizable-windows-hidpi.patch diff --git a/wxGTK3-3.0.2-check-radio-button-rendering.patch b/wxGTK3-3.0.2-check-radio-button-rendering.patch new file mode 100644 index 0000000..8367ae9 --- /dev/null +++ b/wxGTK3-3.0.2-check-radio-button-rendering.patch @@ -0,0 +1,256 @@ +From ec023e99774d90e3ac16a3a5b4e55c6cdf9fb3c1 Mon Sep 17 00:00:00 2001 +From: Paul Cornett +Date: Sat, 10 Dec 2016 21:49:06 -0800 +Subject: [PATCH] Fix rendering of check and radio buttons with GTK+ >= 3.20 + +(cherry picked from commit e627970ba6126113fdf09db69c50582b369d0d8a) +--- + src/gtk/renderer.cpp | 184 ++++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 153 insertions(+), 31 deletions(-) + +diff --git a/src/gtk/renderer.cpp b/src/gtk/renderer.cpp +index 965d5fe..c89b0d3 100644 +--- a/src/gtk/renderer.cpp ++++ b/src/gtk/renderer.cpp +@@ -503,6 +503,49 @@ wxRendererGTK::DrawComboBoxDropButton(wxWindow *win, + wxSize + wxRendererGTK::GetCheckBoxSize(wxWindow *WXUNUSED(win)) + { ++#ifdef __WXGTK3__ ++ int min_width, min_height; ++ GtkWidgetPath* path = gtk_widget_path_new(); ++ GtkStyleContext* sc = gtk_style_context_new(); ++ GtkStyleContext* sc1 = NULL; ++ gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON); ++#if GTK_CHECK_VERSION(3,20,0) ++ if (gtk_check_version(3,20,0) == NULL) ++ { ++ gtk_widget_path_iter_set_object_name(path, -1, "checkbutton"); ++ sc1 = gtk_style_context_new(); ++ gtk_style_context_set_path(sc1, path); ++ gtk_widget_path_append_type(path, G_TYPE_NONE); ++ gtk_widget_path_iter_set_object_name(path, -1, "check"); ++ gtk_style_context_set_path(sc, path); ++ gtk_style_context_set_parent(sc, sc1); ++ gtk_style_context_get(sc, GTK_STATE_FLAG_NORMAL, ++ "min-width", &min_width, "min-height", &min_height, NULL); ++ GtkBorder margin; ++ gtk_style_context_get_margin(sc, GTK_STATE_FLAG_NORMAL, &margin); ++ min_width += margin.left + margin.right; ++ min_height += margin.top + margin.bottom; ++ } ++ else ++#endif ++ { ++ gtk_style_context_set_path(sc, path); ++ GValue value = G_VALUE_INIT; ++ g_value_init(&value, G_TYPE_INT); ++ gtk_style_context_get_style_property(sc, "indicator-size", &value); ++ min_width = g_value_get_int(&value); ++ gtk_style_context_get_style_property(sc, "indicator-spacing", &value); ++ min_width += 2 * g_value_get_int(&value); ++ min_height = min_width; ++ g_value_unset(&value); ++ } ++ gtk_widget_path_unref(path); ++ g_object_unref(sc); ++ if (sc1) ++ g_object_unref(sc1); ++ ++ return wxSize(min_width, min_height); ++#else // !__WXGTK3__ + gint indicator_size, indicator_spacing; + gtk_widget_style_get(wxGTKPrivate::GetCheckButtonWidget(), + "indicator_size", &indicator_size, +@@ -511,6 +554,7 @@ wxRendererGTK::GetCheckBoxSize(wxWindow *WXUNUSED(win)) + + int size = indicator_size + indicator_spacing * 2; + return wxSize(size, size); ++#endif // !__WXGTK3__ + } + + void +@@ -519,6 +563,7 @@ wxRendererGTK::DrawCheckBox(wxWindow* win, + const wxRect& rect, + int flags ) + { ++#ifndef __WXGTK3__ + GtkWidget *button = wxGTKPrivate::GetCheckButtonWidget(); + + gint indicator_size, indicator_spacing; +@@ -527,7 +572,6 @@ wxRendererGTK::DrawCheckBox(wxWindow* win, + "indicator_spacing", &indicator_spacing, + NULL); + +-#ifndef __WXGTK3__ + GtkStateType state; + + if ( flags & wxCONTROL_PRESSED ) +@@ -551,31 +595,68 @@ wxRendererGTK::DrawCheckBox(wxWindow* win, + + #ifdef __WXGTK3__ + cairo_t* cr = wxGetGTKDrawable(win, dc); +- if (cr) ++ if (cr == NULL) ++ return; ++ ++ int state = GTK_STATE_FLAG_NORMAL; ++ if (flags & wxCONTROL_CHECKED) + { +- int stateFlags = GTK_STATE_FLAG_NORMAL; +- if (flags & wxCONTROL_CHECKED) +- { +- stateFlags = GTK_STATE_FLAG_ACTIVE; +- if (gtk_check_version(3,14,0) == NULL) +- stateFlags = GTK_STATE_FLAG_CHECKED; +- } +- if (flags & wxCONTROL_DISABLED) +- stateFlags |= GTK_STATE_FLAG_INSENSITIVE; +- if (flags & wxCONTROL_UNDETERMINED) +- stateFlags |= GTK_STATE_FLAG_INCONSISTENT; +- if (flags & wxCONTROL_CURRENT) +- stateFlags |= GTK_STATE_FLAG_PRELIGHT; +- GtkStyleContext* sc = gtk_widget_get_style_context(button); +- gtk_style_context_save(sc); +- gtk_style_context_set_state(sc, GtkStateFlags(stateFlags)); +- gtk_style_context_add_class(sc, GTK_STYLE_CLASS_CHECK); +- gtk_render_check(sc, cr, +- rect.x + (rect.width - indicator_size) / 2, +- rect.y + (rect.height - indicator_size) / 2, +- indicator_size, indicator_size); +- gtk_style_context_restore(sc); ++ state = GTK_STATE_FLAG_ACTIVE; ++ if (gtk_check_version(3,14,0) == NULL) ++ state = GTK_STATE_FLAG_CHECKED; ++ } ++ if (flags & wxCONTROL_DISABLED) ++ state |= GTK_STATE_FLAG_INSENSITIVE; ++ if (flags & wxCONTROL_UNDETERMINED) ++ state |= GTK_STATE_FLAG_INCONSISTENT; ++ if (flags & wxCONTROL_CURRENT) ++ state |= GTK_STATE_FLAG_PRELIGHT; ++ ++ int min_width, min_height; ++ GtkWidgetPath* path = gtk_widget_path_new(); ++ GtkStyleContext* sc = gtk_style_context_new(); ++ GtkStyleContext* sc1 = NULL; ++ gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON); ++#if GTK_CHECK_VERSION(3,20,0) ++ if (gtk_check_version(3,20,0) == NULL) ++ { ++ gtk_widget_path_iter_set_object_name(path, -1, "checkbutton"); ++ sc1 = gtk_style_context_new(); ++ gtk_style_context_set_path(sc1, path); ++ gtk_widget_path_append_type(path, G_TYPE_NONE); ++ gtk_widget_path_iter_set_object_name(path, -1, "check"); ++ gtk_style_context_set_path(sc, path); ++ gtk_style_context_set_parent(sc, sc1); ++ gtk_style_context_get(sc, GTK_STATE_FLAG_NORMAL, ++ "min-width", &min_width, "min-height", &min_height, NULL); ++ } ++ else ++#endif ++ { ++ gtk_style_context_set_path(sc, path); ++ GValue value = G_VALUE_INIT; ++ g_value_init(&value, G_TYPE_INT); ++ gtk_style_context_get_style_property(sc, "indicator-size", &value); ++ min_width = g_value_get_int(&value); ++ min_height = min_width; ++ g_value_unset(&value); + } ++ ++ // need save/restore for GTK+ 3.6 & 3.8 ++ gtk_style_context_save(sc); ++ gtk_style_context_set_state(sc, GtkStateFlags(state)); ++ const int x = rect.x + (rect.width - min_width) / 2; ++ const int y = rect.y + (rect.height - min_height) / 2; ++ gtk_render_background(sc, cr, x, y, min_width, min_height); ++ gtk_render_frame(sc, cr, x, y, min_width, min_height); ++ gtk_style_context_add_class(sc, "check"); ++ gtk_render_check(sc, cr, x, y, min_width, min_height); ++ gtk_style_context_restore(sc); ++ ++ gtk_widget_path_unref(path); ++ g_object_unref(sc); ++ if (sc1) ++ g_object_unref(sc1); + #else + GdkWindow* gdk_window = wxGetGTKDrawable(win, dc); + if (gdk_window == NULL) +@@ -869,8 +950,6 @@ void wxRendererGTK::DrawRadioBitmap(wxWindow* win, wxDC& dc, const wxRect& rect, + if (drawable == NULL) + return; + +- GtkWidget* button = wxGTKPrivate::GetRadioButtonWidget(); +- + #ifdef __WXGTK3__ + int state = GTK_STATE_FLAG_NORMAL; + if (flags & wxCONTROL_CHECKED) +@@ -879,18 +958,61 @@ void wxRendererGTK::DrawRadioBitmap(wxWindow* win, wxDC& dc, const wxRect& rect, + if (gtk_check_version(3,14,0) == NULL) + state = GTK_STATE_FLAG_CHECKED; + } +- else if (flags & wxCONTROL_UNDETERMINED) +- state = GTK_STATE_FLAG_INCONSISTENT; + if (flags & wxCONTROL_DISABLED) + state |= GTK_STATE_FLAG_INSENSITIVE; ++ if (flags & wxCONTROL_UNDETERMINED) ++ state |= GTK_STATE_FLAG_INCONSISTENT; ++ if (flags & wxCONTROL_CURRENT) ++ state |= GTK_STATE_FLAG_PRELIGHT; ++ ++ int min_width, min_height; ++ GtkWidgetPath* path = gtk_widget_path_new(); ++ GtkStyleContext* sc = gtk_style_context_new(); ++ GtkStyleContext* sc1 = NULL; ++ gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON); ++#if GTK_CHECK_VERSION(3,20,0) ++ if (gtk_check_version(3,20,0) == NULL) ++ { ++ gtk_widget_path_iter_set_object_name(path, -1, "radiobutton"); ++ sc1 = gtk_style_context_new(); ++ gtk_style_context_set_path(sc1, path); ++ gtk_widget_path_append_type(path, G_TYPE_NONE); ++ gtk_widget_path_iter_set_object_name(path, -1, "radio"); ++ gtk_style_context_set_path(sc, path); ++ gtk_style_context_set_parent(sc, sc1); ++ gtk_style_context_get(sc, GTK_STATE_FLAG_NORMAL, ++ "min-width", &min_width, "min-height", &min_height, NULL); ++ } ++ else ++#endif ++ { ++ gtk_style_context_set_path(sc, path); ++ GValue value = G_VALUE_INIT; ++ g_value_init(&value, G_TYPE_INT); ++ gtk_style_context_get_style_property(sc, "indicator-size", &value); ++ min_width = g_value_get_int(&value); ++ min_height = min_width; ++ g_value_unset(&value); ++ } + +- GtkStyleContext* sc = gtk_widget_get_style_context(button); ++ // need save/restore for GTK+ 3.6 & 3.8 + gtk_style_context_save(sc); +- gtk_style_context_add_class(sc, GTK_STYLE_CLASS_RADIO); + gtk_style_context_set_state(sc, GtkStateFlags(state)); +- gtk_render_option(sc, drawable, rect.x, rect.y, rect.width, rect.height); ++ const int x = rect.x + (rect.width - min_width) / 2; ++ const int y = rect.y + (rect.height - min_height) / 2; ++ gtk_render_background(sc, drawable, x, y, min_width, min_height); ++ gtk_render_frame(sc, drawable, x, y, min_width, min_height); ++ gtk_style_context_add_class(sc, "radio"); ++ gtk_render_option(sc, drawable, x, y, min_width, min_height); + gtk_style_context_restore(sc); ++ ++ gtk_widget_path_unref(path); ++ g_object_unref(sc); ++ if (sc1) ++ g_object_unref(sc1); + #else ++ GtkWidget* button = wxGTKPrivate::GetRadioButtonWidget(); ++ + GtkShadowType shadow_type = GTK_SHADOW_OUT; + if ( flags & wxCONTROL_CHECKED ) + shadow_type = GTK_SHADOW_IN; diff --git a/wxGTK3-3.0.2-unresizable-windows-hidpi.patch b/wxGTK3-3.0.2-unresizable-windows-hidpi.patch new file mode 100644 index 0000000..71cecac --- /dev/null +++ b/wxGTK3-3.0.2-unresizable-windows-hidpi.patch @@ -0,0 +1,29 @@ +From a97553a939b76df1564ffbfe9c919d1da5a34c5a Mon Sep 17 00:00:00 2001 +From: Paul Cornett +Date: Mon, 21 Mar 2016 09:46:46 -0700 +Subject: [PATCH] Avoid unresizable windows on HiDPI displays when using + SetSizeHints() + +see #17456 + +(cherry picked from commit 4793e5b0a4e189e492287305859b278fed780080) +--- + src/gtk/toplevel.cpp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp +index 464fb3f..69fca2a 100644 +--- a/src/gtk/toplevel.cpp ++++ b/src/gtk/toplevel.cpp +@@ -1273,8 +1273,9 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH, + int hints_mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE; + hints.min_width = 1; + hints.min_height = 1; +- hints.max_width = INT_MAX; +- hints.max_height = INT_MAX; ++ // using INT_MAX for size will lead to integer overflow with HiDPI scaling ++ hints.max_width = INT_MAX / 16; ++ hints.max_height = INT_MAX / 16; + int decorSize_x; + int decorSize_y; + #ifdef HAS_CLIENT_DECOR diff --git a/wxGTK3.spec b/wxGTK3.spec index 8a1f065..b10f4ae 100644 --- a/wxGTK3.spec +++ b/wxGTK3.spec @@ -11,7 +11,7 @@ Name: %{wxgtkname} Version: 3.0.2 -Release: 30%{?dist} +Release: 31%{?dist} Summary: GTK port of the wxWidgets GUI library License: wxWidgets Group: System Environment/Libraries @@ -113,6 +113,14 @@ Patch23: %{name}-%{version}-paint-clipping-region.patch # For more details, see the upstream commit: # https://github.com/wxWidgets/wxWidgets/commit/dcc23ceba8e1dba828e8b3e4633ac77acaad7562 Patch24: %{name}-%{version}-wxpgchoicesdata-protected-destructor.patch +# Fixes unresizable windows on HiDPI displays +# For more details, see the upstream commit: +# https://github.com/wxWidgets/wxWidgets/commit/a97553a939b76df1564ffbfe9c919d1da5a34c5a +Patch25: %{name}-%{version}-unresizable-windows-hidpi.patch +# Fixes rendering of check and radio buttons with GTK+ >= 3.20 +# For more details, see the upstream commit: +# https://github.com/wxWidgets/wxWidgets/commit/ec023e99774d90e3ac16a3a5b4e55c6cdf9fb3c1 +Patch26: %{name}-%{version}-check-radio-button-rendering.patch BuildRequires: gtk%{gtkver}-devel #Note webkitgtk (GTK2) does not appear to be supported @@ -414,6 +422,10 @@ fi %doc docs/doxygen/out/xml/* %changelog +* Wed Dec 28 2016 Scott Talbert - 3.0.2-31 +- Fix unresizable windows on HiDPI displays (#1402630) +- Fix rendering of check and radio buttons on GTK+ 3.20+ (#1405841) + * Mon Nov 21 2016 Scott Talbert - 3.0.2-30 - Fix poedit regression in -29 - add paint clipping region patch (#1396747) - Add patch to change ~wxPGChoicesData from private to protected From 87a683e1658597829125b1a5f547c242c1758cfc Mon Sep 17 00:00:00 2001 From: Scott Talbert Date: Sat, 7 Jan 2017 09:14:32 -0500 Subject: [PATCH 2/3] Fix blank menubar/toolbar when using wx[MT]B_DOCKABLE (#1410729) --- wxGTK3-3.0.2-blank-menubar-toolbar.patch | 53 ++++++++++++++++++++++++ wxGTK3.spec | 9 +++- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 wxGTK3-3.0.2-blank-menubar-toolbar.patch diff --git a/wxGTK3-3.0.2-blank-menubar-toolbar.patch b/wxGTK3-3.0.2-blank-menubar-toolbar.patch new file mode 100644 index 0000000..c35b2ce --- /dev/null +++ b/wxGTK3-3.0.2-blank-menubar-toolbar.patch @@ -0,0 +1,53 @@ +From 57dce78348cbe93d53c1432ee224e27fdd726982 Mon Sep 17 00:00:00 2001 +From: Paul Cornett +Date: Wed, 25 May 2016 09:39:50 -0700 +Subject: [PATCH] Avoid blank menubar/toolbar when using wx[MT]B_DOCKABLE with + GTK+ 3.20 + +A GTK+ bug involving GtkHandleBox somehow prevents drawing of its child +since 3.19.7. Avoid this by disabling the docking functionality, which +is preferable to having the bar be blank. +See #17539 + +(cherry picked from commit 7e41ac405f4105a7703e37bffd8ab951159f5af0) +--- + src/gtk/menu.cpp | 7 ++++++- + src/gtk/toolbar.cpp | 7 ++++++- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp +index 3c5426d..5aa3caf 100644 +--- a/src/gtk/menu.cpp ++++ b/src/gtk/menu.cpp +@@ -141,7 +141,12 @@ void wxMenuBar::Init(size_t n, wxMenu *menus[], const wxString titles[], long st + + m_menubar = gtk_menu_bar_new(); + +- if (style & wxMB_DOCKABLE) ++ if ((style & wxMB_DOCKABLE) ++#ifdef __WXGTK3__ ++ // using GtkHandleBox prevents menubar from drawing with GTK+ >= 3.19.7 ++ && gtk_check_version(3,19,7) ++#endif ++ ) + { + m_widget = gtk_handle_box_new(); + gtk_container_add(GTK_CONTAINER(m_widget), m_menubar); +diff --git a/src/gtk/toolbar.cpp b/src/gtk/toolbar.cpp +index 9416f83..addf63a 100644 +--- a/src/gtk/toolbar.cpp ++++ b/src/gtk/toolbar.cpp +@@ -388,7 +388,12 @@ bool wxToolBar::Create( wxWindow *parent, + #endif + GtkSetStyle(); + +- if (style & wxTB_DOCKABLE) ++ if ((style & wxTB_DOCKABLE) ++#ifdef __WXGTK3__ ++ // using GtkHandleBox prevents toolbar from drawing with GTK+ >= 3.19.7 ++ && gtk_check_version(3,19,7) ++#endif ++ ) + { + m_widget = gtk_handle_box_new(); + diff --git a/wxGTK3.spec b/wxGTK3.spec index b10f4ae..964bbc9 100644 --- a/wxGTK3.spec +++ b/wxGTK3.spec @@ -11,7 +11,7 @@ Name: %{wxgtkname} Version: 3.0.2 -Release: 31%{?dist} +Release: 32%{?dist} Summary: GTK port of the wxWidgets GUI library License: wxWidgets Group: System Environment/Libraries @@ -121,6 +121,10 @@ Patch25: %{name}-%{version}-unresizable-windows-hidpi.patch # For more details, see the upstream commit: # https://github.com/wxWidgets/wxWidgets/commit/ec023e99774d90e3ac16a3a5b4e55c6cdf9fb3c1 Patch26: %{name}-%{version}-check-radio-button-rendering.patch +# Fixes blank menubar/toolbar when using wx[MT]B_DOCKABLE with GTK+ 3.20 +# For more details, see the upstream commit: +# https://github.com/wxWidgets/wxWidgets/commit/57dce78348cbe93d53c1432ee224e27fdd726982 +Patch27: %{name}-%{version}-blank-menubar-toolbar.patch BuildRequires: gtk%{gtkver}-devel #Note webkitgtk (GTK2) does not appear to be supported @@ -422,6 +426,9 @@ fi %doc docs/doxygen/out/xml/* %changelog +* Sat Jan 07 2017 Scott Talbert - 3.0.2-32 +- Fix blank menubar/toolbar when using wx[MT]B_DOCKABLE (#1410729) + * Wed Dec 28 2016 Scott Talbert - 3.0.2-31 - Fix unresizable windows on HiDPI displays (#1402630) - Fix rendering of check and radio buttons on GTK+ 3.20+ (#1405841) From 489bc8557ae2262f66a987dfe0ad1ca5f434c185 Mon Sep 17 00:00:00 2001 From: Scott Talbert Date: Sun, 7 May 2017 21:43:12 -0400 Subject: [PATCH 3/3] Fix merged specfile changelog ordering --- wxGTK3.spec | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wxGTK3.spec b/wxGTK3.spec index 96e82f1..b563df2 100644 --- a/wxGTK3.spec +++ b/wxGTK3.spec @@ -396,22 +396,22 @@ fi * Sat Feb 11 2017 Fedora Release Engineering - 3.0.3-0.4.gitf90b768 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild +* Sat Jan 07 2017 Scott Talbert - 3.0.2-32 +- Fix blank menubar/toolbar when using wx[MT]B_DOCKABLE (#1410729) + * Fri Dec 30 2016 Scott Talbert - 3.0.3-0.3.gitf90b768 - Switch to use GStreamer 1.0 (#1402628) * Wed Dec 28 2016 Jeremy Newton - 3.0.3-0.2.gitf90b768 - Update to newer git snapshot -* Sat Dec 10 2016 Jeremy Newton - 3.0.3-0.1.git9518d52 -- Update to git snapshot - -* Sat Jan 07 2017 Scott Talbert - 3.0.2-32 -- Fix blank menubar/toolbar when using wx[MT]B_DOCKABLE (#1410729) - * Wed Dec 28 2016 Scott Talbert - 3.0.2-31 - Fix unresizable windows on HiDPI displays (#1402630) - Fix rendering of check and radio buttons on GTK+ 3.20+ (#1405841) +* Sat Dec 10 2016 Jeremy Newton - 3.0.3-0.1.git9518d52 +- Update to git snapshot + * Mon Nov 21 2016 Scott Talbert - 3.0.2-30 - Fix poedit regression in -29 - add paint clipping region patch (#1396747) - Add patch to change ~wxPGChoicesData from private to protected