Replace dynamic exports with codegen for GtkBuilder callbacks
This prevents having to export those callbacks and put them in the global namespace. Also, use inline shell script in Makefile.am instead of a Python script which should be more portable (by default) and gets rid of the helper script.
This commit is contained in:
parent
eb36500ac4
commit
1d64d5211f
@ -24,25 +24,14 @@ dnl `__attribute__((visibility(...)))` extension and use it if so.
|
||||
])
|
||||
CFLAGS="${libgeany_backup_cflags}"
|
||||
|
||||
dnl Try and see if we can use our list of dynamically exported symbols with
|
||||
dnl the linker and use it if so.
|
||||
AC_MSG_CHECKING([whether linker supports --dynamic-list])
|
||||
libgeany_backup_ldflags=$LDFLAGS
|
||||
LDFLAGS=-Wl,--dynamic-list="${srcdir}/src/dynamicsymbols.list"
|
||||
AC_LINK_IFELSE([
|
||||
AC_LANG_PROGRAM([], [])
|
||||
], [
|
||||
LIBGEANY_LIBS="-Wl,--dynamic-list=\"\$(top_srcdir)/src/dynamicsymbols.list\""
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
LIBGEANY_LIBS=""
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
LDFLAGS="${libgeany_backup_ldflags}"
|
||||
|
||||
LIBGEANY_LIBS="${LIBGEANY_LIBS} -version-info ${libgeany_current}:${libgeany_revision}:${libgeany_age}"
|
||||
LIBGEANY_LIBS="-version-info ${libgeany_current}:${libgeany_revision}:${libgeany_age}"
|
||||
|
||||
AC_SUBST([LIBGEANY_CFLAGS])
|
||||
AC_SUBST([LIBGEANY_LIBS])
|
||||
|
||||
dnl Check for utilities needed to do codegen
|
||||
AC_PATH_PROG([SORT], [sort], [
|
||||
AC_MSG_ERROR([The 'sort' utility is required, is it installed?])])
|
||||
AC_PATH_PROG([UNIQ], [uniq], [
|
||||
AC_MSG_ERROR([The 'uniq' utility is required, is it installed?])])
|
||||
])
|
||||
|
@ -1,73 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Script to parse GtkBuilder XML file for signal handler references and list
|
||||
them in a linker file for which symbols to dynamically export.
|
||||
"""
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
def find_handlers(xml_filename, excludes=[]):
|
||||
def is_excluded(name, excludes):
|
||||
for exclude in excludes:
|
||||
m = re.match(exclude, name)
|
||||
if m:
|
||||
return True
|
||||
return False
|
||||
|
||||
tree = ET.parse(xml_filename)
|
||||
root = tree.getroot()
|
||||
handlers = []
|
||||
signals = root.findall(".//signal")
|
||||
|
||||
for signal in signals:
|
||||
handler = signal.attrib["handler"]
|
||||
if not is_excluded(handler, excludes):
|
||||
handlers.append(handler)
|
||||
|
||||
return sorted(handlers)
|
||||
|
||||
def write_dynamic_list(handlers, output_file):
|
||||
output_file.write("""\
|
||||
/* This file was auto-generated by the `%s' script, do not edit. */
|
||||
{
|
||||
""" % os.path.basename(__file__))
|
||||
for handler in handlers:
|
||||
output_file.write("\t%s;\n" % handler)
|
||||
output_file.write("};\n")
|
||||
|
||||
def main(args):
|
||||
p = optparse.OptionParser(usage="%prog [-o FILE] XMLFILE")
|
||||
p.add_option("-o", "--output", metavar="FILE", dest="output_file",
|
||||
default="-", help="write the output to this file (default `-' for stdin)")
|
||||
|
||||
opts, args = p.parse_args(args)
|
||||
|
||||
output_file = None
|
||||
try:
|
||||
if opts.output_file == "-":
|
||||
output_file = sys.stdout
|
||||
else:
|
||||
output_file = open(opts.output_file, 'w')
|
||||
|
||||
args = args[1:]
|
||||
if len(args) == 0:
|
||||
p.error("invalid XMLFILE argument, expecting a filename, got none")
|
||||
elif len(args) > 1:
|
||||
p.error("too many XMLFILE arguments, expecting a single filename")
|
||||
|
||||
handlers = find_handlers(args[0], ["gtk_.+"])
|
||||
write_dynamic_list(handlers, output_file)
|
||||
|
||||
finally:
|
||||
if output_file is not None and output_file is not sys.stdout:
|
||||
output_file.close()
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
@ -11,7 +11,7 @@ EXTRA_DIST = \
|
||||
pluginprivate.h \
|
||||
projectprivate.h \
|
||||
makefile.win32 \
|
||||
$(top_srcdir)/src/dynamicsymbols.list
|
||||
$(srcdir)/signalconn.c.in
|
||||
|
||||
bin_PROGRAMS = geany
|
||||
lib_LTLIBRARIES = libgeany.la
|
||||
@ -173,10 +173,20 @@ AM_CFLAGS = -DGEANY_DATADIR=\""$(datadir)"\" \
|
||||
|
||||
clean-local:
|
||||
|
||||
# Helper rule to rebuild the dynamicsymbols.list file when handlers are
|
||||
# added to data/geany.glade. Run `make dynamic-symbols' from the src builddir.
|
||||
$(top_srcdir)/src/dynamicsymbols.list: $(top_srcdir)/data/geany.glade
|
||||
-python $(top_srcdir)/scripts/dynamicsymbols.py -o $@ $(top_srcdir)/data/geany.glade
|
||||
dynamic-symbols: $(top_srcdir)/src/dynamicsymbols.list
|
||||
|
||||
endif
|
||||
|
||||
callbacks.c: signalconn.c
|
||||
|
||||
glade_file=$(top_srcdir)/data/geany.glade
|
||||
template_file=$(srcdir)/signalconn.c.in
|
||||
|
||||
signalconn.c: $(glade_file) $(template_file)
|
||||
$(AM_V_GEN)( \
|
||||
echo '/* This file is auto-generated, do not edit. */' && \
|
||||
$(SED) -n '/@callback_map@/q;p' "$(template_file)" && \
|
||||
$(SED) -n 's/^.*handler="\([^"]\+\)".*$$/\tg_hash_table_insert(hash, "\1", G_CALLBACK(\1));/p' "$(glade_file)" \
|
||||
| $(SORT) | $(UNIQ) && \
|
||||
$(SED) -n '/@callback_map@/{:l;n;p;b l}' "$(template_file)" \
|
||||
) > $@ || { $(RM) $@ && exit 1; }
|
||||
|
||||
CLEANFILES = signalconn.c
|
||||
|
@ -1988,3 +1988,5 @@ GEANY_EXPORT_SYMBOL void on_detect_width_from_file_activate(GtkMenuItem *menuite
|
||||
ui_document_show_hide(doc);
|
||||
}
|
||||
}
|
||||
|
||||
#include "signalconn.c"
|
||||
|
@ -26,6 +26,9 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Defined in auto-generated code in signalconn.c */
|
||||
void callbacks_connect(GtkBuilder *builder);
|
||||
|
||||
extern gboolean ignore_callback;
|
||||
|
||||
void on_new1_activate(GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
@ -1,161 +0,0 @@
|
||||
/* This file was auto-generated by the `dynamicsymbols.py' script, do not edit. */
|
||||
{
|
||||
on_button_customize_toolbar_clicked;
|
||||
on_change_font1_activate;
|
||||
on_clone1_activate;
|
||||
on_close1_activate;
|
||||
on_close_all1_activate;
|
||||
on_close_other_documents1_activate;
|
||||
on_comments_bsd_activate;
|
||||
on_comments_changelog_activate;
|
||||
on_comments_changelog_activate;
|
||||
on_comments_fileheader_activate;
|
||||
on_comments_fileheader_activate;
|
||||
on_comments_function_activate;
|
||||
on_comments_function_activate;
|
||||
on_comments_gpl_activate;
|
||||
on_comments_multiline_activate;
|
||||
on_context_action1_activate;
|
||||
on_copy1_activate;
|
||||
on_copy1_activate;
|
||||
on_copy_current_lines1_activate;
|
||||
on_count_words1_activate;
|
||||
on_cr_activate;
|
||||
on_crlf_activate;
|
||||
on_customize_toolbar1_activate;
|
||||
on_cut1_activate;
|
||||
on_cut1_activate;
|
||||
on_cut_current_lines1_activate;
|
||||
on_debug_messages1_activate;
|
||||
on_delete1_activate;
|
||||
on_delete1_activate;
|
||||
on_delete_current_lines1_activate;
|
||||
on_detect_type_from_file_activate;
|
||||
on_detect_width_from_file_activate;
|
||||
on_duplicate_line_or_selection1_activate;
|
||||
on_edit1_activate;
|
||||
on_escape_key_press_event;
|
||||
on_file1_activate;
|
||||
on_file_properties_activate;
|
||||
on_find1_activate;
|
||||
on_find_document_usage1_activate;
|
||||
on_find_document_usage1_activate;
|
||||
on_find_in_files1_activate;
|
||||
on_find_next1_activate;
|
||||
on_find_nextsel1_activate;
|
||||
on_find_previous1_activate;
|
||||
on_find_prevsel1_activate;
|
||||
on_find_usage1_activate;
|
||||
on_find_usage1_activate;
|
||||
on_fullscreen1_toggled;
|
||||
on_go_to_line_activate;
|
||||
on_go_to_next_marker1_activate;
|
||||
on_go_to_previous_marker1_activate;
|
||||
on_goto_tag_declaration1;
|
||||
on_goto_tag_definition1;
|
||||
on_goto_tag_definition1;
|
||||
on_help1_activate;
|
||||
on_help_menu_item_bug_report_activate;
|
||||
on_help_menu_item_donate_activate;
|
||||
on_help_menu_item_wiki_activate;
|
||||
on_help_shortcuts1_activate;
|
||||
on_hide_toolbar1_activate;
|
||||
on_indent_width_activate;
|
||||
on_indent_width_activate;
|
||||
on_indent_width_activate;
|
||||
on_indent_width_activate;
|
||||
on_indent_width_activate;
|
||||
on_indent_width_activate;
|
||||
on_indent_width_activate;
|
||||
on_indent_width_activate;
|
||||
on_info1_activate;
|
||||
on_insert_alternative_white_space1_activate;
|
||||
on_insert_alternative_white_space1_activate;
|
||||
on_lf_activate;
|
||||
on_line_breaking1_activate;
|
||||
on_line_wrapping1_toggled;
|
||||
on_load_tags1_activate;
|
||||
on_mark_all1_activate;
|
||||
on_markers_margin1_toggled;
|
||||
on_menu_color_schemes_activate;
|
||||
on_menu_comment_line1_activate;
|
||||
on_menu_comments_bsd_activate;
|
||||
on_menu_comments_gpl_activate;
|
||||
on_menu_comments_multiline_activate;
|
||||
on_menu_decrease_indent1_activate;
|
||||
on_menu_fold_all1_activate;
|
||||
on_menu_increase_indent1_activate;
|
||||
on_menu_open_selected_file1_activate;
|
||||
on_menu_open_selected_file1_activate;
|
||||
on_menu_project1_activate;
|
||||
on_menu_reload_configuration1_activate;
|
||||
on_menu_remove_indicators1_activate;
|
||||
on_menu_select_all1_activate;
|
||||
on_menu_select_all1_activate;
|
||||
on_menu_show_indentation_guides1_toggled;
|
||||
on_menu_show_line_endings1_toggled;
|
||||
on_menu_show_sidebar1_toggled;
|
||||
on_menu_show_white_space1_toggled;
|
||||
on_menu_toggle_all_additional_widgets1_activate;
|
||||
on_menu_toggle_line_commentation1_activate;
|
||||
on_menu_uncomment_line1_activate;
|
||||
on_menu_unfold_all1_activate;
|
||||
on_menu_write_unicode_bom1_toggled;
|
||||
on_motion_event;
|
||||
on_move_lines_down1_activate;
|
||||
on_move_lines_up1_activate;
|
||||
on_new1_activate;
|
||||
on_next_message1_activate;
|
||||
on_normal_size1_activate;
|
||||
on_notebook1_switch_page_after;
|
||||
on_open1_activate;
|
||||
on_page_setup1_activate;
|
||||
on_paste1_activate;
|
||||
on_paste1_activate;
|
||||
on_plugin_preferences1_activate;
|
||||
on_preferences1_activate;
|
||||
on_previous_message1_activate;
|
||||
on_print1_activate;
|
||||
on_project_close1_activate;
|
||||
on_project_new1_activate;
|
||||
on_project_open1_activate;
|
||||
on_project_properties1_activate;
|
||||
on_quit1_activate;
|
||||
on_redo1_activate;
|
||||
on_redo1_activate;
|
||||
on_reflow_lines_block1_activate;
|
||||
on_remove_markers1_activate;
|
||||
on_replace1_activate;
|
||||
on_replace_spaces_activate;
|
||||
on_replace_tabs_activate;
|
||||
on_reset_indentation1_activate;
|
||||
on_save1_activate;
|
||||
on_save_all1_activate;
|
||||
on_save_as1_activate;
|
||||
on_search1_activate;
|
||||
on_select_current_lines1_activate;
|
||||
on_select_current_paragraph1_activate;
|
||||
on_send_selection_to_vte1_activate;
|
||||
on_set_file_readonly1_toggled;
|
||||
on_show_color_chooser1_activate;
|
||||
on_show_line_numbers1_toggled;
|
||||
on_show_messages_window1_toggled;
|
||||
on_show_toolbar1_toggled;
|
||||
on_smart_line_indent1_activate;
|
||||
on_spaces1_activate;
|
||||
on_strip_trailing_spaces1_activate;
|
||||
on_tabs1_activate;
|
||||
on_tabs_and_spaces1_activate;
|
||||
on_toggle_case1_activate;
|
||||
on_toolbutton_reload_clicked;
|
||||
on_tv_notebook_switch_page;
|
||||
on_tv_notebook_switch_page_after;
|
||||
on_undo1_activate;
|
||||
on_undo1_activate;
|
||||
on_use_auto_indentation1_toggled;
|
||||
on_website1_activate;
|
||||
on_window_delete_event;
|
||||
on_window_state_event;
|
||||
on_zoom_in1_activate;
|
||||
on_zoom_out1_activate;
|
||||
};
|
32
src/signalconn.c.in
Normal file
32
src/signalconn.c.in
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
static void builder_connect_func(GtkBuilder *builder, GObject *object,
|
||||
const gchar *signal_name, const gchar *handler_name, GObject *connect_obj,
|
||||
GConnectFlags flags, gpointer user_data)
|
||||
{
|
||||
GHashTable *hash = user_data;
|
||||
GCallback callback;
|
||||
|
||||
callback = g_hash_table_lookup(hash, handler_name);
|
||||
g_return_if_fail(callback);
|
||||
|
||||
if (connect_obj == NULL)
|
||||
g_signal_connect_data(object, signal_name, callback, NULL, NULL, flags);
|
||||
else
|
||||
g_signal_connect_object(object, signal_name, callback, connect_obj, flags);
|
||||
}
|
||||
|
||||
|
||||
void callbacks_connect(GtkBuilder *builder)
|
||||
{
|
||||
GHashTable *hash;
|
||||
|
||||
g_return_if_fail(GTK_IS_BUILDER(builder));
|
||||
|
||||
hash = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
|
||||
@callback_map@
|
||||
|
||||
gtk_builder_connect_signals_full(builder, builder_connect_func, hash);
|
||||
g_hash_table_destroy(hash);
|
||||
}
|
@ -2448,7 +2448,7 @@ void ui_init_builder(void)
|
||||
}
|
||||
g_free(interface_file);
|
||||
|
||||
gtk_builder_connect_signals(builder, NULL);
|
||||
callbacks_connect(builder);
|
||||
|
||||
edit_menu1 = GTK_WIDGET(gtk_builder_get_object(builder, "edit_menu1"));
|
||||
prefs_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "prefs_dialog"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user