Use the appalling gnome-terminal hack for server-controlled resizes
[sgt/putty] / unix / pterm.c
index d4b8f4d..3ae931f 100644 (file)
@@ -79,6 +79,14 @@ void logevent(char *string)
      */
 }
 
+int font_dimension(int which)         /* 0 for width, 1 for height */
+{
+    if (which)
+       return inst->font_height;
+    else
+       return inst->font_width;
+}
+
 /*
  * Translate a raw mouse button designation (LEFT, MIDDLE, RIGHT)
  * into a cooked one (SELECT, EXTEND, PASTE).
@@ -245,10 +253,8 @@ gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
     struct gui_data *inst = (struct gui_data *)data;
     int w, h, need_size = 0;
 
-printf("configure %d x %d\n", event->width, event->height);
     w = (event->width - 2*cfg.window_border) / inst->font_width;
     h = (event->height - 2*cfg.window_border) / inst->font_height;
-printf("        = %d x %d\n", w, h);
 
     if (w != cfg.width || h != cfg.height) {
        if (inst->pixmap) {
@@ -258,7 +264,6 @@ printf("        = %d x %d\n", w, h);
        cfg.width = w;
        cfg.height = h;
        need_size = 1;
-printf("need size\n");
     }
     if (!inst->pixmap) {
        GdkGC *gc;
@@ -853,9 +858,68 @@ void set_raw_mouse_mode(int activate)
 
 void request_resize(int w, int h)
 {
-    gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area),
-                         inst->font_width * w + 2*cfg.window_border,
-                         inst->font_height * h + 2*cfg.window_border);
+    int large_x, large_y;
+    int offset_x, offset_y;
+    int area_x, area_y;
+    GtkRequisition inner, outer;
+
+    /*
+     * This is a heinous hack dreamed up by the gnome-terminal
+     * people to get around a limitation in gtk. The problem is
+     * that in order to set the size correctly we really need to be
+     * calling gtk_window_resize - but that needs to know the size
+     * of the _whole window_, not the drawing area. So what we do
+     * is to set an artificially huge size request on the drawing
+     * area, recompute the resulting size request on the window,
+     * and look at the difference between the two. That gives us
+     * the x and y offsets we need to translate drawing area size
+     * into window size for real, and then we call
+     * gtk_window_resize.
+     */
+
+    /*
+     * We start by retrieving the current size of the whole window.
+     * Adding a bit to _that_ will give us a value we can use as a
+     * bogus size request which guarantees to be bigger than the
+     * current size of the drawing area.
+     */
+    get_window_pixels(&large_x, &large_y);
+    large_x += 32;
+    large_y += 32;
+
+#if GTK_CHECK_VERSION(2,0,0)
+    gtk_widget_set_size_request(inst->area, large_x, large_y);
+#else
+    gtk_widget_set_usize(inst->area, large_x, large_y);
+#endif
+    gtk_widget_size_request(inst->area, &inner);
+    gtk_widget_size_request(inst->window, &outer);
+
+    offset_x = outer.width - inner.width;
+    offset_y = outer.height - inner.height;
+
+    area_x = inst->font_width * w + 2*cfg.window_border;
+    area_y = inst->font_height * h + 2*cfg.window_border;
+
+    /*
+     * Now we must set the size request on the drawing area back to
+     * something sensible before we commit the real resize. Best
+     * way to do this, I think, is to set it to what the size is
+     * really going to end up being.
+     */
+#if GTK_CHECK_VERSION(2,0,0)
+    gtk_widget_set_size_request(inst->area, area_x, area_y);
+#else
+    gtk_widget_set_usize(inst->area, area_x, area_y);
+#endif
+
+#if GTK_CHECK_VERSION(2,0,0)
+    gtk_window_resize(GTK_WINDOW(inst->window),
+                     area_x + offset_x, area_y + offset_y);
+#else
+    gdk_window_resize(inst->window->window,
+                     area_x + offset_x, area_y + offset_y);
+#endif
 }
 
 void real_palette_set(int n, int r, int g, int b)
@@ -1430,8 +1494,6 @@ int main(int argc, char **argv)
     if (cfg.scrollbar)
        gtk_box_pack_start(inst->hbox, inst->sbar, FALSE, FALSE, 0);
 
-    gtk_window_set_policy(GTK_WINDOW(inst->window), FALSE, TRUE, TRUE);
-
     gtk_container_add(GTK_CONTAINER(inst->window), GTK_WIDGET(inst->hbox));
 
     {