From 915e8b781c22fc2e8a3a9a3bdae227c89db01296 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 27 Apr 2016 16:01:16 +0200 Subject: [PATCH 1/8] GTK: Fix popup font on GTK >= 3.20 X-Scintilla-Bug-URL: https://sourceforge.net/p/scintilla/bugs/1825/ X-Scintilla-Commit-ID: a28863773874af35d3cc8912ae3c028fb0462ea9 --- scintilla/gtk/PlatGTK.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index 059cebfa..e7cd9d2a 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -1456,7 +1456,7 @@ void ListBoxX::SetFont(Font &scint_font) { if (cssProvider) { PangoFontDescription *pfd = PFont(scint_font)->pfd; std::ostringstream ssFontSetting; - ssFontSetting << "GtkTreeView { "; + ssFontSetting << "GtkTreeView, treeview { "; ssFontSetting << "font-family: " << pango_font_description_get_family(pfd) << "; "; ssFontSetting << "font-size:"; ssFontSetting << static_cast(pango_font_description_get_size(pfd)) / PANGO_SCALE; From 28a99f8188724a999f74751501c1e223c2d61a7f Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 27 Apr 2016 16:01:17 +0200 Subject: [PATCH 2/8] GTK: Properly ask wText what size it wants to please GTK 3.20 It's not really of any use as we do know any size would do as wText is ours anyway, but GTK 3.20 doesn't like allocating without querying the preferred size beforehand, so do it. As wText has a size_request() of 100x100, this might change how we allocate in case we used to underallocate it, but AFAIK we don't, and it is the real minimum size expected. X-Scintilla-Bug-URL: https://sourceforge.net/p/scintilla/bugs/1825/ X-Scintilla-Commit-ID: d06e3db3e26842cd136328df17eb6f864b3adc02 --- scintilla/gtk/ScintillaGTK.cxx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/scintilla/gtk/ScintillaGTK.cxx b/scintilla/gtk/ScintillaGTK.cxx index 7f192942..4c068885 100644 --- a/scintilla/gtk/ScintillaGTK.cxx +++ b/scintilla/gtk/ScintillaGTK.cxx @@ -1769,8 +1769,17 @@ void ScintillaGTK::Resize(int width, int height) { alloc.x = 0; alloc.y = 0; - alloc.width = Platform::Maximum(1, width - verticalScrollBarWidth); - alloc.height = Platform::Maximum(1, height - horizontalScrollBarHeight); + alloc.width = 1; + alloc.height = 1; +#if GTK_CHECK_VERSION(3, 0, 0) + // please GTK 3.20 and ask wText what size it wants, although we know it doesn't really need + // anything special as it's ours. + gtk_widget_get_preferred_size(PWidget(wText), &requisition, NULL); + alloc.width = requisition.width; + alloc.height = requisition.height; +#endif + alloc.width = Platform::Maximum(alloc.width, width - verticalScrollBarWidth); + alloc.height = Platform::Maximum(alloc.height, height - horizontalScrollBarHeight); gtk_widget_size_allocate(GTK_WIDGET(PWidget(wText)), &alloc); } From ead0e9ee5fb6d0242a729f86991c16979ff90fae Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 27 Apr 2016 16:01:17 +0200 Subject: [PATCH 3/8] GTK: Fix fetching the frame border width on GTK 3.20 GTK 3.20 introduced a sub-node named "border" to the frame, requiring to lookup the border on that sub-node rather than on the frame itself. Unfortunately supporting this requires to be built against GTK 3.20, as it requires API this version introduced. This means that a build against an older version won't be able to get the popup sizing right if running on 3.20. To mitigate this, add reasonable fallback defaults when running 3.20 but built on an earlier version, to try and avoid X-Scintilla-Bug-URL: https://sourceforge.net/p/scintilla/bugs/1825/ X-Scintilla-Commit-ID: 83d56b1fc63a206e4c1b776f5991b3b17ccb3473 2px-scrolling on GTK 3.20's default theme. --- scintilla/gtk/PlatGTK.cxx | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index e7cd9d2a..09752293 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -1534,12 +1534,34 @@ PRectangle ListBoxX::GetDesiredRect() { int row_height = GetRowHeight(); #if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *styleContextFrame = gtk_widget_get_style_context(PWidget(frame)); - GtkBorder padding, border; + GtkBorder padding, border, border_border = { 0, 0, 0, 0 }; gtk_style_context_get_padding(styleContextFrame, GTK_STATE_FLAG_NORMAL, &padding); gtk_style_context_get_border(styleContextFrame, GTK_STATE_FLAG_NORMAL, &border); + +# if GTK_CHECK_VERSION(3,20,0) + // on GTK 3.20 the frame border is in a sub-node "border". + // Unfortunately we need to be built against 3.20 to be able to support this, as it requires + // new API. + GtkStyleContext *styleContextFrameBorder = gtk_style_context_new(); + GtkWidgetPath *widget_path = gtk_widget_path_copy(gtk_style_context_get_path(styleContextFrame)); + gtk_widget_path_append_type(widget_path, GTK_TYPE_BORDER); // dummy type + gtk_widget_path_iter_set_object_name(widget_path, -1, "border"); + gtk_style_context_set_path(styleContextFrameBorder, widget_path); + gtk_widget_path_free(widget_path); + gtk_style_context_get_border(styleContextFrameBorder, GTK_STATE_FLAG_NORMAL, &border_border); + g_object_unref(styleContextFrameBorder); +# else // < 3.20 + if (gtk_check_version(3, 20, 0) == NULL) { + // default to 1px all around as it's likely what it is, and so we don't miss 2px height + // on GTK 3.20 when built against an earlier version. + border_border.top = border_border.bottom = border_border.left = border_border.right = 1; + } +# endif + height = (rows * row_height + padding.top + padding.bottom + border.top + border.bottom + + border_border.top + border_border.bottom + 2 * gtk_container_get_border_width(GTK_CONTAINER(PWidget(list)))); #else height = (rows * row_height @@ -1560,6 +1582,7 @@ PRectangle ListBoxX::GetDesiredRect() { #if GTK_CHECK_VERSION(3,0,0) rc.right += (padding.left + padding.right + border.left + border.right + + border_border.left + border_border.right + 2 * gtk_container_get_border_width(GTK_CONTAINER(PWidget(list)))); #else rc.right += 2 * (PWidget(frame)->style->xthickness From 2723727ecdcc124f87f914ffe1018e4eb6d044a3 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 27 Apr 2016 16:01:17 +0200 Subject: [PATCH 4/8] GTK: Plug a memory leak X-Scintilla-Bug-URL: https://sourceforge.net/p/scintilla/bugs/1825/ X-Scintilla-Commit-ID: 4f96ed32ebb94809ca419c0f77d37de41984cf76 --- scintilla/gtk/PlatGTK.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index 09752293..ed184496 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -1494,6 +1494,7 @@ int ListBoxX::GetRowHeight() GdkRectangle rect; GtkTreePath *path = gtk_tree_path_new_first(); gtk_tree_view_get_background_area(GTK_TREE_VIEW(list), path, NULL, &rect); + gtk_tree_path_free(path); return rect.height; #else int row_height=0; From abf0365e43156be12cc0a03b0a5fb6325039b6f0 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 27 Apr 2016 16:01:17 +0200 Subject: [PATCH 5/8] GTK: Fix auto-completion popup sizing code for GTK 3.20 GTK 3.20's GtkScrolledWinodw doesn't like having a too small allocation and spews scary assertion failures. Fix that by requesting the real size we'd like instead of hard-coding 1 as small-enough value in our overriding height requisition method. The actual value doesn't really matter so long as it's small enough anyway, as we resize the popup to fit later on. Note: this moves the actual implementation of ListBoxX::GetRowHeight() to the new convenience function treeViewGetRowHeight(), with no changes in implementation. X-Scintilla-Bug-URL: https://sourceforge.net/p/scintilla/bugs/1825/ X-Scintilla-Commit-ID: 5a0afdd87d56d837dd8068e234aed8e2b6bdbe93 --- scintilla/gtk/PlatGTK.cxx | 63 ++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index ed184496..11aff431 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -1263,6 +1263,31 @@ ListBox *ListBox::Allocate() { return lb; } +static int treeViewGetRowHeight(GtkTreeView *view) +{ +#if GTK_CHECK_VERSION(3,0,0) + // This version sometimes reports erroneous results on GTK2, but the GTK2 + // version is inaccurate for GTK 3.14. + GdkRectangle rect; + GtkTreePath *path = gtk_tree_path_new_first(); + gtk_tree_view_get_background_area(view, path, NULL, &rect); + gtk_tree_path_free(path); + return rect.height; +#else + int row_height=0; + int vertical_separator=0; + int expander_size=0; + GtkTreeViewColumn *column = gtk_tree_view_get_column(view, 0); + gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &row_height); + gtk_widget_style_get(GTK_WIDGET(view), + "vertical-separator", &vertical_separator, + "expander-size", &expander_size, NULL); + row_height += vertical_separator; + row_height = Platform::Maximum(row_height, expander_size); + return row_height; +#endif +} + // SmallScroller, a GtkScrolledWindow that can shrink very small, as // gtk_widget_set_size_request() cannot shrink widgets on GTK3 typedef struct { @@ -1287,9 +1312,19 @@ G_DEFINE_TYPE(SmallScroller, small_scroller, GTK_TYPE_SCROLLED_WINDOW) #if GTK_CHECK_VERSION(3,0,0) static void small_scroller_get_preferred_height(GtkWidget *widget, gint *min, gint *nat) { - GTK_WIDGET_CLASS(small_scroller_parent_class)->get_preferred_height(widget, min, nat); - if (*min > 1) - *min = 1; + GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget)); + if (GTK_IS_TREE_VIEW(child)) { + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(child)); + int n_rows = gtk_tree_model_iter_n_children(model, NULL); + int row_height = treeViewGetRowHeight(GTK_TREE_VIEW(child)); + + *min = MAX(1, row_height); + *nat = MAX(*min, n_rows * row_height); + } else { + GTK_WIDGET_CLASS(small_scroller_parent_class)->get_preferred_height(widget, min, nat); + if (*min > 1) + *min = 1; + } } #else static void small_scroller_size_request(GtkWidget *widget, GtkRequisition *req) { @@ -1488,27 +1523,7 @@ int ListBoxX::GetVisibleRows() const { int ListBoxX::GetRowHeight() { -#if GTK_CHECK_VERSION(3,0,0) - // This version sometimes reports erroneous results on GTK2, but the GTK2 - // version is inaccurate for GTK 3.14. - GdkRectangle rect; - GtkTreePath *path = gtk_tree_path_new_first(); - gtk_tree_view_get_background_area(GTK_TREE_VIEW(list), path, NULL, &rect); - gtk_tree_path_free(path); - return rect.height; -#else - int row_height=0; - int vertical_separator=0; - int expander_size=0; - GtkTreeViewColumn *column = gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0); - gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &row_height); - gtk_widget_style_get(PWidget(list), - "vertical-separator", &vertical_separator, - "expander-size", &expander_size, NULL); - row_height += vertical_separator; - row_height = Platform::Maximum(row_height, expander_size); - return row_height; -#endif + return treeViewGetRowHeight(GTK_TREE_VIEW(list)); } PRectangle ListBoxX::GetDesiredRect() { From ba58a391c73024a9b40c638757352e171dd53333 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 27 Apr 2016 16:01:17 +0200 Subject: [PATCH 6/8] GTK: Get border for the exact current style's state on GTK 3 GTK 3.20 doesn't seem to like it so much when looking up details of a non-exact current style context state, so use the current one. This is GTK being really picky as in this case we are just missing the `DIR_LTR` flag, which we definitely don't care about, but let's make it happy. X-Scintilla-Bug-URL: https://sourceforge.net/p/scintilla/bugs/1825/ X-Scintilla-Commit-ID: 9fc624da4a3d935633c45fb56d0e9a77ef9b5af1 --- scintilla/gtk/PlatGTK.cxx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index 11aff431..1b7f8c3b 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -1550,9 +1550,10 @@ PRectangle ListBoxX::GetDesiredRect() { int row_height = GetRowHeight(); #if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *styleContextFrame = gtk_widget_get_style_context(PWidget(frame)); + GtkStateFlags stateFlagsFrame = gtk_style_context_get_state(styleContextFrame); GtkBorder padding, border, border_border = { 0, 0, 0, 0 }; - gtk_style_context_get_padding(styleContextFrame, GTK_STATE_FLAG_NORMAL, &padding); - gtk_style_context_get_border(styleContextFrame, GTK_STATE_FLAG_NORMAL, &border); + gtk_style_context_get_padding(styleContextFrame, stateFlagsFrame, &padding); + gtk_style_context_get_border(styleContextFrame, stateFlagsFrame, &border); # if GTK_CHECK_VERSION(3,20,0) // on GTK 3.20 the frame border is in a sub-node "border". @@ -1564,7 +1565,7 @@ PRectangle ListBoxX::GetDesiredRect() { gtk_widget_path_iter_set_object_name(widget_path, -1, "border"); gtk_style_context_set_path(styleContextFrameBorder, widget_path); gtk_widget_path_free(widget_path); - gtk_style_context_get_border(styleContextFrameBorder, GTK_STATE_FLAG_NORMAL, &border_border); + gtk_style_context_get_border(styleContextFrameBorder, stateFlagsFrame, &border_border); g_object_unref(styleContextFrameBorder); # else // < 3.20 if (gtk_check_version(3, 20, 0) == NULL) { From 0a0c9bb7ce3d58939e32a8f47e46a3624c02e22d Mon Sep 17 00:00:00 2001 From: Neil Hodgson Date: Sat, 30 Apr 2016 14:03:28 +1000 Subject: [PATCH 7/8] Move function braces for consistency. X-Scintilla-Bug-URL: https://sourceforge.net/p/scintilla/bugs/1825/ X-Scintilla-Commit-ID: cdded8beb41e4a494e68b76a6bafeeae14b0d103 --- scintilla/gtk/PlatGTK.cxx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index 1b7f8c3b..700e8816 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -1263,8 +1263,7 @@ ListBox *ListBox::Allocate() { return lb; } -static int treeViewGetRowHeight(GtkTreeView *view) -{ +static int treeViewGetRowHeight(GtkTreeView *view) { #if GTK_CHECK_VERSION(3,0,0) // This version sometimes reports erroneous results on GTK2, but the GTK2 // version is inaccurate for GTK 3.14. @@ -1521,8 +1520,7 @@ int ListBoxX::GetVisibleRows() const { return desiredVisibleRows; } -int ListBoxX::GetRowHeight() -{ +int ListBoxX::GetRowHeight() { return treeViewGetRowHeight(GTK_TREE_VIEW(list)); } From bf3140004d1618e0ae5fad1595aadf6835a97551 Mon Sep 17 00:00:00 2001 From: Neil Hodgson Date: Sun, 1 May 2016 08:59:04 +1000 Subject: [PATCH 8/8] Do not call deprecated functions on newer GTK+. X-Scintilla-Bug-URL: https://sourceforge.net/p/scintilla/bugs/1825/ X-Scintilla-Commit-ID: 5e4f2e6c167ee30e2c2bfadd1b1579c3d8716c60 --- scintilla/gtk/ScintillaGTK.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scintilla/gtk/ScintillaGTK.cxx b/scintilla/gtk/ScintillaGTK.cxx index 4c068885..728e6743 100644 --- a/scintilla/gtk/ScintillaGTK.cxx +++ b/scintilla/gtk/ScintillaGTK.cxx @@ -472,8 +472,10 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { #else gdk_window_set_user_data(gtk_widget_get_window(widget), widget); #endif +#if !GTK_CHECK_VERSION(3,18,0) gtk_style_context_set_background(gtk_widget_get_style_context(widget), gtk_widget_get_window(widget)); +#endif gdk_window_show(gtk_widget_get_window(widget)); UnRefCursor(cursor); #else @@ -1223,7 +1225,9 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) { gtk_adjustment_set_upper(adjustmentv, nMax + 1); gtk_adjustment_set_page_size(adjustmentv, nPage); gtk_adjustment_set_page_increment(adjustmentv, pageScroll); +#if !GTK_CHECK_VERSION(3,18,0) gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv)); +#endif modified = true; } @@ -1242,7 +1246,9 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) { gtk_adjustment_set_page_size(adjustmenth, pageWidth); gtk_adjustment_set_page_increment(adjustmenth, pageIncrement); gtk_adjustment_set_step_increment(adjustmenth, charWidth); +#if !GTK_CHECK_VERSION(3,18,0) gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth)); +#endif modified = true; } if (modified && (paintState == painting)) {