mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +00:00
Stop using GtkDialog (for most purposes) in GTK 3!
They've now deprecated gtk_dialog_get_action_area, because they really want a dialog box's action area to be filled with nothing but buttons controlled by GTK which end the dialog with a response code. But we're accustomed to putting all sorts of other things in our action area - non-buttons, buttons that don't end the dialog, and sub-widgets that do layout - and so I think it's no longer sensible to be trying to coerce our use cases into GtkDialog. Hence, I'm introducing a set of wrapper functions which equivocate between a GtkDialog for GTK1 and GTK2, and a GtkWindow with a vbox in it for GTK3, and I'll lay out the action area by hand. (Not everything has sensible layout and margins in the new GTK3 system yet, but I can sort that out later.) Because the new functions are needed by gtkask.c, which doesn't link against gtkdlg.c or include putty.h, I've put them in a new source file and header file pair gtkmisc.[ch] which is common to gtkask and the main GTK edifice.
This commit is contained in:
parent
749b0fdda0
commit
dc11417aee
4
Recipe
4
Recipe
@ -207,7 +207,7 @@ GUITERM = TERMINAL window windlg winctrls sizetip winucs winprint
|
||||
|
||||
# Same thing on Unix.
|
||||
UXTERM = TERMINAL uxcfg sercfg uxucs uxprint timing callback miscucs
|
||||
GTKTERM = UXTERM gtkwin gtkcfg gtkdlg gtkfont gtkcols xkeysym
|
||||
GTKTERM = UXTERM gtkwin gtkcfg gtkdlg gtkfont gtkcols gtkmisc xkeysym
|
||||
OSXTERM = UXTERM osxwin osxdlg osxctrls
|
||||
|
||||
# Non-SSH back ends (putty, puttytel, plink).
|
||||
@ -306,7 +306,7 @@ psftp : [U] psftp uxsftp uxcons UXSSH BE_SSH SFTP wildcard UXMISC
|
||||
pageant : [X] uxpgnt uxagentc pageant sshrsa sshpubk sshdes sshbn sshmd5
|
||||
+ version tree234 misc sshaes sshsha sshdss sshsh256 sshsh512 sshecc
|
||||
+ conf uxsignal nocproxy nogss be_none x11fwd ux_x11 uxcons gtkask
|
||||
+ UXMISC
|
||||
+ gtkmisc UXMISC
|
||||
|
||||
PuTTY : [MX] osxmain OSXTERM OSXMISC CHARSET U_BE_ALL NONSSH UXSSH
|
||||
+ ux_x11 uxpty uxsignal testback putty.icns info.plist
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "gtkfont.h"
|
||||
#include "gtkcompat.h"
|
||||
#include "gtkmisc.h"
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
@ -289,6 +290,7 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
|
||||
const char *prompt_text)
|
||||
{
|
||||
int i;
|
||||
GtkBox *action_area;
|
||||
|
||||
ctx->passlen = 0;
|
||||
ctx->passsize = 2048;
|
||||
@ -297,13 +299,13 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
|
||||
/*
|
||||
* Create widgets.
|
||||
*/
|
||||
ctx->dialog = gtk_dialog_new();
|
||||
ctx->dialog = our_dialog_new();
|
||||
gtk_window_set_title(GTK_WINDOW(ctx->dialog), window_title);
|
||||
gtk_window_set_position(GTK_WINDOW(ctx->dialog), GTK_WIN_POS_CENTER);
|
||||
ctx->promptlabel = gtk_label_new(prompt_text);
|
||||
gtk_label_set_line_wrap(GTK_LABEL(ctx->promptlabel), TRUE);
|
||||
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area
|
||||
(GTK_DIALOG(ctx->dialog))),
|
||||
ctx->promptlabel);
|
||||
our_dialog_add_to_content_area(GTK_WINDOW(ctx->dialog),
|
||||
ctx->promptlabel, TRUE, TRUE, 0);
|
||||
#if GTK_CHECK_VERSION(2,0,0)
|
||||
ctx->imc = gtk_im_multicontext_new();
|
||||
#endif
|
||||
@ -319,6 +321,9 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
|
||||
return "unable to allocate colours";
|
||||
}
|
||||
#endif
|
||||
|
||||
action_area = our_dialog_make_action_hbox(GTK_WINDOW(ctx->dialog));
|
||||
|
||||
for (i = 0; i < N_DRAWING_AREAS; i++) {
|
||||
ctx->drawingareas[i].area = gtk_drawing_area_new();
|
||||
#ifndef DRAW_DEFAULT_CAIRO
|
||||
@ -330,9 +335,8 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
|
||||
* context-sensitive way, like measuring the size of some
|
||||
* piece of template text. */
|
||||
gtk_widget_set_size_request(ctx->drawingareas[i].area, 32, 32);
|
||||
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_action_area
|
||||
(GTK_DIALOG(ctx->dialog))),
|
||||
ctx->drawingareas[i].area);
|
||||
gtk_box_pack_end(action_area, ctx->drawingareas[i].area,
|
||||
TRUE, TRUE, 5);
|
||||
g_signal_connect(G_OBJECT(ctx->drawingareas[i].area),
|
||||
"configure_event",
|
||||
G_CALLBACK(configure_area),
|
||||
|
127
unix/gtkdlg.c
127
unix/gtkdlg.c
@ -12,10 +12,13 @@
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#endif
|
||||
|
||||
#define MAY_REFER_TO_GTK_IN_HEADERS
|
||||
|
||||
#include "putty.h"
|
||||
#include "gtkcompat.h"
|
||||
#include "gtkcols.h"
|
||||
#include "gtkfont.h"
|
||||
#include "gtkmisc.h"
|
||||
|
||||
#ifndef NOT_X_WINDOWS
|
||||
#include <gdk/gdkx.h>
|
||||
@ -2930,84 +2933,6 @@ int get_listitemheight(GtkWidget *w)
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_dialog_action_area(GtkDialog *dlg, GtkWidget *w)
|
||||
{
|
||||
#if !GTK_CHECK_VERSION(2,0,0)
|
||||
|
||||
/*
|
||||
* In GTK 1, laying out the buttons at the bottom of the
|
||||
* configuration box is nice and easy, because a GtkDialog's
|
||||
* action_area is a GtkHBox which stretches to cover the full
|
||||
* width of the dialog. So we just put our Columns widget
|
||||
* straight into that hbox, and it ends up just where we want
|
||||
* it.
|
||||
*/
|
||||
gtk_box_pack_start(GTK_BOX(dlg->action_area), w, TRUE, TRUE, 0);
|
||||
|
||||
#else
|
||||
/*
|
||||
* In GTK 2, the action area is now a GtkHButtonBox and its
|
||||
* layout behaviour seems to be different: it doesn't stretch
|
||||
* to cover the full width of the window, but instead finds its
|
||||
* own preferred width and right-aligns that within the window.
|
||||
* This isn't what we want, because we have both left-aligned
|
||||
* and right-aligned buttons coming out of the above call to
|
||||
* layout_ctrls(), and right-aligning the whole thing will
|
||||
* result in the former being centred and looking weird.
|
||||
*
|
||||
* So instead we abandon the dialog's action area completely:
|
||||
* we gtk_widget_hide() it in the below code, and we also call
|
||||
* gtk_dialog_set_has_separator() to remove the separator above
|
||||
* it. We then insert our own action area into the end of the
|
||||
* dialog's main vbox, and add our own separator above that.
|
||||
*
|
||||
* (Ideally, if we were a native GTK app, we would use the
|
||||
* GtkHButtonBox's _own_ innate ability to support one set of
|
||||
* buttons being right-aligned and one left-aligned. But to do
|
||||
* that here, we would have to either (a) pick apart our cross-
|
||||
* platform layout structures and treat them specially for this
|
||||
* particular set of controls, which would be painful, or else
|
||||
* (b) develop a special and simpler cross-platform
|
||||
* representation for these particular controls, and introduce
|
||||
* special-case code into all the _other_ platforms to handle
|
||||
* it. Neither appeals. Therefore, I regretfully discard the
|
||||
* GTKHButtonBox and go it alone.)
|
||||
*/
|
||||
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(dlg)),
|
||||
w, FALSE, TRUE, 0);
|
||||
#else
|
||||
GtkWidget *align;
|
||||
align = gtk_alignment_new(0, 0, 1, 1);
|
||||
gtk_container_add(GTK_CONTAINER(align), w);
|
||||
/*
|
||||
* The purpose of this GtkAlignment is to provide padding
|
||||
* around the buttons. The padding we use is twice the padding
|
||||
* used in our GtkColumns, because we nest two GtkColumns most
|
||||
* of the time (one separating the tree view from the main
|
||||
* controls, and another for the main controls themselves).
|
||||
*/
|
||||
#if GTK_CHECK_VERSION(2,4,0)
|
||||
gtk_alignment_set_padding(GTK_ALIGNMENT(align), 8, 8, 8, 8);
|
||||
#endif
|
||||
gtk_widget_show(align);
|
||||
gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(dlg)),
|
||||
align, FALSE, TRUE, 0);
|
||||
#endif
|
||||
|
||||
w = gtk_hseparator_new();
|
||||
gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(dlg)),
|
||||
w, FALSE, TRUE, 0);
|
||||
gtk_widget_show(w);
|
||||
gtk_widget_hide(gtk_dialog_get_action_area(dlg));
|
||||
#if !GTK_CHECK_VERSION(3,0,0)
|
||||
/* This cosmetic property is withdrawn in GTK 3's GtkDialog */
|
||||
g_object_set(G_OBJECT(dlg), "has-separator", TRUE, (const char *)NULL);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if GTK_CHECK_VERSION(2,0,0)
|
||||
void initial_treeview_collapse(struct dlgparam *dp, GtkWidget *tree)
|
||||
{
|
||||
@ -3064,7 +2989,7 @@ int do_config_box(const char *title, Conf *conf, int midsession,
|
||||
scs.sc[index].action = SHORTCUT_EMPTY;
|
||||
}
|
||||
|
||||
window = gtk_dialog_new();
|
||||
window = our_dialog_new();
|
||||
|
||||
ctrlbox = ctrl_new_box();
|
||||
protocol = conf_get_int(conf, CONF_protocol);
|
||||
@ -3074,9 +2999,7 @@ int do_config_box(const char *title, Conf *conf, int midsession,
|
||||
|
||||
gtk_window_set_title(GTK_WINDOW(window), title);
|
||||
hbox = gtk_hbox_new(FALSE, 4);
|
||||
gtk_box_pack_start
|
||||
(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))),
|
||||
hbox, TRUE, TRUE, 0);
|
||||
our_dialog_add_to_content_area(GTK_WINDOW(window), hbox, TRUE, TRUE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);
|
||||
gtk_widget_show(hbox);
|
||||
vbox = gtk_vbox_new(FALSE, 4);
|
||||
@ -3130,7 +3053,7 @@ int do_config_box(const char *title, Conf *conf, int midsession,
|
||||
if (!*s->pathname) {
|
||||
w = layout_ctrls(&dp, &scs, s, GTK_WINDOW(window));
|
||||
|
||||
set_dialog_action_area(GTK_DIALOG(window), w);
|
||||
our_dialog_set_action_area(GTK_WINDOW(window), w);
|
||||
} else {
|
||||
int j = path ? ctrl_path_compare(s->pathname, path) : 0;
|
||||
if (j != INT_MAX) { /* add to treeview, start new panel */
|
||||
@ -3451,17 +3374,15 @@ int messagebox(GtkWidget *parentwin, const char *title, const char *msg,
|
||||
s1 = ctrl_getset(ctrlbox, "x", "", "");
|
||||
ctrl_text(s1, msg, HELPCTX(no_help));
|
||||
|
||||
window = gtk_dialog_new();
|
||||
window = our_dialog_new();
|
||||
gtk_window_set_title(GTK_WINDOW(window), title);
|
||||
w0 = layout_ctrls(&dp, &scs, s0, GTK_WINDOW(window));
|
||||
set_dialog_action_area(GTK_DIALOG(window), w0);
|
||||
our_dialog_set_action_area(GTK_WINDOW(window), w0);
|
||||
gtk_widget_show(w0);
|
||||
w1 = layout_ctrls(&dp, &scs, s1, GTK_WINDOW(window));
|
||||
gtk_container_set_border_width(GTK_CONTAINER(w1), 10);
|
||||
gtk_widget_set_size_request(w1, minwid+20, -1);
|
||||
gtk_box_pack_start
|
||||
(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))),
|
||||
w1, TRUE, TRUE, 0);
|
||||
our_dialog_add_to_content_area(GTK_WINDOW(window), w1, TRUE, TRUE, 0);
|
||||
gtk_widget_show(w1);
|
||||
|
||||
dp.shortcuts = &scs;
|
||||
@ -3701,6 +3622,7 @@ static void licence_clicked(GtkButton *button, gpointer data)
|
||||
void about_box(void *window)
|
||||
{
|
||||
GtkWidget *w;
|
||||
GtkBox *action_area;
|
||||
char *title;
|
||||
|
||||
if (aboutbox) {
|
||||
@ -3708,7 +3630,7 @@ void about_box(void *window)
|
||||
return;
|
||||
}
|
||||
|
||||
aboutbox = gtk_dialog_new();
|
||||
aboutbox = our_dialog_new();
|
||||
gtk_container_set_border_width(GTK_CONTAINER(aboutbox), 10);
|
||||
title = dupcat("About ", appname, NULL);
|
||||
gtk_window_set_title(GTK_WINDOW(aboutbox), title);
|
||||
@ -3717,36 +3639,29 @@ void about_box(void *window)
|
||||
w = gtk_button_new_with_label("Close");
|
||||
gtk_widget_set_can_default(w, TRUE);
|
||||
gtk_window_set_default(GTK_WINDOW(aboutbox), w);
|
||||
gtk_box_pack_end(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(aboutbox))),
|
||||
w, FALSE, FALSE, 0);
|
||||
action_area = our_dialog_make_action_hbox(GTK_WINDOW(aboutbox));
|
||||
gtk_box_pack_end(action_area, w, FALSE, FALSE, 0);
|
||||
g_signal_connect(G_OBJECT(w), "clicked",
|
||||
G_CALLBACK(about_close_clicked), NULL);
|
||||
gtk_widget_show(w);
|
||||
|
||||
w = gtk_button_new_with_label("View Licence");
|
||||
gtk_widget_set_can_default(w, TRUE);
|
||||
gtk_box_pack_end(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(aboutbox))),
|
||||
w, FALSE, FALSE, 0);
|
||||
gtk_box_pack_end(action_area, w, FALSE, FALSE, 0);
|
||||
g_signal_connect(G_OBJECT(w), "clicked",
|
||||
G_CALLBACK(licence_clicked), NULL);
|
||||
gtk_widget_show(w);
|
||||
|
||||
w = gtk_label_new(appname);
|
||||
gtk_box_pack_start
|
||||
(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(aboutbox))),
|
||||
w, FALSE, FALSE, 0);
|
||||
our_dialog_add_to_content_area(GTK_WINDOW(aboutbox), w, FALSE, FALSE, 0);
|
||||
gtk_widget_show(w);
|
||||
|
||||
w = gtk_label_new(ver);
|
||||
gtk_box_pack_start
|
||||
(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(aboutbox))),
|
||||
w, FALSE, FALSE, 5);
|
||||
our_dialog_add_to_content_area(GTK_WINDOW(aboutbox), w, FALSE, FALSE, 5);
|
||||
gtk_widget_show(w);
|
||||
|
||||
w = gtk_label_new("Copyright 1997-2015 Simon Tatham. All rights reserved");
|
||||
gtk_box_pack_start
|
||||
(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(aboutbox))),
|
||||
w, FALSE, FALSE, 5);
|
||||
our_dialog_add_to_content_area(GTK_WINDOW(aboutbox), w, FALSE, FALSE, 5);
|
||||
gtk_widget_show(w);
|
||||
|
||||
set_transient_window_pos(GTK_WIDGET(window), aboutbox);
|
||||
@ -3922,12 +3837,12 @@ void showeventlog(void *estuff, void *parentwin)
|
||||
c->listbox.percentages[1] = 10;
|
||||
c->listbox.percentages[2] = 65;
|
||||
|
||||
es->window = window = gtk_dialog_new();
|
||||
es->window = window = our_dialog_new();
|
||||
title = dupcat(appname, " Event Log", NULL);
|
||||
gtk_window_set_title(GTK_WINDOW(window), title);
|
||||
sfree(title);
|
||||
w0 = layout_ctrls(&es->dp, &es->scs, s0, GTK_WINDOW(window));
|
||||
set_dialog_action_area(GTK_DIALOG(window), w0);
|
||||
our_dialog_set_action_area(GTK_WINDOW(window), w0);
|
||||
gtk_widget_show(w0);
|
||||
w1 = layout_ctrls(&es->dp, &es->scs, s1, GTK_WINDOW(window));
|
||||
gtk_container_set_border_width(GTK_CONTAINER(w1), 10);
|
||||
@ -3935,9 +3850,7 @@ void showeventlog(void *estuff, void *parentwin)
|
||||
("LINE OF TEXT GIVING WIDTH OF EVENT LOG IS "
|
||||
"QUITE LONG 'COS SSH LOG ENTRIES ARE WIDE"),
|
||||
-1);
|
||||
gtk_box_pack_start
|
||||
(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))),
|
||||
w1, TRUE, TRUE, 0);
|
||||
our_dialog_add_to_content_area(GTK_WINDOW(window), w1, TRUE, TRUE, 0);
|
||||
gtk_widget_show(w1);
|
||||
|
||||
es->dp.data = es;
|
||||
|
145
unix/gtkmisc.c
Normal file
145
unix/gtkmisc.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Miscellaneous GTK helper functions.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#if !GTK_CHECK_VERSION(3,0,0)
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#endif
|
||||
|
||||
#include "putty.h"
|
||||
#include "gtkcompat.h"
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Functions to arrange controls in a basically dialog-like window.
|
||||
*
|
||||
* The best method for doing this has varied wildly with versions of
|
||||
* GTK, hence the set of wrapper functions here.
|
||||
*
|
||||
* In GTK 1, a GtkDialog has an 'action_area' at the bottom, which is
|
||||
* a GtkHBox which stretches to cover the full width of the dialog. So
|
||||
* we can either add buttons or other widgets to that box directly, or
|
||||
* alternatively we can fill the hbox with some layout class of our
|
||||
* own such as a Columns widget.
|
||||
*
|
||||
* In GTK 2, the action area has become a GtkHButtonBox, and its
|
||||
* layout behaviour seems to be different and not what we want. So
|
||||
* instead we abandon the dialog's action area completely: we
|
||||
* gtk_widget_hide() it in the below code, and we also call
|
||||
* gtk_dialog_set_has_separator() to remove the separator above it. We
|
||||
* then insert our own action area into the end of the dialog's main
|
||||
* vbox, and add our own separator above that.
|
||||
*
|
||||
* In GTK 3, we typically don't even want to use GtkDialog at all,
|
||||
* because GTK 3 has become a lot more restrictive about what you can
|
||||
* sensibly use GtkDialog for - it deprecates direct access to the
|
||||
* action area in favour of making you provide nothing but
|
||||
* dialog-ending buttons in the form of (text, response code) pairs,
|
||||
* so you can't put any other kind of control in there, or fiddle with
|
||||
* alignment and positioning, or even have a button that _doesn't_ end
|
||||
* the dialog (e.g. 'View Licence' in our About box). So instead of
|
||||
* GtkDialog, we use a straight-up GtkWindow and have it contain a
|
||||
* vbox as its (unique) child widget; and we implement the action area
|
||||
* by adding a separator and another widget at the bottom of that
|
||||
* vbox.
|
||||
*/
|
||||
|
||||
GtkWidget *our_dialog_new(void)
|
||||
{
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
/*
|
||||
* See comment in our_dialog_set_action_area(): in GTK 3, we use
|
||||
* GtkWindow in place of GtkDialog for most purposes.
|
||||
*/
|
||||
GtkWidget *w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
|
||||
gtk_container_add(GTK_CONTAINER(w), vbox);
|
||||
gtk_widget_show(vbox);
|
||||
return w;
|
||||
#else
|
||||
return gtk_dialog_new();
|
||||
#endif
|
||||
}
|
||||
|
||||
void our_dialog_set_action_area(GtkWindow *dlg, GtkWidget *w)
|
||||
{
|
||||
#if !GTK_CHECK_VERSION(2,0,0)
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area),
|
||||
w, TRUE, TRUE, 0);
|
||||
|
||||
#elif !GTK_CHECK_VERSION(3,0,0)
|
||||
|
||||
GtkWidget *align;
|
||||
align = gtk_alignment_new(0, 0, 1, 1);
|
||||
gtk_container_add(GTK_CONTAINER(align), w);
|
||||
/*
|
||||
* The purpose of this GtkAlignment is to provide padding
|
||||
* around the buttons. The padding we use is twice the padding
|
||||
* used in our GtkColumns, because we nest two GtkColumns most
|
||||
* of the time (one separating the tree view from the main
|
||||
* controls, and another for the main controls themselves).
|
||||
*/
|
||||
#if GTK_CHECK_VERSION(2,4,0)
|
||||
gtk_alignment_set_padding(GTK_ALIGNMENT(align), 8, 8, 8, 8);
|
||||
#endif
|
||||
gtk_widget_show(align);
|
||||
gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dlg))),
|
||||
align, FALSE, TRUE, 0);
|
||||
|
||||
w = gtk_hseparator_new();
|
||||
gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dlg))),
|
||||
w, FALSE, TRUE, 0);
|
||||
gtk_widget_show(w);
|
||||
gtk_widget_hide(gtk_dialog_get_action_area(GTK_DIALOG(dlg)));
|
||||
g_object_set(G_OBJECT(dlg), "has-separator", TRUE, (const char *)NULL);
|
||||
|
||||
#else /* GTK 3 */
|
||||
|
||||
/* GtkWindow is a GtkBin, hence contains exactly one child, which
|
||||
* here we always expect to be a vbox */
|
||||
GtkBox *vbox = GTK_BOX(gtk_bin_get_child(GTK_BIN(dlg)));
|
||||
|
||||
GtkWidget *sep = gtk_hseparator_new();
|
||||
gtk_box_pack_end(vbox, sep, FALSE, TRUE, 0);
|
||||
gtk_widget_show(sep);
|
||||
|
||||
g_object_set(G_OBJECT(w), "margin", 8, (const char *)NULL);
|
||||
gtk_box_pack_end(vbox, w, FALSE, TRUE, 0);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
GtkBox *our_dialog_make_action_hbox(GtkWindow *dlg)
|
||||
{
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
our_dialog_set_action_area(dlg, hbox);
|
||||
gtk_widget_show(hbox);
|
||||
return GTK_BOX(hbox);
|
||||
#else /* not GTK 3 */
|
||||
return GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(dlg)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void our_dialog_add_to_content_area(GtkWindow *dlg, GtkWidget *w,
|
||||
gboolean expand, gboolean fill,
|
||||
guint padding)
|
||||
{
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
/* GtkWindow is a GtkBin, hence contains exactly one child, which
|
||||
* here we always expect to be a vbox */
|
||||
GtkBox *vbox = GTK_BOX(gtk_bin_get_child(GTK_BIN(dlg)));
|
||||
|
||||
gtk_box_pack_start(vbox, w, expand, fill, padding);
|
||||
#else
|
||||
gtk_box_pack_start
|
||||
(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dlg))),
|
||||
w, expand, fill, padding);
|
||||
#endif
|
||||
}
|
15
unix/gtkmisc.h
Normal file
15
unix/gtkmisc.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Miscellaneous helper functions for GTK.
|
||||
*/
|
||||
|
||||
#ifndef PUTTY_GTKMISC_H
|
||||
#define PUTTY_GTKMISC_H
|
||||
|
||||
GtkWidget *our_dialog_new(void);
|
||||
void our_dialog_add_to_content_area(GtkWindow *dlg, GtkWidget *w,
|
||||
gboolean expand, gboolean fill,
|
||||
guint padding);
|
||||
void our_dialog_set_action_area(GtkWindow *dlg, GtkWidget *w);
|
||||
GtkBox *our_dialog_make_action_hbox(GtkWindow *dlg);
|
||||
|
||||
#endif /* PUTTY_GTKMISC_H */
|
Loading…
Reference in New Issue
Block a user