commit 1d07c0f5db9e4339ada457a8c569503ba6005bf6
parent 8daa7c79cf26b723abc221504e1a6fe403790453
Author: Andrej Kacian <ticho@claws-mail.org>
Date: Fri, 9 Feb 2018 21:28:08 +0100
Limit external editor feature to UNIX OS with X11.
It uses GtkSocket, which is only available on X11
with GTK3.
Diffstat:
5 files changed, 81 insertions(+), 38 deletions(-)
diff --git a/src/compose.c b/src/compose.c
@@ -31,6 +31,9 @@
#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
+#include <gtk/gtkx.h>
+#endif
#include <pango/pango-break.h>
#include <stdio.h>
@@ -353,10 +356,10 @@ static gboolean attach_property_key_pressed (GtkWidget *widget,
GdkEventKey *event,
gboolean *cancelled);
+#ifdef CAN_USE_EXTERNAL_EDITOR
static void compose_exec_ext_editor (Compose *compose);
-#ifdef G_OS_UNIX
static gint compose_exec_ext_editor_real (const gchar *file,
- GdkNativeWindow socket_wid);
+ Window socket_wid);
static gboolean compose_ext_editor_kill (Compose *compose);
static gboolean compose_input_cb (GIOChannel *source,
GIOCondition condition,
@@ -368,7 +371,7 @@ static gboolean compose_get_ext_editor_uses_socket();
static gboolean compose_ext_editor_plug_removed_cb
(GtkSocket *socket,
Compose *compose);
-#endif /* G_OS_UNIX */
+#endif /* CAN_USE_EXTERNAL_EDITOR */
static void compose_undo_state_changed (UndoMain *undostruct,
gint undo_state,
@@ -437,8 +440,10 @@ static void about_show_cb (GtkAction *action,
static void compose_template_activate_cb(GtkWidget *widget,
gpointer data);
+#ifdef CAN_USE_EXTERNAL_EDITOR
static void compose_ext_editor_cb (GtkAction *action,
gpointer data);
+#endif /* CAN_USE_EXTERNAL_EDITOR */
static gint compose_delete_cb (GtkWidget *widget,
GdkEventAny *event,
@@ -662,8 +667,12 @@ static GtkActionEntry compose_entries[] =
/* {"Edit/---", NULL, "---", NULL, NULL, NULL }, */
{"Edit/WrapPara", NULL, N_("_Wrap current paragraph"), "<control>L", NULL, G_CALLBACK(compose_wrap_cb) }, /* 0 */
{"Edit/WrapAllLines", NULL, N_("Wrap all long _lines"), "<control><alt>L", NULL, G_CALLBACK(compose_wrap_all_cb) }, /* 1 */
+
+#ifdef CAN_USE_EXTERNAL_EDITOR
/* {"Edit/---", NULL, "---", NULL, NULL, NULL }, */
{"Edit/ExtEditor", NULL, N_("Edit with e_xternal editor"), "<shift><control>X", NULL, G_CALLBACK(compose_ext_editor_cb) },
+#endif /* CAN_USE_EXTERNAL_EDITOR */
+
#if USE_ENCHANT
/* Spelling menu */
{"Spelling/CheckAllSel", NULL, N_("_Check all or check selection"), NULL, NULL, G_CALLBACK(compose_check_all) },
@@ -1246,8 +1255,10 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
undo_unblock(compose->undostruct);
+#ifdef CAN_USE_EXTERNAL_EDITOR
if (prefs_common.auto_exteditor)
compose_exec_ext_editor(compose);
+#endif /* CAN_USE_EXTERNAL_EDITOR */
compose->draft_timeout_tag = COMPOSE_DRAFT_TIMEOUT_UNSET;
@@ -1692,8 +1703,10 @@ static Compose *compose_generic_reply(MsgInfo *msginfo,
undo_unblock(compose->undostruct);
+#ifdef CAN_USE_EXTERNAL_EDITOR
if (prefs_common.auto_exteditor)
compose_exec_ext_editor(compose);
+#endif /* CAN_USE_EXTERNAL_EDITOR */
compose->modified = FALSE;
compose_set_title(compose);
@@ -1882,8 +1895,10 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
else
gtk_widget_grab_focus(compose->text);
+#ifdef CAN_USE_EXTERNAL_EDITOR
if (!no_extedit && prefs_common.auto_exteditor)
compose_exec_ext_editor(compose);
+#endif /* CAN_USE_EXTERNAL_EDITOR */
/*save folder*/
if (msginfo->folder && msginfo->folder->prefs && msginfo->folder->prefs->save_copy_to_folder) {
@@ -2043,8 +2058,10 @@ static Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_
gtk_text_buffer_get_start_iter(textbuf, &iter);
gtk_text_buffer_place_cursor(textbuf, &iter);
+#ifdef CAN_USE_EXTERNAL_EDITOR
if (prefs_common.auto_exteditor)
compose_exec_ext_editor(compose);
+#endif /* CAN_USE_EXTERNAL_EDITOR */
gtk_widget_grab_focus(compose->header_last->entry);
undo_unblock(compose->undostruct);
@@ -2452,9 +2469,12 @@ Compose *compose_reedit(MsgInfo *msginfo, gboolean batch)
gtk_widget_grab_focus(compose->text);
- if (prefs_common.auto_exteditor) {
+#ifdef CAN_USE_EXTERNAL_EDITOR
+ if (prefs_common.auto_exteditor) {
compose_exec_ext_editor(compose);
}
+#endif /* CAN_USE_EXTERNAL_EDITOR */
+
compose->modified = FALSE;
compose_set_title(compose);
@@ -7810,9 +7830,10 @@ static Compose *compose_create(PrefsAccount *account,
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "AutoWrap", "Edit/AutoWrap", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "AutoIndent", "Edit/AutoIndent", GTK_UI_MANAGER_MENUITEM)
+#ifdef CAN_USE_EXTERNAL_EDITOR
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "Separator3", "Edit/---", GTK_UI_MANAGER_SEPARATOR)
-
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "ExtEditor", "Edit/ExtEditor", GTK_UI_MANAGER_MENUITEM)
+#endif /* CAN_USE_EXTERNAL_EDITOR */
#if USE_ENCHANT
/* Spelling menu */
@@ -9517,12 +9538,20 @@ static gboolean attach_property_key_pressed(GtkWidget *widget,
return FALSE;
}
+static gboolean compose_can_autosave(Compose *compose)
+{
+ if (compose->privacy_system && compose->use_encryption)
+ return prefs_common.autosave && prefs_common.autosave_encrypted;
+ else
+ return prefs_common.autosave;
+}
+
+#ifdef CAN_USE_EXTERNAL_EDITOR
static void compose_exec_ext_editor(Compose *compose)
{
-#ifdef G_OS_UNIX
gchar *tmp;
GtkWidget *socket;
- GdkNativeWindow socket_wid = 0;
+ Window socket_wid = 0;
pid_t pid;
gint pipe_fds[2];
@@ -9541,7 +9570,7 @@ static void compose_exec_ext_editor(Compose *compose)
}
/* Create the receiving GtkSocket */
socket = gtk_socket_new ();
- g_signal_connect (GTK_OBJECT(socket), "plug-removed",
+ g_signal_connect (G_OBJECT(socket), "plug-removed",
G_CALLBACK(compose_ext_editor_plug_removed_cb),
compose);
gtk_box_pack_start(GTK_BOX(compose->edit_vbox), socket, TRUE, TRUE, 0);
@@ -9573,11 +9602,7 @@ static void compose_exec_ext_editor(Compose *compose)
compose_set_ext_editor_sensitive(compose, FALSE);
-#ifndef G_OS_WIN32
compose->exteditor_ch = g_io_channel_unix_new(pipe_fds[0]);
-#else
- compose->exteditor_ch = g_io_channel_win32_new_fd(pipe_fds[0]);
-#endif
compose->exteditor_tag = g_io_add_watch(compose->exteditor_ch,
G_IO_IN,
compose_input_cb,
@@ -9612,18 +9637,8 @@ static void compose_exec_ext_editor(Compose *compose)
}
g_free(tmp);
-#endif /* G_OS_UNIX */
-}
-
-static gboolean compose_can_autosave(Compose *compose)
-{
- if (compose->privacy_system && compose->use_encryption)
- return prefs_common.autosave && prefs_common.autosave_encrypted;
- else
- return prefs_common.autosave;
}
-#ifdef G_OS_UNIX
static gboolean compose_get_ext_editor_cmd_valid()
{
gboolean has_s = FALSE;
@@ -9648,7 +9663,7 @@ static gboolean compose_get_ext_editor_cmd_valid()
return TRUE;
}
-static gint compose_exec_ext_editor_real(const gchar *file, GdkNativeWindow socket_wid)
+static gint compose_exec_ext_editor_real(const gchar *file, Window socket_wid)
{
gchar *buf;
gchar *p, *s;
@@ -9896,7 +9911,7 @@ static gboolean compose_ext_editor_plug_removed_cb(GtkSocket *socket, Compose *c
/* returning FALSE allows destruction of the socket */
return FALSE;
}
-#endif /* G_OS_UNIX */
+#endif /* CAN_USE_EXTERNAL_EDITOR */
/**
* compose_undo_state_changed:
@@ -10171,7 +10186,7 @@ static void compose_send_cb(GtkAction *action, gpointer data)
{
Compose *compose = (Compose *)data;
-#ifdef G_OS_UNIX
+#ifdef CAN_USE_EXTERNAL_EDITOR
if (compose->exteditor_tag != -1) {
debug_print("ignoring send: external editor still open\n");
return;
@@ -10673,12 +10688,12 @@ static void compose_close_cb(GtkAction *action, gpointer data)
Compose *compose = (Compose *)data;
AlertValue val;
-#ifdef G_OS_UNIX
+#ifdef CAN_USE_EXTERNAL_EDITOR
if (compose->exteditor_tag != -1) {
if (!compose_ext_editor_kill(compose))
return;
}
-#endif
+#endif /* CAN_USE_EXTERNAL_EDITOR */
if (compose->modified) {
gboolean reedit = (compose->rmode == COMPOSE_REEDIT);
@@ -10781,17 +10796,17 @@ static void compose_template_activate_cb(GtkWidget *widget, gpointer data)
compose_template_apply(compose, tmpl, FALSE);
}
+#ifdef CAN_USE_EXTERNAL_EDITOR
static void compose_ext_editor_cb(GtkAction *action, gpointer data)
{
Compose *compose = (Compose *)data;
-#ifdef G_OS_UNIX
if (compose->exteditor_tag != -1) {
debug_print("ignoring open external editor: external editor still open\n");
return;
}
-#endif
compose_exec_ext_editor(compose);
+#endif /* CAN_USE_EXTERNAL_EDITOR */
}
static void compose_undo_cb(GtkAction *action, gpointer data)
diff --git a/src/compose.h b/src/compose.h
@@ -43,6 +43,12 @@ typedef struct _AttachInfo AttachInfo;
#define COMPOSE_CHECK_BEFORE_SEND_HOOKLIST "compose_check_before_send"
#define COMPOSE_CREATED_HOOKLIST "compose_created"
+/* Define a convenient macro for further ifdefs around code related to
+ * external editor. */
+#if defined G_OS_UNIX && defined GDK_WINDOWING_X11
+# define CAN_USE_EXTERNAL_EDITOR
+#endif
+
typedef enum
{
COMPOSE_TO,
diff --git a/src/prefs_common.c b/src/prefs_common.c
@@ -1660,6 +1660,7 @@ const gchar *prefs_common_get_uri_cmd(void)
#endif
}
+#ifdef CAN_USE_EXTERNAL_EDITOR
const gchar *prefs_common_get_ext_editor_cmd(void)
{
return prefs_common.ext_editor_cmd;
@@ -1676,8 +1677,9 @@ const gchar *prefs_common_get_ext_editor_cmd(void)
g_free(tmp);
return "xdg-open %s";
-#endif
+#endif /* 0 */
}
+#endif /* CAN_USE_EXTERNAL_EDITOR */
gboolean prefs_common_get_use_shred(void)
{
diff --git a/src/prefs_compose_writing.c b/src/prefs_compose_writing.c
@@ -52,7 +52,9 @@ typedef struct _WritingPage
GtkWidget *window;
+#ifdef CAN_USE_EXTERNAL_EDITOR
GtkWidget *checkbtn_autoextedit;
+#endif /* CAN_USE_EXTERNAL_EDITOR */
GtkWidget *checkbtn_reply_account_autosel;
GtkWidget *checkbtn_forward_account_autosel;
GtkWidget *checkbtn_reedit_account_autosel;
@@ -77,7 +79,9 @@ static void prefs_compose_writing_create_widget(PrefsPage *_page, GtkWindow *win
GtkWidget *vbox1;
GtkWidget *vbox2;
+#ifdef CAN_USE_EXTERNAL_EDITOR
GtkWidget *checkbtn_autoextedit;
+#endif /* CAN_USE_EXTERNAL_EDITOR */
GtkWidget *frame;
GtkWidget *hbox_autosel;
@@ -140,9 +144,11 @@ static void prefs_compose_writing_create_widget(PrefsPage *_page, GtkWindow *win
/* Editing */
vbox2 = gtkut_get_options_frame(vbox1, &frame, _("Editing"));
+#ifdef CAN_USE_EXTERNAL_EDITOR
/* Editing: automatically start the text editor */
PACK_CHECK_BUTTON (vbox2, checkbtn_autoextedit,
_("Automatically launch the external editor"));
+#endif /* CAN_USE_EXTERNAL_EDITOR */
/* Editing: automatically save draft */
hbox_autosave = gtk_hbox_new (FALSE, 8);
@@ -258,8 +264,9 @@ static void prefs_compose_writing_create_widget(PrefsPage *_page, GtkWindow *win
SET_TOGGLE_SENSITIVITY (checkbtn_warn_large_insert, spinbtn_warn_large_insert_size);
SET_TOGGLE_SENSITIVITY (checkbtn_warn_large_insert, label_warn_large_insert_size);
-
+#ifdef CAN_USE_EXTERNAL_EDITOR
prefs_writing->checkbtn_autoextedit = checkbtn_autoextedit;
+#endif /* CAN_USE_EXTERNAL_EDITOR */
prefs_writing->checkbtn_reply_account_autosel = checkbtn_reply_account_autosel;
prefs_writing->checkbtn_forward_account_autosel = checkbtn_forward_account_autosel;
@@ -283,9 +290,10 @@ static void prefs_compose_writing_create_widget(PrefsPage *_page, GtkWindow *win
prefs_writing->optmenu_dnd_insert_or_attach = optmenu_dnd_insert_or_attach;
-
+#ifdef CAN_USE_EXTERNAL_EDITOR
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_autoextedit),
prefs_common.auto_exteditor);
+#endif /* CAN_USE_EXTERNAL_EDITOR */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_forward_as_attachment),
prefs_common.forward_as_attachment);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_redirect_keep_from),
@@ -322,8 +330,10 @@ static void prefs_compose_writing_save(PrefsPage *_page)
{
WritingPage *page = (WritingPage *) _page;
+#ifdef CAN_USE_EXTERNAL_EDITOR
prefs_common.auto_exteditor =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_autoextedit));
+#endif /* CAN_USE_EXTERNAL_EDITOR */
prefs_common.forward_as_attachment =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_forward_as_attachment));
prefs_common.redirect_keep_from =
diff --git a/src/prefs_ext_prog.c b/src/prefs_ext_prog.c
@@ -53,11 +53,13 @@ typedef struct _ExtProgPage
GtkWidget *uri_label;
GtkWidget *uri_combo;
GtkWidget *uri_entry;
-
-#endif
+#endif /* !G_OS_WIN32 */
+
GtkWidget *exteditor_label;
+#ifdef CAN_USE_EXTERNAL_EDITOR
GtkWidget *exteditor_combo;
GtkWidget *exteditor_entry;
+#endif /* CAN_USE_EXTERNAL_EDITOR */
GtkWidget *astextviewer_label;
GtkWidget *astextviewer_entry;
@@ -77,10 +79,14 @@ static void prefs_ext_prog_create_widget(PrefsPage *_page, GtkWindow *window,
GtkWidget *uri_label;
GtkWidget *uri_combo;
GtkWidget *uri_entry;
-#endif
+#endif /* !G_OS_WIN32 */
+
+#ifdef CAN_USE_EXTERNAL_EDITOR
GtkWidget *exteditor_label;
GtkWidget *exteditor_combo;
GtkWidget *exteditor_entry;
+#endif /* CAN_USE_EXTERNAL_EDITOR */
+
GtkWidget *astextviewer_label;
GtkWidget *astextviewer_entry;
int i = 0;
@@ -174,7 +180,9 @@ static void prefs_ext_prog_create_widget(PrefsPage *_page, GtkWindow *window,
uri_entry = gtk_bin_get_child(GTK_BIN((uri_combo)));
gtk_entry_set_text(GTK_ENTRY(uri_entry), prefs_common.uri_cmd ? prefs_common.uri_cmd : "");
-#endif
+#endif /* !G_OS_WIN32 */
+
+#ifdef CAN_USE_EXTERNAL_EDITOR
exteditor_label = gtk_label_new (_("Text editor"));
gtk_widget_show(exteditor_label);
@@ -206,6 +214,7 @@ static void prefs_ext_prog_create_widget(PrefsPage *_page, GtkWindow *window,
exteditor_entry = gtk_bin_get_child(GTK_BIN((exteditor_combo)));
gtk_entry_set_text(GTK_ENTRY(exteditor_entry),
prefs_common.ext_editor_cmd ? prefs_common.ext_editor_cmd : "");
+#endif /* CAN_USE_EXTERNAL_EDITOR */
astextviewer_label = gtk_label_new(_("Command for 'Display as text'"));
gtk_widget_show(astextviewer_label);
@@ -233,7 +242,8 @@ static void prefs_ext_prog_create_widget(PrefsPage *_page, GtkWindow *window,
#ifndef G_OS_WIN32
SET_TOGGLE_SENSITIVITY_REVERSE (cmds_use_system_default_checkbtn, uri_label);
SET_TOGGLE_SENSITIVITY_REVERSE (cmds_use_system_default_checkbtn, uri_combo);
-#endif
+#endif /* !G_OS_WIN32 */
+
#if 0 /* we should do that, but it detaches the editor and breaks
compose.c's external composition. */
SET_TOGGLE_SENSITIVITY_REVERSE (cmds_use_system_default_checkbtn, exteditor_label);
@@ -257,7 +267,7 @@ static void prefs_ext_prog_save(PrefsPage *_page)
#ifndef G_OS_WIN32
prefs_common.uri_cmd = gtk_editable_get_chars
(GTK_EDITABLE(ext_prog->uri_entry), 0, -1);
-#endif
+#endif /* !G_OS_WIN32 */
prefs_common.ext_editor_cmd = gtk_editable_get_chars
(GTK_EDITABLE(ext_prog->exteditor_entry), 0, -1);
prefs_common.mime_textviewer = gtk_editable_get_chars