1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

New front end to PuTTY/pterm, as a GtkApplication.

When it's finished, this will be the backbone of the OS X GTK port:
using a GtkApplication automatically gives us a properly OS X
integrated menu bar.

Using this source file in place of gtkmain.c turns the usual Unix
single-session-per-process PuTTY or pterm into the multi-session-per-
process OS X style one.

Things like Duplicate Session can be done much more simply here - we
just grab the Conf * from the source window and launch a new window
using it, with no fiddly interprocess work needed.

This is still experimental and has a lot of holes, but it's usable
enough to test and improve.
This commit is contained in:
Simon Tatham 2016-03-23 22:22:30 +00:00
parent f23375b14e
commit 19b5a74f71
3 changed files with 183 additions and 0 deletions

2
.gitignore vendored
View File

@ -35,6 +35,8 @@
/puttytel
/puttygen
/pterm
/puttyapp
/ptermapp
/fuzzterm
/testbn
/*.DSA

6
Recipe
View File

@ -322,6 +322,12 @@ pageant : [X] uxpgnt uxagentc pageant sshrsa sshpubk sshdes sshbn sshmd5
PuTTY : [MX] osxmain OSXTERM OSXMISC CHARSET U_BE_ALL NONSSH UXSSH
+ ux_x11 uxpty uxsignal testback putty.icns info.plist
ptermapp : [XT] GTKTERM uxmisc misc ldisc settings uxpty uxsel BE_NONE uxstore
+ uxsignal CHARSET cmdline uxpterm version time xpmpterm xpmptcfg
+ nogss gtkapp
puttyapp : [XT] GTKTERM uxmisc misc ldisc settings uxsel U_BE_ALL uxstore
+ uxsignal CHARSET uxputty NONSSH UXSSH UXMISC ux_x11 xpmputty
+ xpmpucfg gtkapp
fuzzterm : [UT] UXTERM CHARSET misc uxmisc uxucs fuzzterm time settings
+ uxstore be_none
testbn : [UT] testbn sshbn misc conf tree234 uxmisc

175
unix/gtkapp.c Normal file
View File

@ -0,0 +1,175 @@
/*
* gtkapp.c: a top-level front end to GUI PuTTY and pterm, using
* GtkApplication. Suitable for OS X. Currently unfinished.
*
* (You could run it on ordinary Linux GTK too, in principle, but I
* don't think it would be particularly useful to do so, even once
* it's fully working.)
*/
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <gtk/gtk.h>
#define MAY_REFER_TO_GTK_IN_HEADERS
#include "putty.h"
char *x_get_default(const char *key) { return NULL; }
#if !GTK_CHECK_VERSION(3,0,0)
/* This front end only works in GTK 3. If that's not what we've got,
* it's easier to just turn this program into a trivial stub by ifdef
* in the source than it is to remove it in the makefile edifice. */
int main(int argc, char **argv)
{
fprintf(stderr, "launcher does nothing on non-OSX platforms\n");
return 1;
}
GtkWidget *make_gtk_toplevel_window(void *frontend) { return NULL; }
void launch_duplicate_session(Conf *conf) {}
void launch_new_session(void) {}
void launch_saved_session(const char *str) {}
#else /* GTK_CHECK_VERSION(3,0,0) */
static void startup(GApplication *app, gpointer user_data)
{
GMenu *menubar, *menu, *section;
menubar = g_menu_new();
menu = g_menu_new();
g_menu_append_submenu(menubar, "File", G_MENU_MODEL(menu));
section = g_menu_new();
g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
g_menu_append(section, "New Window", "app.newwin");
menu = g_menu_new();
g_menu_append_submenu(menubar, "Edit", G_MENU_MODEL(menu));
section = g_menu_new();
g_menu_append_section(menu, NULL, G_MENU_MODEL(section));
g_menu_append(section, "Paste", "win.paste");
gtk_application_set_menubar(GTK_APPLICATION(app),
G_MENU_MODEL(menubar));
}
static void paste_cb(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
request_paste(user_data);
}
static const GActionEntry win_actions[] = {
{ "paste", paste_cb },
};
static GtkApplication *app;
GtkWidget *make_gtk_toplevel_window(void *frontend)
{
GtkWidget *win = gtk_application_window_new(app);
g_action_map_add_action_entries(G_ACTION_MAP(win),
win_actions,
G_N_ELEMENTS(win_actions),
frontend);
return win;
}
extern int cfgbox(Conf *conf);
void launch_duplicate_session(Conf *conf)
{
assert(conf_launchable(conf));
new_session_window(conf, NULL);
}
void launch_new_session(void)
{
Conf *conf = conf_new();
do_defaults(NULL, conf);
if (conf_launchable(conf) || cfgbox(conf)) {
new_session_window(conf, NULL);
}
}
void launch_saved_session(const char *str)
{
Conf *conf = conf_new();
do_defaults(str, conf);
if (conf_launchable(conf) || cfgbox(conf)) {
new_session_window(conf, NULL);
}
}
void new_app_win(GtkApplication *app)
{
launch_new_session();
}
static void activate(GApplication *app,
gpointer user_data)
{
new_app_win(GTK_APPLICATION(app));
}
static void newwin_cb(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
new_app_win(GTK_APPLICATION(user_data));
}
static void quit_cb(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
g_application_quit(G_APPLICATION(user_data));
}
static const GActionEntry app_actions[] = {
{ "newwin", newwin_cb },
{ "quit", quit_cb },
};
int main(int argc, char **argv)
{
int status;
{
/* Call the function in ux{putty,pterm}.c to do app-type
* specific setup */
extern void setup(int);
setup(FALSE); /* FALSE means we are not a one-session process */
}
{
const char *home = getenv("HOME");
if (home) {
if (chdir(home)) {}
}
}
gtkcomm_setup();
app = gtk_application_new("org.tartarus.projects.putty.macputty",
G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
g_signal_connect(app, "startup", G_CALLBACK(startup), NULL);
g_action_map_add_action_entries(G_ACTION_MAP(app),
app_actions,
G_N_ELEMENTS(app_actions),
app);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
#endif /* GTK_CHECK_VERSION(3,0,0) */