}
#endif
+static void change_font_size(struct gui_data *inst, int increment);
+
gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
struct gui_data *inst = (struct gui_data *)data;
}
}
+ if (event->keyval == GDK_KEY_greater &&
+ (event->state & GDK_CONTROL_MASK)) {
+#ifdef KEY_EVENT_DIAGNOSTICS
+ debug((" - Ctrl->: increase font size\n"));
+#endif
+ change_font_size(inst, +1);
+ return TRUE;
+ }
+ if (event->keyval == GDK_KEY_less &&
+ (event->state & GDK_CONTROL_MASK)) {
+#ifdef KEY_EVENT_DIAGNOSTICS
+ debug((" - Ctrl-<: increase font size\n"));
+#endif
+ change_font_size(inst, -1);
+ return TRUE;
+ }
+
/*
* Shift-PgUp and Shift-PgDn don't even generate keystrokes
* at all.
return NULL;
}
+#if GTK_CHECK_VERSION(3,0,0)
+struct find_app_menu_bar_ctx {
+ GtkWidget *area, *menubar;
+};
+static void find_app_menu_bar(GtkWidget *widget, gpointer data)
+{
+ struct find_app_menu_bar_ctx *ctx = (struct find_app_menu_bar_ctx *)data;
+ if (widget != ctx->area && GTK_IS_MENU_BAR(widget))
+ ctx->menubar = widget;
+}
+#endif
+
static void compute_geom_hints(struct gui_data *inst, GdkGeometry *geom)
{
/*
/*
* Set up the geometry fields we care about, with reference to
- * just the drawing area. We'll correct for the scrollbar in a
+ * just the drawing area. We'll correct for other widgets in a
* moment.
*/
geom->min_width = inst->font_width + 2*inst->window_border;
if (geom->min_height < min_sb_height)
geom->min_height = min_sb_height;
}
+
+#if GTK_CHECK_VERSION(3,0,0)
+ /*
+ * And if we're running a gtkapp.c based program and
+ * GtkApplicationWindow has given us a menu bar inside the window,
+ * then we must take that into account as well.
+ *
+ * In its unbounded wisdom, GtkApplicationWindow doesn't actually
+ * give us a direct function call to _find_ the menu bar widget.
+ * Fortunately, we can find it by enumerating the children of the
+ * top-level window and looking for one we didn't put there
+ * ourselves.
+ */
+ {
+ struct find_app_menu_bar_ctx actx, *ctx = &actx;
+ ctx->area = inst->area;
+ ctx->menubar = NULL;
+ gtk_container_foreach(GTK_CONTAINER(inst->window),
+ find_app_menu_bar, ctx);
+
+ if (ctx->menubar) {
+ GtkRequisition req;
+ int min_menu_width;
+ gtk_widget_get_preferred_size(ctx->menubar, NULL, &req);
+
+ /*
+ * This time, the height adjustment is easy (the menu bar
+ * sits above everything), but we have to take care with
+ * the _width_ to ensure we keep min_width and base_width
+ * congruent modulo width_inc.
+ */
+ geom->min_height += req.height;
+ geom->base_height += req.height;
+
+ min_menu_width = req.width;
+ min_menu_width += geom->width_inc - 1;
+ min_menu_width -=
+ ((min_menu_width - geom->base_width%geom->width_inc)
+ % geom->width_inc);
+ if (geom->min_width < min_menu_width)
+ geom->min_width = min_menu_width;
+ }
+ }
+#endif
}
void set_geom_hints(struct gui_data *inst)
inst->reconfiguring = FALSE;
}
+static void change_font_size(struct gui_data *inst, int increment)
+{
+ static const int conf_keys[lenof(inst->fonts)] = {
+ CONF_font, CONF_boldfont, CONF_widefont, CONF_wideboldfont,
+ };
+ FontSpec *oldfonts[lenof(inst->fonts)];
+ FontSpec *newfonts[lenof(inst->fonts)];
+ char *errmsg = NULL;
+ int i;
+
+ for (i = 0; i < lenof(newfonts); i++)
+ oldfonts[i] = newfonts[i] = NULL;
+
+ for (i = 0; i < lenof(inst->fonts); i++) {
+ if (inst->fonts[i]) {
+ char *newname = unifont_size_increment(inst->fonts[i], increment);
+ if (!newname)
+ goto cleanup;
+ newfonts[i] = fontspec_new(newname);
+ sfree(newname);
+ }
+ }
+
+ for (i = 0; i < lenof(newfonts); i++) {
+ if (newfonts[i]) {
+ oldfonts[i] = fontspec_copy(
+ conf_get_fontspec(inst->conf, conf_keys[i]));
+ conf_set_fontspec(inst->conf, conf_keys[i], newfonts[i]);
+ }
+ }
+
+ errmsg = setup_fonts_ucs(inst);
+ if (errmsg)
+ goto cleanup;
+
+ /* Success, so suppress putting everything back */
+ for (i = 0; i < lenof(newfonts); i++) {
+ if (oldfonts[i]) {
+ fontspec_free(oldfonts[i]);
+ oldfonts[i] = NULL;
+ }
+ }
+
+ set_geom_hints(inst);
+ request_resize(inst, conf_get_int(inst->conf, CONF_width),
+ conf_get_int(inst->conf, CONF_height));
+ term_invalidate(inst->term);
+ gtk_widget_queue_draw(inst->area);
+
+ cleanup:
+ for (i = 0; i < lenof(oldfonts); i++) {
+ if (oldfonts[i]) {
+ conf_set_fontspec(inst->conf, conf_keys[i], oldfonts[i]);
+ fontspec_free(oldfonts[i]);
+ }
+ if (newfonts[i])
+ fontspec_free(newfonts[i]);
+ }
+ sfree(errmsg);
+}
+
void dup_session_menuitem(GtkMenuItem *item, gpointer gdata)
{
struct gui_data *inst = (struct gui_data *)gdata;
show_scrollbar(inst, conf_get_int(inst->conf, CONF_scrollbar));
gtk_widget_show(GTK_WIDGET(inst->hbox));
+ /*
+ * We must call gtk_widget_realize before setting up the geometry
+ * hints, so that GtkApplicationWindow will have actually created
+ * its menu bar (if it's going to) and hence compute_geom_hints
+ * can find it to take its size into account.
+ */
+ gtk_widget_realize(inst->window);
set_geom_hints(inst);
#if GTK_CHECK_VERSION(3,0,0)