]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/gtkwin.c
Remove/rescope variable 'ret' in sftp_put_file.
[PuTTY.git] / unix / gtkwin.c
index fb45324d10c04e24382743d07b804c0d0b8f7a71..eca119eb76799476530cd471b8b105f380e49050 100644 (file)
@@ -94,11 +94,7 @@ struct gui_data {
     GtkIMContext *imc;
 #endif
     unifont *fonts[4];                 /* normal, bold, wide, widebold */
-#if GTK_CHECK_VERSION(2,0,0)
-    const char *geometry;
-#else
     int xpos, ypos, gotpos, gravity;
-#endif
     GdkCursor *rawcursor, *textcursor, *blankcursor, *waitcursor, *currcursor;
     GdkColor cols[NALLCOLOURS];
 #if !GTK_CHECK_VERSION(3,0,0)
@@ -341,6 +337,8 @@ void move_window(void *frontend, int x, int y)
      * though.
      */
 #if GTK_CHECK_VERSION(2,0,0)
+    /* in case we reset this at startup due to a geometry string */
+    gtk_window_set_gravity(GTK_WINDOW(inst->window), GDK_GRAVITY_NORTH_EAST);
     gtk_window_move(GTK_WINDOW(inst->window), x, y);
 #else
     gdk_window_move(gtk_widget_get_window(inst->window), x, y);
@@ -640,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;
@@ -840,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.
@@ -3609,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)
 {
     /*
@@ -3619,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;
@@ -3664,15 +3693,63 @@ 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)
 {
     GdkGeometry geom;
+    gint flags = GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | GDK_HINT_RESIZE_INC;
     compute_geom_hints(inst, &geom);
-    gtk_window_set_geometry_hints
-        (GTK_WINDOW(inst->window), NULL, &geom,
-         GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | GDK_HINT_RESIZE_INC);
+#if GTK_CHECK_VERSION(2,0,0)
+    if (inst->gotpos)
+        flags |= GDK_HINT_USER_POS;
+#endif
+    gtk_window_set_geometry_hints(GTK_WINDOW(inst->window),
+                                  NULL, &geom, flags);
 }
 
 #if GTK_CHECK_VERSION(2,0,0)
@@ -3914,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;
@@ -4153,11 +4291,8 @@ struct gui_data *new_session_window(Conf *conf, const char *geometry_string)
     inst->cumulative_scroll = 0.0;
 #endif
 
+#ifndef NOT_X_WINDOWS
     if (geometry_string) {
-#if GTK_CHECK_VERSION(2,0,0)
-        inst->geometry = geometry_string;
-#else
-        /* On GTK 1, we have to do this using raw Xlib */
         int flags, x, y;
         unsigned int w, h;
         flags = XParseGeometry(geometry_string, &x, &y, &w, &h);
@@ -4173,8 +4308,8 @@ struct gui_data *new_session_window(Conf *conf, const char *geometry_string)
             inst->gravity = ((flags & XNegative ? 1 : 0) |
                              (flags & YNegative ? 2 : 0));
         }
-#endif
     }
+#endif
 
     if (!compound_text_atom)
         compound_text_atom = gdk_atom_intern("COMPOUND_TEXT", FALSE);
@@ -4233,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)
@@ -4254,8 +4396,21 @@ struct gui_data *new_session_window(Conf *conf, const char *geometry_string)
 #endif
 
 #if GTK_CHECK_VERSION(2,0,0)
-    if (inst->geometry) {
-        gtk_window_parse_geometry(GTK_WINDOW(inst->window), inst->geometry);
+    if (inst->gotpos) {
+        static const GdkGravity gravities[] = {
+            GDK_GRAVITY_NORTH_WEST,
+            GDK_GRAVITY_NORTH_EAST,
+            GDK_GRAVITY_SOUTH_WEST,
+            GDK_GRAVITY_SOUTH_EAST,
+        };
+        int x = inst->xpos, y = inst->ypos;
+        int wp, hp;
+        compute_whole_window_size(inst, inst->width, inst->height, &wp, &hp);
+        if (inst->gravity & 1) x += (gdk_screen_width() - wp);
+        if (inst->gravity & 2) y += (gdk_screen_height() - hp);
+        gtk_window_set_gravity(GTK_WINDOW(inst->window),
+                               gravities[inst->gravity & 3]);
+       gtk_window_move(GTK_WINDOW(inst->window), x, y);
     }
 #else
     if (inst->gotpos) {