Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Sun, 10 Mar 2013 16:20:25 UTC Commit: 35cc441b74dc8103144d09c429f5da5c11770680 https://github.com/geany/geany/commit/35cc441b74dc8103144d09c429f5da5c117706...
Log Message: ----------- Merge branch 'gtk3-support'
Conflicts: src/ui_utils.c
Modified Paths: -------------- Makefile.am configure.ac data/geany.css plugins/filebrowser.c plugins/saveactions.c plugins/splitwindow.c src/Makefile.am src/build.c src/callbacks.c src/dialogs.c src/document.c src/editor.c src/gb.c src/geanywraplabel.c src/gtkcompat.h src/keybindings.c src/notebook.c src/plugindata.h src/search.c src/sidebar.c src/socket.c src/stash.c src/toolbar.c src/ui_utils.c src/ui_utils.h src/vte.c
Modified: Makefile.am 7 files changed, 6 insertions(+), 1 deletions(-) =================================================================== @@ -24,8 +24,13 @@ SYS_DATA_FILES = \ $(srcdir)/data/templates/* \ $(srcdir)/data/templates/files/* \ $(srcdir)/data/colorschemes/* \ - $(top_srcdir)/data/geany.glade \ + $(top_srcdir)/data/geany.glade + +if GTK3 + $(top_srcdir)/data/geany.css +else $(top_srcdir)/data/geany.gtkrc +endif
EXTRA_DIST = \ autogen.sh \
Modified: configure.ac 17 files changed, 15 insertions(+), 2 deletions(-) =================================================================== @@ -56,14 +56,27 @@ GEANY_CHECK_REVISION([dnl force debug mode for a SVN working copy CFLAGS="-g -DGEANY_DEBUG $CFLAGS"])
+AC_ARG_ENABLE([gtk3], + [AS_HELP_STRING([--enable-gtk3], + [compile with GTK3 support (experimental) [default=no]])], + [enable_gtk3=$enableval], + [enable_gtk3=no]) + +AS_IF([test "x$enable_gtk3" = xyes], + [gtk_package=gtk+-3.0 + gtk_min_version=3.0], + [gtk_package=gtk+-2.0 + gtk_min_version=2.16]) +AM_CONDITIONAL([GTK3], [test "x$gtk_package" = "xgtk+-3.0"]) + # GTK/GLib/GIO checks -gtk_modules="gtk+-2.0 >= 2.16 glib-2.0 >= 2.20" +gtk_modules="$gtk_package >= $gtk_min_version glib-2.0 >= 2.20" gtk_modules_private="gio-2.0 >= 2.20 gmodule-2.0" PKG_CHECK_MODULES([GTK], [$gtk_modules $gtk_modules_private]) AC_SUBST([DEPENDENCIES], [$gtk_modules]) AC_SUBST([GTK_CFLAGS]) AC_SUBST([GTK_LIBS]) -GTK_VERSION=`$PKG_CONFIG --modversion gtk+-2.0` +GTK_VERSION=`$PKG_CONFIG --modversion $gtk_package` GEANY_STATUS_ADD([Using GTK version], [${GTK_VERSION}]) # GTHREAD checks gthread_modules="gthread-2.0"
Modified: data/geany.css 36 files changed, 36 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,36 @@ +/* custom GTK3 CSS for Geany */ + +/* make close button on the editor's tabs smaller */ +#geany-close-tab-button { + -GtkWidget-focus-padding: 0; + -GtkWidget-focus-line-width: 0; + -GtkButton-default-border: 0; + -GtkButton-default-outside-border: 0; + -GtkButton-inner-border: 0; + padding: 0; +} + +/* use monospaced font in search entries for easier reading of regexp (#1907117) */ +#GeanyDialogSearch GtkEntry { + font-family: monospace; +} + +/* set red background for GtkEntries showing unmatched searches */ +#geany-search-entry-no-match { + color: #fff; + background: #ff6666; +} +#geany-search-entry-no-match:selected { + background-color: #771111; +} + +/* document status colors */ +#geany-document-status-changed { + color: #ff0000; +} +#geany-document-status-disk-changed { + color: #ff7f00; +} +#geany-document-status-readonly { + color: #007f00; +}
Modified: plugins/filebrowser.c 9 files changed, 5 insertions(+), 4 deletions(-) =================================================================== @@ -26,6 +26,7 @@ #endif
#include "geanyplugin.h" +#include "gtkcompat.h" #include <string.h>
#include <gdk/gdkkeysyms.h> @@ -280,7 +281,7 @@ static void refresh(void) utf8_dir = utils_get_utf8_from_locale(current_dir); gtk_entry_set_text(GTK_ENTRY(path_entry), utf8_dir); gtk_widget_set_tooltip_text(path_entry, utf8_dir); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(path_combo), utf8_dir, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(path_combo), utf8_dir, 0); g_free(utf8_dir);
add_top_level_entry(); /* ".." item */ @@ -803,7 +804,7 @@ static void on_filter_activate(GtkEntry *entry, gpointer user_data) { clear_filter(); } - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(filter_combo), NULL, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(filter_combo), NULL, 0); refresh(); }
@@ -897,7 +898,7 @@ static GtkWidget *make_filterbar(void)
label = gtk_label_new(_("Filter:"));
- filter_combo = gtk_combo_box_entry_new_text(); + filter_combo = gtk_combo_box_text_new_with_entry(); filter_entry = gtk_bin_get_child(GTK_BIN(filter_combo));
ui_entry_add_clear_icon(GTK_ENTRY(filter_entry)); @@ -1091,7 +1092,7 @@ void plugin_init(GeanyData *data) filterbar = make_filterbar(); gtk_box_pack_start(GTK_BOX(file_view_vbox), filterbar, FALSE, FALSE, 0);
- path_combo = gtk_combo_box_entry_new_text(); + path_combo = gtk_combo_box_text_new_with_entry(); gtk_box_pack_start(GTK_BOX(file_view_vbox), path_combo, FALSE, FALSE, 2); g_signal_connect(path_combo, "changed", G_CALLBACK(ui_combo_box_changed), NULL); path_entry = gtk_bin_get_child(GTK_BIN(path_combo));
Modified: plugins/saveactions.c 11 files changed, 6 insertions(+), 5 deletions(-) =================================================================== @@ -25,6 +25,7 @@ #endif
#include "geanyplugin.h" +#include "gtkcompat.h"
#include <unistd.h> #include <errno.h> @@ -429,8 +430,8 @@ static void configure_response_cb(GtkDialog *dialog, gint response, G_GNUC_UNUSE GTK_TOGGLE_BUTTON(pref_widgets.autosave_save_all_radio2));
g_free(instantsave_default_ft); - instantsave_default_ft = gtk_combo_box_get_active_text( - GTK_COMBO_BOX(pref_widgets.instantsave_ft_combo)); + instantsave_default_ft = gtk_combo_box_text_get_active_text( + GTK_COMBO_BOX_TEXT(pref_widgets.instantsave_ft_combo));
text_dir = gtk_entry_get_text(GTK_ENTRY(pref_widgets.backupcopy_entry_dir)); text_time = gtk_entry_get_text(GTK_ENTRY(pref_widgets.backupcopy_entry_time)); @@ -529,7 +530,7 @@ GtkWidget *plugin_configure(GtkDialog *dialog) vbox = gtk_vbox_new(FALSE, 6);
notebook = gtk_notebook_new(); - GTK_WIDGET_UNSET_FLAGS(notebook, GTK_CAN_FOCUS); + gtk_widget_set_can_focus(notebook, FALSE); gtk_container_set_border_width(GTK_CONTAINER(notebook), 5); gtk_box_pack_start(GTK_BOX(vbox), notebook, FALSE, TRUE, 0);
@@ -620,13 +621,13 @@ GtkWidget *plugin_configure(GtkDialog *dialog) gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(inner_vbox), label, FALSE, FALSE, 0);
- pref_widgets.instantsave_ft_combo = combo = gtk_combo_box_new_text(); + pref_widgets.instantsave_ft_combo = combo = gtk_combo_box_text_new(); i = 0; foreach_slist(node, filetypes_get_sorted_by_name()) { GeanyFiletype *ft = node->data;
- gtk_combo_box_append_text(GTK_COMBO_BOX(combo), ft->name); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ft->name);
if (utils_str_equal(ft->name, instantsave_default_ft)) gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i);
Modified: plugins/splitwindow.c 5 files changed, 3 insertions(+), 2 deletions(-) =================================================================== @@ -26,6 +26,7 @@ #endif
#include "geanyplugin.h" +#include "gtkcompat.h" #include <string.h>
@@ -300,8 +301,8 @@ static void split_view(gboolean horizontal) GtkWidget *parent = gtk_widget_get_parent(notebook); GtkWidget *pane, *toolbar, *box; GeanyDocument *doc = document_get_current(); - gint width = notebook->allocation.width / 2; - gint height = notebook->allocation.height / 2; + gint width = gtk_widget_get_allocated_width(notebook) / 2; + gint height = gtk_widget_get_allocated_height(notebook) / 2;
g_return_if_fail(doc); g_return_if_fail(edit_window.editor == NULL);
Modified: src/Makefile.am 2 files changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -20,6 +20,7 @@ SRCS = \ geanymenubuttonaction.c geanymenubuttonaction.h \ geanyobject.c geanyobject.h \ geanywraplabel.c geanywraplabel.h \ + gtkcompat.h \ highlighting.c highlighting.h \ highlightingmappings.h \ keybindings.c keybindings.h \ @@ -59,6 +60,7 @@ geany_include_HEADERS = \ encodings.h \ filetypes.h \ geany.h \ + gtkcompat.h \ highlighting.h \ keybindings.h \ msgwindow.h \
Modified: src/build.c 3 files changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -61,6 +61,7 @@ #include "win32.h" #include "toolbar.h" #include "geanymenubuttonaction.h" +#include "gtkcompat.h"
/* g_spawn_async_with_pipes doesn't work on Windows */ #ifdef G_OS_WIN32 @@ -1922,7 +1923,7 @@ static void on_label_button_clicked(GtkWidget *wid, gpointer user_data) const gchar *old = gtk_button_get_label(GTK_BUTTON(wid)); gchar *str;
- if (GTK_WIDGET_TOPLEVEL(top_level) && GTK_IS_WINDOW(top_level)) + if (gtk_widget_is_toplevel(top_level) && GTK_IS_WINDOW(top_level)) str = dialogs_show_input(_("Set menu item label"), GTK_WINDOW(top_level), NULL, old); else str = dialogs_show_input(_("Set menu item label"), NULL, NULL, old);
Modified: src/callbacks.c 3 files changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -65,6 +65,7 @@ #include "toolbar.h" #include "highlighting.h" #include "pluginutils.h" +#include "gtkcompat.h"
#ifdef HAVE_VTE @@ -1811,7 +1812,7 @@ G_MODULE_EXPORT void on_back_activate(GtkMenuItem *menuitem, gpointer user_data)
G_MODULE_EXPORT gboolean on_motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { - if (prefs.auto_focus && ! GTK_WIDGET_HAS_FOCUS(widget)) + if (prefs.auto_focus && ! gtk_widget_has_focus(widget)) gtk_widget_grab_focus(widget);
return FALSE;
Modified: src/dialogs.c 25 files changed, 20 insertions(+), 5 deletions(-) =================================================================== @@ -55,6 +55,7 @@ #include "build.h" #include "main.h" #include "project.h" +#include "gtkcompat.h"
enum @@ -319,7 +320,7 @@ static GtkWidget *add_file_open_extra_widget(GtkWidget *dialog) (GtkAttachOptions) (0), 4, 5); /* the ebox is for the tooltip, because gtk_combo_box can't show tooltips */ filetype_ebox = gtk_event_box_new(); - filetype_combo = gtk_combo_box_new_text(); + filetype_combo = gtk_combo_box_text_new(); gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(filetype_combo), 2); gtk_widget_set_tooltip_text(filetype_ebox, _("Explicitly defines a filetype for the file, if it would not be detected by filename extension.\nNote if you choose multiple files, they will all be opened with the chosen filetype.")); @@ -377,7 +378,7 @@ static GtkWidget *create_open_file_dialog(void) gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), add_file_open_extra_widget(dialog)); filetype_combo = ui_lookup_widget(dialog, "filetype_combo");
- gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), _("Detect by file extension")); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(filetype_combo), _("Detect by file extension")); /* add FileFilters(start with "All Files") */ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filetypes_create_file_filter(filetypes[GEANY_FILETYPES_NONE])); @@ -390,7 +391,7 @@ static GtkWidget *create_open_file_dialog(void)
if (G_UNLIKELY(ft->id == GEANY_FILETYPES_NONE)) continue; - gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), ft->title); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(filetype_combo), ft->title); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filetypes_create_file_filter(ft)); } gtk_combo_box_set_active(GTK_COMBO_BOX(filetype_combo), 0); @@ -820,6 +821,20 @@ gboolean dialogs_show_unsaved_file(GeanyDocument *doc)
#ifndef G_OS_WIN32 +/* Use GtkFontChooserDialog on GTK3.2 for consistency, and because + * GtkFontSelectionDialog is somewhat broken on 3.4 */ +#if GTK_CHECK_VERSION(3, 2, 0) +# undef GTK_FONT_SELECTION_DIALOG +# define GTK_FONT_SELECTION_DIALOG GTK_FONT_CHOOSER_DIALOG + +# define gtk_font_selection_dialog_new(title) \ + gtk_font_chooser_dialog_new((title), NULL) +# define gtk_font_selection_dialog_get_font_name(dlg) \ + gtk_font_chooser_get_font(GTK_FONT_CHOOSER(dlg)) +# define gtk_font_selection_dialog_set_font_name(dlg, font) \ + gtk_font_chooser_set_font(GTK_FONT_CHOOSER(dlg), (font)) +#endif + static void on_font_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) { @@ -926,7 +941,7 @@ void dialogs_show_open_font() if (persistent) { GtkWidget *combo = (GtkWidget *) g_object_get_data(G_OBJECT(dialog), "combo"); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(combo), str, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(combo), str, 0); } input_cb(str); } @@ -950,7 +965,7 @@ static void add_input_widgets(GtkWidget *dialog, GtkWidget *vbox,
if (persistent) /* remember previous entry text in a combo box */ { - GtkWidget *combo = gtk_combo_box_entry_new_text(); + GtkWidget *combo = gtk_combo_box_text_new_with_entry();
entry = gtk_bin_get_child(GTK_BIN(combo)); ui_entry_add_clear_icon(GTK_ENTRY(entry));
Modified: src/document.c 20 files changed, 20 insertions(+), 0 deletions(-) =================================================================== @@ -2771,6 +2771,25 @@ const GdkColor *document_get_status_color(GeanyDocument *doc) return NULL; if (! document_status_styles[status].loaded) { +#if GTK_CHECK_VERSION(3, 0, 0) + GdkRGBA color; + GtkWidgetPath *path = gtk_widget_path_new(); + GtkStyleContext *ctx = gtk_style_context_new(); + gtk_widget_path_append_type(path, GTK_TYPE_WINDOW); + gtk_widget_path_append_type(path, GTK_TYPE_BOX); + gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK); + gtk_widget_path_append_type(path, GTK_TYPE_LABEL); + gtk_widget_path_iter_set_name(path, -1, document_status_styles[status].name); + gtk_style_context_set_screen(ctx, gtk_widget_get_screen(GTK_WIDGET(doc->editor->sci))); + gtk_style_context_set_path(ctx, path); + gtk_style_context_get_color(ctx, GTK_STATE_NORMAL, &color); + document_status_styles[status].color.red = 0xffff * color.red; + document_status_styles[status].color.green = 0xffff * color.green; + document_status_styles[status].color.blue = 0xffff * color.blue; + document_status_styles[status].loaded = TRUE; + gtk_widget_path_unref(path); + g_object_unref(ctx); +#else GtkSettings *settings = gtk_widget_get_settings(GTK_WIDGET(doc->editor->sci)); gchar *path = g_strconcat("GeanyMainWindow.GtkHBox.GtkNotebook.", document_status_styles[status].name, NULL); @@ -2779,6 +2798,7 @@ const GdkColor *document_get_status_color(GeanyDocument *doc) document_status_styles[status].color = style->fg[GTK_STATE_NORMAL]; document_status_styles[status].loaded = TRUE; g_free(path); +#endif } return &document_status_styles[status].color; }
Modified: src/editor.c 15 files changed, 14 insertions(+), 1 deletions(-) =================================================================== @@ -60,6 +60,7 @@ #include "projectprivate.h" #include "main.h" #include "highlighting.h" +#include "gtkcompat.h"
/* Note: use sciwrappers.h instead where possible. @@ -192,7 +193,7 @@ static void on_snippet_keybinding_activate(gchar *key) const gchar *s; GHashTable *specials;
- if (!doc || !GTK_WIDGET_HAS_FOCUS(doc->editor->sci)) + if (!doc || !gtk_widget_has_focus(GTK_WIDGET(doc->editor->sci))) return;
s = snippets_find_completion_by_name(doc->file_type->name, key); @@ -4645,6 +4646,14 @@ static gboolean on_editor_expose_event(GtkWidget *widget, GdkEventExpose *event, }
+#if GTK_CHECK_VERSION(3, 0, 0) +static gboolean on_editor_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data) +{ + return on_editor_expose_event(widget, NULL, user_data); +} +#endif + + static void setup_sci_keys(ScintillaObject *sci) { /* disable some Scintilla keybindings to be able to redefine them cleanly */ @@ -4768,7 +4777,11 @@ static ScintillaObject *create_new_sci(GeanyEditor *editor) g_signal_connect(sci, "scroll-event", G_CALLBACK(on_editor_scroll_event), editor); g_signal_connect(sci, "motion-notify-event", G_CALLBACK(on_motion_event), NULL); g_signal_connect(sci, "focus-in-event", G_CALLBACK(on_editor_focus_in), editor); +#if GTK_CHECK_VERSION(3, 0, 0) + g_signal_connect(sci, "draw", G_CALLBACK(on_editor_draw), editor); +#else g_signal_connect(sci, "expose-event", G_CALLBACK(on_editor_expose_event), editor); +#endif } return sci; }
Modified: src/gb.c 3 files changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -29,6 +29,7 @@ #include <signal.h> #include <unistd.h> #include <gdk-pixbuf/gdk-pixdata.h> +#include "gtkcompat.h"
#define MAX_PICS 10 #define LOOP_DELAY 200000 /* micro seconds */ @@ -191,7 +192,7 @@ static GtkWidget *create_help_dialog(GtkWindow *parent) okbutton1 = gtk_button_new_from_stock(GTK_STOCK_OK); gtk_widget_show(okbutton1); gtk_dialog_add_action_widget(GTK_DIALOG(help_dialog), okbutton1, GTK_RESPONSE_OK); - GTK_WIDGET_SET_FLAGS(okbutton1, GTK_CAN_DEFAULT); + gtk_widget_set_can_default(okbutton1, TRUE);
return help_dialog; }
Modified: src/geanywraplabel.c 99 files changed, 96 insertions(+), 3 deletions(-) =================================================================== @@ -30,7 +30,6 @@ #include "geanywraplabel.h"
- struct _GeanyWrapLabelClass { GtkLabelClass parent_class; @@ -49,9 +48,22 @@ struct _GeanyWrapLabel };
+#if GTK_CHECK_VERSION(3, 0, 0) +static gboolean geany_wrap_label_draw(GtkWidget *widget, cairo_t *cr); +static void geany_wrap_label_get_preferred_width (GtkWidget *widget, + gint *minimal_width, gint *natural_width); +static void geany_wrap_label_get_preferred_height (GtkWidget *widget, + gint *minimal_height, gint *natural_height); +static void geany_wrap_label_get_preferred_width_for_height (GtkWidget *widget, + gint height, gint *minimal_width, gint *natural_width); +static void geany_wrap_label_get_preferred_height_for_width (GtkWidget *widget, + gint width, gint *minimal_height, gint *natural_height); +static GtkSizeRequestMode geany_wrap_label_get_request_mode(GtkWidget *widget); +#else +static gboolean geany_wrap_label_expose (GtkWidget *widget, GdkEventExpose *event); static void geany_wrap_label_size_request (GtkWidget *widget, GtkRequisition *req); +#endif static void geany_wrap_label_size_allocate (GtkWidget *widget, GtkAllocation *alloc); -static gboolean geany_wrap_label_expose (GtkWidget *widget, GdkEventExpose *event); static void geany_wrap_label_set_wrap_width (GtkWidget *widget, gint width); static void geany_wrap_label_label_notify (GObject *object, GParamSpec *pspec, gpointer data);
@@ -62,9 +74,18 @@ static void geany_wrap_label_class_init(GeanyWrapLabelClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- widget_class->size_request = geany_wrap_label_size_request; widget_class->size_allocate = geany_wrap_label_size_allocate; +#if GTK_CHECK_VERSION(3, 0, 0) + widget_class->draw = geany_wrap_label_draw; + widget_class->get_preferred_width = geany_wrap_label_get_preferred_width; + widget_class->get_preferred_width_for_height = geany_wrap_label_get_preferred_width_for_height; + widget_class->get_preferred_height = geany_wrap_label_get_preferred_height; + widget_class->get_preferred_height_for_width = geany_wrap_label_get_preferred_height_for_width; + widget_class->get_request_mode = geany_wrap_label_get_request_mode; +#else + widget_class->size_request = geany_wrap_label_size_request; widget_class->expose_event = geany_wrap_label_expose; +#endif
g_type_class_add_private(klass, sizeof (GeanyWrapLabelPrivate)); } @@ -119,6 +140,67 @@ static void geany_wrap_label_label_notify(GObject *object, GParamSpec *pspec, gp }
+#if GTK_CHECK_VERSION(3, 0, 0) +/* makes sure the layout is setup for rendering and chains to parent renderer */ +static gboolean geany_wrap_label_draw(GtkWidget *widget, cairo_t *cr) +{ + GeanyWrapLabel *self = GEANY_WRAP_LABEL(widget); + PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget)); + + pango_layout_set_width(layout, self->priv->wrap_width * PANGO_SCALE); + pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); + + return (* GTK_WIDGET_CLASS(geany_wrap_label_parent_class)->draw)(widget, cr); +} + + +static void geany_wrap_label_get_preferred_width (GtkWidget *widget, + gint *minimal_width, gint *natural_width) +{ + *minimal_width = *natural_width = 0; +} + + +static void geany_wrap_label_get_preferred_width_for_height (GtkWidget *widget, + gint height, gint *minimal_width, gint *natural_width) +{ + PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));; + + pango_layout_set_height(layout, height * PANGO_SCALE); + pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); + pango_layout_get_pixel_size(layout, natural_width, NULL); + + *minimal_width = 0; +} + + +static void geany_wrap_label_get_preferred_height (GtkWidget *widget, + gint *minimal_height, gint *natural_height) +{ + *minimal_height = *natural_height = GEANY_WRAP_LABEL(widget)->priv->wrap_height; +} + + +static void geany_wrap_label_get_preferred_height_for_width (GtkWidget *widget, + gint width, gint *minimal_height, gint *natural_height) +{ + PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget)); + + pango_layout_set_width(layout, width * PANGO_SCALE); + pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); + pango_layout_get_pixel_size(layout, NULL, natural_height); + + *minimal_height = *natural_height; +} + + +static GtkSizeRequestMode geany_wrap_label_get_request_mode(GtkWidget *widget) +{ + return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT; +} + +#else /* GTK3 */ + /* makes sure the layout is setup for rendering and chains to parent renderer */ static gboolean geany_wrap_label_expose(GtkWidget *widget, GdkEventExpose *event) { @@ -139,6 +221,7 @@ static void geany_wrap_label_size_request(GtkWidget *widget, GtkRequisition *req req->width = 0; req->height = GEANY_WRAP_LABEL(widget)->priv->wrap_height; } +#endif /* GTK3 */
/* Sets the wrap width to the width allocated to us. */ @@ -147,6 +230,16 @@ static void geany_wrap_label_size_allocate(GtkWidget *widget, GtkAllocation *all (* GTK_WIDGET_CLASS(geany_wrap_label_parent_class)->size_allocate)(widget, alloc);
geany_wrap_label_set_wrap_width(widget, alloc->width); + +#if GTK_CHECK_VERSION(3, 0, 0) +{ + /* ask the parent to recompute our size, because it seems GTK3 size + * caching is too aggressive */ + GtkWidget *parent = gtk_widget_get_parent(widget); + if (GTK_IS_CONTAINER(parent)) + gtk_container_check_resize(GTK_CONTAINER(parent)); +} +#endif }
Modified: src/gtkcompat.h 128 files changed, 128 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,128 @@ +/* + * gtkcompat.h - this file is part of Geany, a fast and lightweight IDE + * + * Copyright 2012 Colomban Wendling <ban(at)herbesfolles(dot)org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Compatibility macros to support older GTK+ versions */ + +#ifndef GTK_COMPAT_H +#define GTK_COMPAT_H + +#include <gtk/gtk.h> +#if GTK_CHECK_VERSION(3, 0, 0) +# include <gdk/gdkkeysyms-compat.h> +#endif + +G_BEGIN_DECLS + + +/* GtkComboBoxText */ +/* This is actually available in GTK 2.24, but we expose GtkComboBoxText in the + * API so we don't want the type to change for no good reason (although this + * should probably be harmless since it's only a derivated type). However, since + * a plugin needs to be rebuilt and tuned to work with GTK3 we don't mind that + * a type changes between the GTK2 and GTK3 version */ +#if ! GTK_CHECK_VERSION(3, 0, 0) +/* undef those not to get warnings about redefinitions under GTK 2.24 */ +# undef GTK_COMBO_BOX_TEXT +# undef GTK_COMBO_BOX_TEXT_CLASS +# undef GTK_COMBO_BOX_TEXT_GET_CLASS +# undef GTK_IS_COMBO_BOX_TEXT +# undef GTK_IS_COMBO_BOX_TEXT_CLASS +# undef GTK_TYPE_COMBO_BOX_TEXT + +# define GTK_COMBO_BOX_TEXT GTK_COMBO_BOX +# define GTK_COMBO_BOX_TEXT_CLASS GTK_COMBO_BOX_CLASS +# define GTK_COMBO_BOX_TEXT_GET_CLASS GTK_COMBO_BOX_GET_CLASS +# define GTK_IS_COMBO_BOX_TEXT GTK_IS_COMBO_BOX +# define GTK_IS_COMBO_BOX_TEXT_CLASS GTK_IS_COMBO_BOX_CLASS +# define GTK_TYPE_COMBO_BOX_TEXT GTK_TYPE_COMBO_BOX +# define GtkComboBoxText GtkComboBox +# define gtk_combo_box_text_new gtk_combo_box_new_text +# define gtk_combo_box_text_new_with_entry gtk_combo_box_entry_new_text +# define gtk_combo_box_text_append_text gtk_combo_box_append_text +# define gtk_combo_box_text_insert_text gtk_combo_box_insert_text +# define gtk_combo_box_text_prepend_text gtk_combo_box_prepend_text +# define gtk_combo_box_text_remove gtk_combo_box_remove_text +# define gtk_combo_box_text_get_active_text gtk_combo_box_get_active_text +#endif + +/* GtkDialog */ +/* GTK 2.22 deprecated dialog separators and 3.0 removed them + * We keep those however in case 2.16 has separators by default */ +#if GTK_CHECK_VERSION(3, 0, 0) +# define gtk_dialog_set_has_separator(dialog, setting) /* nothing */ +# define GTK_DIALOG_NO_SEPARATOR 0 +#endif + +/* GtkWidget */ +#if ! GTK_CHECK_VERSION(2, 18, 0) +# define compat_widget_set_flag(widget, flag, enable) \ + ((enable) ? GTK_WIDGET_SET_FLAGS((widget), (flag)) : GTK_WIDGET_UNSET_FLAGS((widget), (flag))) +# define gtk_widget_set_can_default(widget, can_default) \ + compat_widget_set_flag((widget), GTK_CAN_DEFAULT, (can_default)) +# define gtk_widget_is_toplevel(widget) GTK_WIDGET_TOPLEVEL(widget) +# define gtk_widget_is_sensitive(widget) GTK_WIDGET_IS_SENSITIVE(widget) +# define gtk_widget_has_focus(widget) GTK_WIDGET_HAS_FOCUS(widget) +# define gtk_widget_get_sensitive(widget) GTK_WIDGET_SENSITIVE(widget) +# define gtk_widget_set_has_window(widget, has_window) \ + compat_widget_set_flag((widget), GTK_NO_WINDOW, !(has_window)) +# define gtk_widget_set_can_focus(widget, can_focus) \ + compat_widget_set_flag((widget), GTK_CAN_FOCUS, (can_focus)) +#endif +#if ! GTK_CHECK_VERSION(2, 20, 0) +# define gtk_widget_get_mapped(widget) GTK_WIDGET_MAPPED(widget) +#endif +#if ! GTK_CHECK_VERSION(3, 0, 0) +# define gtk_widget_get_allocated_height(widget) (((GtkWidget *) (widget))->allocation.height) +# define gtk_widget_get_allocated_width(widget) (((GtkWidget *) (widget))->allocation.width) +#endif + + +/* Mappings below only prevent some deprecation warnings on GTK3 for things + * that didn't exist on GTK2. That's not future-proof. */ +#if GTK_CHECK_VERSION(3, 0, 0) +/* Gtk[VH]Box */ +# define compat_gtk_box_new(orientation, homogeneous, spacing) \ + g_object_new(GTK_TYPE_BOX, \ + "orientation", (orientation), \ + "homogeneous", (homogeneous), \ + "spacing", (spacing), \ + NULL) +# define gtk_vbox_new(homogeneous, spacing) \ + compat_gtk_box_new(GTK_ORIENTATION_VERTICAL, (homogeneous), (spacing)) +# define gtk_hbox_new(homogeneous, spacing) \ + compat_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, (homogeneous), (spacing)) +/* Gtk[VH]ButtonBox */ +# define gtk_vbutton_box_new() gtk_button_box_new(GTK_ORIENTATION_VERTICAL) +# define gtk_hbutton_box_new() gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL) +/* Gtk[VH]Separator */ +# define gtk_vseparator_new() gtk_separator_new(GTK_ORIENTATION_VERTICAL) +# define gtk_hseparator_new() gtk_separator_new(GTK_ORIENTATION_HORIZONTAL) +/* Gtk[VH]Paned */ +# define gtk_vpaned_new() gtk_paned_new(GTK_ORIENTATION_VERTICAL) +# define gtk_hpaned_new() gtk_paned_new(GTK_ORIENTATION_HORIZONTAL) +/* Gtk[VH]Scrollbar */ +# define gtk_vscrollbar_new(adj) gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, (adj)) +# define gtk_hscrollbar_new(adj) gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, (adj)) +#endif + + +G_END_DECLS + +#endif /* GTK_COMPAT_H */
Modified: src/keybindings.c 23 files changed, 18 insertions(+), 5 deletions(-) =================================================================== @@ -56,6 +56,7 @@ #include "geanywraplabel.h" #include "main.h" #include "search.h" +#include "gtkcompat.h" #ifdef HAVE_VTE # include "vte.h" #endif @@ -1072,12 +1073,20 @@ static gboolean check_menu_key(GeanyDocument *doc, guint keyval, guint state, gu static gboolean on_menu_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { - if (!GTK_WIDGET_SENSITIVE(widget)) + if (!gtk_widget_get_sensitive(widget)) gtk_widget_set_sensitive(GTK_WIDGET(widget), TRUE); return FALSE; }
+#if GTK_CHECK_VERSION(3, 0, 0) +static gboolean on_menu_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data) +{ + return on_menu_expose_event(widget, NULL, user_data); +} +#endif + + static gboolean set_sensitive(gpointer widget) { gtk_widget_set_sensitive(GTK_WIDGET(widget), TRUE); @@ -1122,7 +1131,11 @@ static gboolean check_vte(GdkModifierType state, guint keyval) /* make the menubar sensitive before it is redrawn */ static gboolean connected = FALSE; if (!connected) +#if GTK_CHECK_VERSION(3, 0, 0) + g_signal_connect(widget, "draw", G_CALLBACK(on_menu_draw), NULL); +#else g_signal_connect(widget, "expose-event", G_CALLBACK(on_menu_expose_event), NULL); +#endif }
widget = main_widgets.editor_menu; @@ -1508,7 +1521,7 @@ static gboolean cb_func_build_action(guint key_id) if (doc == NULL) return TRUE;
- if (!GTK_WIDGET_IS_SENSITIVE(ui_lookup_widget(main_widgets.window, "menu_build1"))) + if (!gtk_widget_is_sensitive(ui_lookup_widget(main_widgets.window, "menu_build1"))) return TRUE;
menu_items = build_get_menu_items(doc->file_type->id); @@ -1548,7 +1561,7 @@ static gboolean cb_func_build_action(guint key_id) /* Note: For Build menu items it's OK (at the moment) to assume they are in the correct * sensitive state, but some other menus don't update the sensitive status until * they are redrawn. */ - if (item && GTK_WIDGET_IS_SENSITIVE(item)) + if (item && gtk_widget_is_sensitive(item)) gtk_menu_item_activate(GTK_MENU_ITEM(item)); return TRUE; } @@ -1631,7 +1644,7 @@ static gboolean cb_func_switch_action(guint key_id) if (doc != NULL) { GtkWidget *sci = GTK_WIDGET(doc->editor->sci); - if (GTK_WIDGET_HAS_FOCUS(sci)) + if (gtk_widget_has_focus(sci)) ui_update_statusbar(doc, -1); else gtk_widget_grab_focus(sci); @@ -1861,7 +1874,7 @@ static gboolean cb_func_goto_action(guint key_id) GtkWidget *wid = toolbar_get_widget_child_by_name("GotoEntry");
/* use toolbar item if shown & not in the drop down overflow menu */ - if (wid && GTK_WIDGET_MAPPED(wid)) + if (wid && gtk_widget_get_mapped(wid)) { gtk_widget_grab_focus(wid); return TRUE;
Modified: src/notebook.c 11 files changed, 6 insertions(+), 5 deletions(-) =================================================================== @@ -38,6 +38,7 @@ #include "utils.h" #include "keybindings.h" #include "main.h" +#include "gtkcompat.h"
#define GEANY_DND_NOTEBOOK_TAB_TYPE "geany_dnd_notebook_tab"
@@ -376,11 +377,11 @@ static gboolean is_position_on_tab_bar(GtkNotebook *notebook, GdkEventButton *ev case GTK_POS_TOP: case GTK_POS_BOTTOM: { - if (event->y >= 0 && event->y <= tab->allocation.height) + if (event->y >= 0 && event->y <= gtk_widget_get_allocated_height(tab)) { if (! gtk_notebook_show_arrows(notebook) || ( x > scroll_arrow_hlength && - x < nb->allocation.width - scroll_arrow_hlength)) + x < gtk_widget_get_allocated_width(nb) - scroll_arrow_hlength)) return TRUE; } break; @@ -388,11 +389,11 @@ static gboolean is_position_on_tab_bar(GtkNotebook *notebook, GdkEventButton *ev case GTK_POS_LEFT: case GTK_POS_RIGHT: { - if (event->x >= 0 && event->x <= tab->allocation.width) + if (event->x >= 0 && event->x <= gtk_widget_get_allocated_width(tab)) { if (! gtk_notebook_show_arrows(notebook) || ( y > scroll_arrow_vlength && - y < nb->allocation.height - scroll_arrow_vlength)) + y < gtk_widget_get_allocated_height(nb) - scroll_arrow_vlength)) return TRUE; } } @@ -666,7 +667,7 @@ gint notebook_new_tab(GeanyDocument *this) /* get button press events for the tab label and the space between it and * the close button, if any */ ebox = gtk_event_box_new(); - GTK_WIDGET_SET_FLAGS(ebox, GTK_NO_WINDOW); + gtk_widget_set_has_window(ebox, FALSE); g_signal_connect(ebox, "button-press-event", G_CALLBACK(notebook_tab_click), page); /* focus the current document after clicking on a tab */ g_signal_connect_after(ebox, "button-release-event",
Modified: src/plugindata.h 12 files changed, 10 insertions(+), 2 deletions(-) =================================================================== @@ -41,6 +41,7 @@
#include "editor.h" /* GeanyIndentType */ #include "build.h" /* GeanyBuildGroup, GeanyBuildSource, GeanyBuildCmdEntries enums */ +#include "gtkcompat.h"
/** The Application Programming Interface (API) version, incremented @@ -56,12 +57,19 @@ */ #define GEANY_API_VERSION 216
+/* hack to have a different ABI when built with GTK3 because loading GTK2-linked plugins + * with GTK3-linked Geany leads to crash */ +#if GTK_CHECK_VERSION(3, 0, 0) +# define GEANY_ABI_SHIFT 8 +#else +# define GEANY_ABI_SHIFT 0 +#endif /** The Application Binary Interface (ABI) version, incremented whenever * existing fields in the plugin data types have to be changed or reordered. * Changing this forces all plugins to be recompiled before Geany can load them. */ /* This should usually stay the same if fields are only appended, assuming only pointers to * structs and not structs themselves are declared by plugins. */ -#define GEANY_ABI_VERSION 69 +#define GEANY_ABI_VERSION (69 << GEANY_ABI_SHIFT)
/** Defines a function to check the plugin is safe to load. @@ -476,7 +484,7 @@ void (*ui_widget_modify_font_from_string) (GtkWidget *widget, const gchar *str); gboolean (*ui_is_keyval_enter_or_return) (guint keyval); gint (*ui_get_gtk_settings_integer) (const gchar *property_name, gint default_value); - void (*ui_combo_box_add_to_history) (GtkComboBoxEntry *combo_entry, + void (*ui_combo_box_add_to_history) (GtkComboBoxText *combo_entry, const gchar *text, gint history_len); void (*ui_menu_add_document_items_sorted) (GtkMenu *menu, struct GeanyDocument *active, GCallback callback, GCompareFunc compare_func);
Modified: src/search.c 40 files changed, 20 insertions(+), 20 deletions(-) =================================================================== @@ -41,6 +41,7 @@ #include "keyfile.h" #include "stash.h" #include "toolbar.h" +#include "gtkcompat.h"
#include <unistd.h> #include <string.h> @@ -455,7 +456,7 @@ static void create_find_dialog(void) label = gtk_label_new_with_mnemonic(_("_Search for:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- entry = gtk_combo_box_entry_new_text(); + entry = gtk_combo_box_text_new_with_entry(); ui_entry_add_clear_icon(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry)))); gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry))), 50); @@ -551,7 +552,7 @@ void search_show_find_dialog(void) else { /* only set selection if the dialog is not already visible */ - if (! GTK_WIDGET_VISIBLE(find_dlg.dialog) && sel) + if (! gtk_widget_get_visible(find_dlg.dialog) && sel) gtk_entry_set_text(GTK_ENTRY(find_dlg.entry), sel); gtk_widget_grab_focus(find_dlg.entry); set_dialog_position(find_dlg.dialog, find_dlg.position); @@ -617,14 +618,14 @@ static void create_replace_dialog(void) label_replace = gtk_label_new_with_mnemonic(_("Replace wit_h:")); gtk_misc_set_alignment(GTK_MISC(label_replace), 0, 0.5);
- entry_find = gtk_combo_box_entry_new_text(); + entry_find = gtk_combo_box_text_new_with_entry(); ui_entry_add_clear_icon(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry_find)))); gtk_label_set_mnemonic_widget(GTK_LABEL(label_find), entry_find); gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry_find))), 50); ui_hookup_widget(replace_dlg.dialog, entry_find, "entry_find"); replace_dlg.find_entry = gtk_bin_get_child(GTK_BIN(entry_find));
- entry_replace = gtk_combo_box_entry_new_text(); + entry_replace = gtk_combo_box_text_new_with_entry(); ui_entry_add_clear_icon(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry_replace)))); gtk_label_set_mnemonic_widget(GTK_LABEL(label_replace), entry_replace); gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry_replace))), 50); @@ -725,7 +726,7 @@ void search_show_replace_dialog(void) else { /* only set selection if the dialog is not already visible */ - if (! GTK_WIDGET_VISIBLE(replace_dlg.dialog) && sel) + if (! gtk_widget_get_visible(replace_dlg.dialog) && sel) gtk_entry_set_text(GTK_ENTRY(replace_dlg.find_entry), sel); if (sel != NULL) /* when we have a selection, reset the entry widget's background colour */ ui_set_search_entry_background(replace_dlg.find_entry, TRUE); @@ -853,7 +854,7 @@ static void create_fif_dialog(void) label = gtk_label_new_with_mnemonic(_("_Search for:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- combo = gtk_combo_box_entry_new_text(); + combo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(combo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); @@ -877,7 +878,7 @@ static void create_fif_dialog(void) ui_hookup_widget(fif_dlg.dialog, combo_files_mode, "combo_files_mode"); fif_dlg.files_mode_combo = combo_files_mode;
- fcombo = gtk_combo_box_entry_new_text(); + fcombo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(fcombo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); @@ -896,7 +897,7 @@ static void create_fif_dialog(void) label1 = gtk_label_new_with_mnemonic(_("_Directory:")); gtk_misc_set_alignment(GTK_MISC(label1), 0, 0.5);
- dir_combo = gtk_combo_box_entry_new_text(); + dir_combo = gtk_combo_box_text_new_with_entry(); entry = gtk_bin_get_child(GTK_BIN(dir_combo)); ui_entry_add_clear_icon(GTK_ENTRY(entry)); gtk_label_set_mnemonic_widget(GTK_LABEL(label1), entry); @@ -914,11 +915,11 @@ static void create_fif_dialog(void) label2 = gtk_label_new_with_mnemonic(_("E_ncoding:")); gtk_misc_set_alignment(GTK_MISC(label2), 0, 0.5);
- e_combo = gtk_combo_box_new_text(); + e_combo = gtk_combo_box_text_new(); for (i = 0; i < GEANY_ENCODINGS_MAX; i++) { encoding_string = encodings_to_string(&encodings[i]); - gtk_combo_box_append_text(GTK_COMBO_BOX(e_combo), encoding_string); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(e_combo), encoding_string); g_free(encoding_string); } gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(e_combo), 3); @@ -1024,7 +1025,7 @@ void search_show_find_in_files_dialog(const gchar *dir) stash_group_display(fif_prefs, fif_dlg.dialog);
/* only set selection if the dialog is not already visible, or has just been created */ - if (doc && ! sel && ! GTK_WIDGET_VISIBLE(fif_dlg.dialog)) + if (doc && ! sel && ! gtk_widget_get_visible(fif_dlg.dialog)) sel = editor_get_default_selection(doc->editor, search_prefs.use_current_word, NULL);
entry = gtk_bin_get_child(GTK_BIN(fif_dlg.search_combo)); @@ -1036,7 +1037,7 @@ void search_show_find_in_files_dialog(const gchar *dir) * (in create_fif_dialog() it would fail if a project is opened after dialog creation) */ if (app->project != NULL && NZV(app->project->base_path)) { - ui_combo_box_prepend_text_once(GTK_COMBO_BOX(fif_dlg.dir_combo), + ui_combo_box_prepend_text_once(GTK_COMBO_BOX_TEXT(fif_dlg.dir_combo), app->project->base_path); }
@@ -1055,8 +1056,7 @@ void search_show_find_in_files_dialog(const gchar *dir) if (doc == last_doc && cur_dir && utils_str_equal(cur_dir, last_cur_dir)) { /* in case the user now wants the current directory, add it to history */ - ui_combo_box_add_to_history( - GTK_COMBO_BOX_ENTRY(fif_dlg.dir_combo), cur_dir, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(fif_dlg.dir_combo), cur_dir, 0); SETPTR(cur_dir, NULL); } else @@ -1241,7 +1241,7 @@ gint search_mark_all(GeanyDocument *doc, const gchar *search_text, gint flags) if (! utils_str_replace_escape(search_data.text, FALSE)) goto fail; } - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(user_data), search_data.original_text, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(user_data), search_data.original_text, 0);
switch (response) { @@ -1378,9 +1378,9 @@ static void replace_in_session(GeanyDocument *doc, goto fail; }
- ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY( + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT( gtk_widget_get_parent(replace_dlg.find_entry)), original_find, 0); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY( + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT( gtk_widget_get_parent(replace_dlg.replace_entry)), original_replace, 0);
switch (response) @@ -1520,9 +1520,9 @@ static GString *get_grep_options(void)
if (search_find_in_files(search_text, locale_dir, opts->str, enc)) { - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(search_combo), search_text, 0); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(fif_dlg.files_combo), NULL, 0); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(dir_combo), utf8_dir, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(search_combo), search_text, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(fif_dlg.files_combo), NULL, 0); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(dir_combo), utf8_dir, 0); gtk_widget_hide(fif_dlg.dialog); } g_free(locale_dir);
Modified: src/sidebar.c 8 files changed, 8 insertions(+), 0 deletions(-) =================================================================== @@ -588,16 +588,24 @@ void sidebar_add_common_menu_items(GtkMenu *menu)
item = gtk_check_menu_item_new_with_mnemonic(_("Show S_ymbol List")); gtk_container_add(GTK_CONTAINER(menu), item); +#if GTK_CHECK_VERSION(3, 0, 0) + g_signal_connect(item, "draw", G_CALLBACK(on_sidebar_display_symbol_list_show), NULL); +#else g_signal_connect(item, "expose-event", G_CALLBACK(on_sidebar_display_symbol_list_show), NULL); +#endif gtk_widget_show(item); g_signal_connect(item, "activate", G_CALLBACK(on_list_symbol_activate), NULL);
item = gtk_check_menu_item_new_with_mnemonic(_("Show _Document List")); gtk_container_add(GTK_CONTAINER(menu), item); +#if GTK_CHECK_VERSION(3, 0, 0) + g_signal_connect(item, "draw", G_CALLBACK(on_sidebar_display_open_files_show), NULL); +#else g_signal_connect(item, "expose-event", G_CALLBACK(on_sidebar_display_open_files_show), NULL); +#endif gtk_widget_show(item); g_signal_connect(item, "activate", G_CALLBACK(on_list_document_activate), NULL);
Modified: src/socket.c 10 files changed, 8 insertions(+), 2 deletions(-) =================================================================== @@ -663,12 +663,18 @@ gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpoint if (popup) { #ifdef GDK_WINDOWING_X11 + GdkWindow *x11_window = gtk_widget_get_window(window); + /* Set the proper interaction time on the window. This seems necessary to make * gtk_window_present() really bring the main window into the foreground on some * window managers like Gnome's metacity. * Code taken from Gedit. */ - gdk_x11_window_set_user_time(gtk_widget_get_window(window), - gdk_x11_get_server_time(gtk_widget_get_window(window))); +# if GTK_CHECK_VERSION(3, 0, 0) + if (GDK_IS_X11_WINDOW(x11_window)) +# endif + { + gdk_x11_window_set_user_time(x11_window, gdk_x11_get_server_time(x11_window)); + } #endif gtk_window_present(GTK_WINDOW(window)); #ifdef G_OS_WIN32
Modified: src/stash.c 24 files changed, 22 insertions(+), 2 deletions(-) =================================================================== @@ -85,6 +85,26 @@ #include "stash.h"
+/* GTK3 removed ComboBoxEntry, but we need a value to differentiate combo box with and + * without entries, and it must not collide with other GTypes */ +#ifdef GTK_TYPE_COMBO_BOX_ENTRY +# define TYPE_COMBO_BOX_ENTRY GTK_TYPE_COMBO_BOX_ENTRY +#else /* !GTK_TYPE_COMBO_BOX_ENTRY */ +# define TYPE_COMBO_BOX_ENTRY get_combo_box_entry_type() +static GType get_combo_box_entry_type(void) +{ + static volatile gsize type = 0; + if (g_once_init_enter(&type)) + { + GType g_type = g_type_register_static_simple(GTK_TYPE_COMBO_BOX, "dummy-combo-box-entry", + sizeof(GtkComboBoxClass), NULL, sizeof(GtkComboBox), NULL, G_TYPE_FLAG_ABSTRACT); + g_once_init_leave(&type, g_type); + } + return type; +} +#endif /* !GTK_TYPE_COMBO_BOX_ENTRY */ + + struct StashPref { GType setting_type; /* e.g. G_TYPE_INT */ @@ -696,7 +716,7 @@ static void pref_action(PrefAction action, StashGroup *group, GtkWidget *owner) handle_spin_button(widget, entry, action); else if (entry->widget_type == GTK_TYPE_COMBO_BOX) handle_combo_box(widget, entry, action); - else if (entry->widget_type == GTK_TYPE_COMBO_BOX_ENTRY) + else if (entry->widget_type == TYPE_COMBO_BOX_ENTRY) handle_combo_box_entry(widget, entry, action); else if (entry->widget_type == GTK_TYPE_ENTRY) handle_entry(widget, entry, action); @@ -861,7 +881,7 @@ void stash_group_add_combo_box_entry(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value, StashWidgetID widget_id) { add_widget_pref(group, G_TYPE_STRING, setting, key_name, (gpointer)default_value, - GTK_TYPE_COMBO_BOX_ENTRY, widget_id); + TYPE_COMBO_BOX_ENTRY, widget_id); }
Modified: src/toolbar.c 3 files changed, 3 insertions(+), 0 deletions(-) =================================================================== @@ -395,6 +395,9 @@ GtkWidget *toolbar_init(void) gtk_ui_manager_insert_action_group(uim, group, 0);
toolbar = toolbar_reload(NULL); +#if GTK_CHECK_VERSION(3, 0, 0) + gtk_style_context_add_class(gtk_widget_get_style_context(toolbar), "primary-toolbar"); +#endif
gtk_settings = gtk_widget_get_settings(GTK_WIDGET(toolbar)); if (gtk_settings != NULL)
Modified: src/ui_utils.c 43 files changed, 32 insertions(+), 11 deletions(-) =================================================================== @@ -55,6 +55,7 @@ #include "main.h" #include "stash.h" #include "keyfile.h" +#include "gtkcompat.h"
GeanyInterfacePrefs interface_prefs; @@ -1312,7 +1313,7 @@ GtkWidget *ui_dialog_vbox_new(GtkDialog *dialog) GtkWidget *vbox = gtk_vbox_new(FALSE, 12); /* need child vbox to set a separate border. */
gtk_container_set_border_width(GTK_CONTAINER(vbox), 6); - gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), vbox); + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), vbox, TRUE, TRUE, 0); return vbox; }
@@ -1465,7 +1466,7 @@ static gboolean tree_model_find_text(GtkTreeModel *model, * @param combo_entry . * @param text Text to add, or @c NULL for current entry text. * @param history_len Max number of items, or @c 0 for default. */ -void ui_combo_box_add_to_history(GtkComboBoxEntry *combo_entry, +void ui_combo_box_add_to_history(GtkComboBoxText *combo_entry, const gchar *text, gint history_len) { GtkComboBox *combo = GTK_COMBO_BOX(combo_entry); @@ -1484,7 +1485,7 @@ void ui_combo_box_add_to_history(GtkComboBoxEntry *combo_entry, { gtk_list_store_remove(GTK_LIST_STORE(model), &iter); } - gtk_combo_box_prepend_text(combo, text); + gtk_combo_box_text_prepend_text(combo_entry, text);
/* limit history */ path = gtk_tree_path_new_from_indices(history_len, -1); @@ -1496,18 +1497,18 @@ void ui_combo_box_add_to_history(GtkComboBoxEntry *combo_entry, }
-/* Same as gtk_combo_box_prepend_text(), except that text is only prepended if it not already +/* Same as gtk_combo_box_text_prepend_text(), except that text is only prepended if it not already * exists in the combo's model. */ -void ui_combo_box_prepend_text_once(GtkComboBox *combo, const gchar *text) +void ui_combo_box_prepend_text_once(GtkComboBoxText *combo, const gchar *text) { GtkTreeModel *model; GtkTreeIter iter;
- model = gtk_combo_box_get_model(combo); + model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); if (tree_model_find_text(model, &iter, 0, text)) return; /* don't prepend duplicate */
- gtk_combo_box_prepend_text(combo, text); + gtk_combo_box_text_prepend_text(combo, text); }
@@ -1911,7 +1912,7 @@ void ui_swap_sidebar_pos(void) g_object_unref(left); g_object_unref(right);
- gtk_paned_set_position(GTK_PANED(pane), pane->allocation.width + gtk_paned_set_position(GTK_PANED(pane), gtk_widget_get_allocated_width(pane) - gtk_paned_get_position(GTK_PANED(pane))); }
@@ -2160,10 +2161,30 @@ void ui_init_builder(void)
static void init_custom_style(void) { +#if GTK_CHECK_VERSION(3, 0, 0) + gchar *css_file = g_build_filename(app->datadir, "geany.css", NULL); + GtkCssProvider *css = gtk_css_provider_new(); + GError *error = NULL; + + if (! gtk_css_provider_load_from_path(css, css_file, &error)) + { + g_warning("Failed to load custom CSS: %s", error->message); + g_error_free(error); + } + else + { + gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), + GTK_STYLE_PROVIDER(css), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + } + + g_object_unref(css); + g_free(css_file); +#else gchar *gtkrc_file = g_build_filename(app->datadir, "geany.gtkrc", NULL);
gtk_rc_parse(gtkrc_file); g_free(gtkrc_file); +#endif }
@@ -2263,7 +2284,7 @@ static void on_auto_separator_item_show_hide(GtkWidget *widget, gpointer user_da { GeanyAutoSeparator *autosep = user_data;
- if (GTK_WIDGET_VISIBLE(widget)) + if (gtk_widget_get_visible(widget)) autosep->show_count++; else autosep->show_count--; @@ -2277,7 +2298,7 @@ static void on_auto_separator_item_destroy(GtkWidget *widget, gpointer user_data
autosep->item_count--; autosep->item_count = MAX(autosep->item_count, 0); - /* GTK_WIDGET_VISIBLE won't work now the widget is being destroyed, + /* gtk_widget_get_visible() won't work now the widget is being destroyed, * so assume widget was visible */ autosep->show_count--; autosep->show_count = MAX(autosep->item_count, 0); @@ -2296,7 +2317,7 @@ void ui_auto_separator_add_ref(GeanyAutoSeparator *autosep, GtkWidget *item) g_signal_connect(autosep->widget, "destroy", G_CALLBACK(gtk_widget_destroyed), &autosep->widget);
- if (GTK_WIDGET_VISIBLE(item)) + if (gtk_widget_get_visible(item)) autosep->show_count++;
autosep->item_count++;
Modified: src/ui_utils.h 6 files changed, 4 insertions(+), 2 deletions(-) =================================================================== @@ -22,6 +22,8 @@ #ifndef GEANY_UI_UTILS_H #define GEANY_UI_UTILS_H 1
+#include "gtkcompat.h" + G_BEGIN_DECLS
@@ -188,10 +190,10 @@
void ui_hbutton_box_copy_layout(GtkButtonBox *master, GtkButtonBox *copy);
-void ui_combo_box_add_to_history(GtkComboBoxEntry *combo_entry, +void ui_combo_box_add_to_history(GtkComboBoxText *combo_entry, const gchar *text, gint history_len);
-void ui_combo_box_prepend_text_once(GtkComboBox *combo, const gchar *text); +void ui_combo_box_prepend_text_once(GtkComboBoxText *combo, const gchar *text);
GtkWidget *ui_path_box_new(const gchar *title, GtkFileChooserAction action, GtkEntry *entry);
Modified: src/vte.c 13 files changed, 10 insertions(+), 3 deletions(-) =================================================================== @@ -49,6 +49,7 @@ #include "geanywraplabel.h" #include "editor.h" #include "sciwrappers.h" +#include "gtkcompat.h"
VteInfo vte_info; @@ -200,8 +201,14 @@ void vte_init(void) if (module == NULL) { gint i; - const gchar *sonames[] = { "libvte.so", "libvte.so.4", - "libvte.so.8", "libvte.so.9", NULL }; + const gchar *sonames[] = { +#if GTK_CHECK_VERSION(3, 0, 0) + "libvte2_90.so", "libvte2_90.so.9", +#else + "libvte.so", "libvte.so.4", "libvte.so.8", "libvte.so.9", +#endif + NULL + };
for (i = 0; sonames[i] != NULL && module == NULL; i++) { @@ -253,7 +260,7 @@ static void create_vte(void)
vc->vte = vte = vf->vte_terminal_new(); scrollbar = gtk_vscrollbar_new(GTK_ADJUSTMENT(VTE_TERMINAL(vte)->adjustment)); - GTK_WIDGET_UNSET_FLAGS(scrollbar, GTK_CAN_FOCUS); + gtk_widget_set_can_focus(scrollbar, FALSE);
/* create menu now so copy/paste shortcuts work */ vc->menu = vte_create_popup_menu();
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).