mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 03:22:48 -05:00
Rework window geometry to avoid using geometry_widget.
Partly this is because the geometry_widget functionality is going away in a later version of GTK3, so sooner or later we'll need not to be using it anyway. But also, it turns out that GTK 3's geometry calculations have the unfortunate effect of setting the window's base and min heights to values that are not congruent mod height_increment (because the former is the value we gave, but the latter is based on the minimum height of the scrollbar), which confuses at least one window manager (xfwm4) and causes the window to be created one row too small. So I've redone all the geometry computations my own way, based on the knowledge that the only widgets visible in the top-level window are the drawing area and the scrollbar and I know how both of those behave, and taking care to keep base_height and min_height congruent to avoid that xfwm4 bug.
This commit is contained in:
116
unix/gtkwin.c
116
unix/gtkwin.c
@ -56,6 +56,7 @@ struct clipboard_data_instance;
|
||||
|
||||
struct gui_data {
|
||||
GtkWidget *window, *area, *sbar;
|
||||
gboolean sbar_visible;
|
||||
GtkBox *hbox;
|
||||
GtkAdjustment *sbar_adjust;
|
||||
GtkWidget *menu, *specialsmenu, *specialsitem1, *specialsitem2,
|
||||
@ -2846,6 +2847,15 @@ void scrollbar_moved(GtkAdjustment *adj, gpointer data)
|
||||
term_scroll(inst->term, 1, (int)gtk_adjustment_get_value(adj));
|
||||
}
|
||||
|
||||
static void show_scrollbar(struct gui_data *inst, gboolean visible)
|
||||
{
|
||||
inst->sbar_visible = visible;
|
||||
if (visible)
|
||||
gtk_widget_show(inst->sbar);
|
||||
else
|
||||
gtk_widget_hide(inst->sbar);
|
||||
}
|
||||
|
||||
void sys_cursor(void *frontend, int x, int y)
|
||||
{
|
||||
/*
|
||||
@ -3599,17 +3609,65 @@ char *setup_fonts_ucs(struct gui_data *inst)
|
||||
void set_geom_hints(struct gui_data *inst)
|
||||
{
|
||||
GdkGeometry geom;
|
||||
gint flags;
|
||||
|
||||
/*
|
||||
* Unused fields in geom.
|
||||
*/
|
||||
geom.max_width = geom.max_height = -1;
|
||||
geom.min_aspect = geom.max_aspect = 0;
|
||||
|
||||
/*
|
||||
* Set up the geometry fields we care about, with reference to
|
||||
* just the drawing area. We'll correct for the scrollbar in a
|
||||
* moment.
|
||||
*/
|
||||
flags = GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | GDK_HINT_RESIZE_INC;
|
||||
geom.min_width = inst->font_width + 2*inst->window_border;
|
||||
geom.min_height = inst->font_height + 2*inst->window_border;
|
||||
geom.max_width = geom.max_height = -1;
|
||||
geom.base_width = 2*inst->window_border;
|
||||
geom.base_height = 2*inst->window_border;
|
||||
geom.width_inc = inst->font_width;
|
||||
geom.height_inc = inst->font_height;
|
||||
geom.min_aspect = geom.max_aspect = 0;
|
||||
gtk_window_set_geometry_hints(GTK_WINDOW(inst->window), inst->area, &geom,
|
||||
GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE |
|
||||
GDK_HINT_RESIZE_INC);
|
||||
|
||||
/*
|
||||
* If we've got a scrollbar visible, then we must include its
|
||||
* width as part of the base and min width, and also ensure that
|
||||
* our window's minimum height is at least the height required by
|
||||
* the scrollbar.
|
||||
*
|
||||
* In the latter case, we must also take care to arrange that
|
||||
* (geom.min_height - geom.base_height) is an integer multiple of
|
||||
* geom.height_inc, because if it's not, then some window managers
|
||||
* (we know of xfwm4) get confused, with the effect that they
|
||||
* resize our window to a height based on min_height instead of
|
||||
* base_height, which we then round down and the window ends up
|
||||
* too short.
|
||||
*/
|
||||
if (inst->sbar_visible) {
|
||||
GtkRequisition req;
|
||||
int min_sb_height;
|
||||
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
gtk_widget_get_preferred_size(inst->sbar, &req, NULL);
|
||||
#else
|
||||
gtk_widget_size_request(inst->sbar, &req);
|
||||
#endif
|
||||
|
||||
/* Compute rounded-up scrollbar height. */
|
||||
min_sb_height = req.height;
|
||||
min_sb_height += geom.height_inc - 1;
|
||||
min_sb_height -= ((min_sb_height - geom.base_height % geom.height_inc)
|
||||
% geom.height_inc);
|
||||
|
||||
geom.min_width += req.width;
|
||||
geom.base_width += req.width;
|
||||
if (geom.min_height < min_sb_height)
|
||||
geom.min_height = min_sb_height;
|
||||
}
|
||||
|
||||
gtk_window_set_geometry_hints(GTK_WINDOW(inst->window),
|
||||
NULL, &geom, flags);
|
||||
}
|
||||
|
||||
void clear_scrollback_menuitem(GtkMenuItem *item, gpointer data)
|
||||
@ -3732,16 +3790,16 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
|
||||
}
|
||||
}
|
||||
|
||||
need_size = FALSE;
|
||||
|
||||
/*
|
||||
* If the scrollbar needs to be shown, hidden, or moved
|
||||
* from one end to the other of the window, do so now.
|
||||
*/
|
||||
if (conf_get_int(oldconf, CONF_scrollbar) !=
|
||||
conf_get_int(newconf, CONF_scrollbar)) {
|
||||
if (conf_get_int(newconf, CONF_scrollbar))
|
||||
gtk_widget_show(inst->sbar);
|
||||
else
|
||||
gtk_widget_hide(inst->sbar);
|
||||
show_scrollbar(inst, conf_get_int(newconf, CONF_scrollbar));
|
||||
need_size = TRUE;
|
||||
}
|
||||
if (conf_get_int(oldconf, CONF_scrollbar_on_left) !=
|
||||
conf_get_int(newconf, CONF_scrollbar_on_left)) {
|
||||
@ -3762,7 +3820,6 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
|
||||
* Redo the whole tangled fonts and Unicode mess if
|
||||
* necessary.
|
||||
*/
|
||||
need_size = FALSE;
|
||||
if (strcmp(conf_get_fontspec(oldconf, CONF_font)->name,
|
||||
conf_get_fontspec(newconf, CONF_font)->name) ||
|
||||
strcmp(conf_get_fontspec(oldconf, CONF_boldfont)->name,
|
||||
@ -4139,23 +4196,6 @@ struct gui_data *new_session_window(Conf *conf, const char *geometry_string)
|
||||
|
||||
init_clipboard(inst);
|
||||
|
||||
set_geom_hints(inst);
|
||||
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
gtk_window_set_default_geometry(GTK_WINDOW(inst->window),
|
||||
inst->width, inst->height);
|
||||
#else
|
||||
{
|
||||
int w = inst->font_width * inst->width + 2*inst->window_border;
|
||||
int h = inst->font_height * inst->height + 2*inst->window_border;
|
||||
#if GTK_CHECK_VERSION(2,0,0)
|
||||
gtk_widget_set_size_request(inst->area, w, h);
|
||||
#else
|
||||
gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area), w, h);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
inst->sbar_adjust = GTK_ADJUSTMENT(gtk_adjustment_new(0,0,0,0,0,0));
|
||||
inst->sbar = gtk_vscrollbar_new(inst->sbar_adjust);
|
||||
inst->hbox = GTK_BOX(gtk_hbox_new(FALSE, 0));
|
||||
@ -4173,12 +4213,26 @@ struct gui_data *new_session_window(Conf *conf, const char *geometry_string)
|
||||
gtk_container_add(GTK_CONTAINER(inst->window), GTK_WIDGET(inst->hbox));
|
||||
|
||||
gtk_widget_show(inst->area);
|
||||
if (conf_get_int(inst->conf, CONF_scrollbar))
|
||||
gtk_widget_show(inst->sbar);
|
||||
else
|
||||
gtk_widget_hide(inst->sbar);
|
||||
show_scrollbar(inst, conf_get_int(inst->conf, CONF_scrollbar));
|
||||
gtk_widget_show(GTK_WIDGET(inst->hbox));
|
||||
|
||||
set_geom_hints(inst);
|
||||
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
gtk_window_set_default_geometry(GTK_WINDOW(inst->window),
|
||||
inst->width, inst->height);
|
||||
#else
|
||||
{
|
||||
int w = inst->font_width * inst->width + 2*inst->window_border;
|
||||
int h = inst->font_height * inst->height + 2*inst->window_border;
|
||||
#if GTK_CHECK_VERSION(2,0,0)
|
||||
gtk_widget_set_size_request(inst->area, w, h);
|
||||
#else
|
||||
gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area), w, h);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GTK_CHECK_VERSION(2,0,0)
|
||||
if (inst->geometry) {
|
||||
gtk_window_parse_geometry(GTK_WINDOW(inst->window), inst->geometry);
|
||||
|
Reference in New Issue
Block a user