]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/gtkwin.c
A bunch of further warning fixes in the Windows code.
[PuTTY.git] / unix / gtkwin.c
index 427608f32862a76cdbfb5e1aa2ce98115511c187..eca119eb76799476530cd471b8b105f380e49050 100644 (file)
@@ -638,6 +638,8 @@ char *dup_keyval_name(guint keyval)
 }
 #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;
@@ -838,6 +840,23 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer 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.
@@ -3607,6 +3626,18 @@ char *setup_fonts_ucs(struct gui_data *inst)
     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)
 {
     /*
@@ -3617,7 +3648,7 @@ 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;
@@ -3662,6 +3693,50 @@ static void compute_geom_hints(struct gui_data *inst, GdkGeometry *geom)
         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)
@@ -3916,6 +3991,67 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
     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;
@@ -4232,6 +4368,13 @@ struct gui_data *new_session_window(Conf *conf, const char *geometry_string)
     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)