X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=gtk.c;h=b1175efd03c6d8a2b1ebc932f17d2a2f0e64d470;hb=db313b3948d27244dd7c34c2609c66d6204d8931;hp=c2125229570927925773a12cf592e17350e9a19f;hpb=d72db91888c1efddd56c67eee665b0a83c9329eb;p=sgt-puzzles.git diff --git a/gtk.c b/gtk.c index c212522..b1175ef 100644 --- a/gtk.c +++ b/gtk.c @@ -189,6 +189,38 @@ struct frontend { int drawing_area_shrink_pending; int menubar_is_local; #endif +#if GTK_CHECK_VERSION(3,0,0) + /* + * This is used to get round an annoying lack of GTK notification + * message. If we request a window resize with + * gtk_window_resize(), we normally get back a "configure" event + * on the window and on its drawing area, and we respond to the + * latter by doing an appropriate resize of the puzzle. If the + * window is maximised, so that gtk_window_resize() _doesn't_ + * change its size, then that configure event never shows up. But + * if we requested the resize in response to a change of puzzle + * parameters (say, the user selected a differently-sized preset + * from the menu), then we would still like to be _notified_ that + * the window size was staying the same, so that we can respond by + * choosing an appropriate tile size for the new puzzle preset in + * the existing window size. + * + * Fortunately, in GTK 3, we may not get a "configure" event on + * the drawing area in this situation, but we still get a + * "size_allocate" event on the whole window (which, in other + * situations when we _do_ get a "configure" on the area, turns up + * second). So we treat _that_ event as indicating that if the + * "configure" event hasn't already shown up then it's not going + * to arrive. + * + * This flag is where we bookkeep this system. On + * gtk_window_resize we set this flag to true; the area's + * configure handler sets it back to false; then if that doesn't + * happen, the window's size_allocate handler does a fallback + * puzzle resize when it sees this flag still set to true. + */ + int awaiting_resize_ack; +#endif }; struct blitter { @@ -1338,15 +1370,10 @@ static gint map_window(GtkWidget *widget, GdkEvent *event, return TRUE; } -static gint configure_area(GtkWidget *widget, - GdkEventConfigure *event, gpointer data) +static void resize_puzzle_to_area(frontend *fe, int x, int y) { - frontend *fe = (frontend *)data; - int x, y; int oldw = fe->w, oldpw = fe->pw, oldh = fe->h, oldph = fe->ph; - x = event->width; - y = event->height; fe->w = x; fe->h = y; midend_size(fe->me, &x, &y, TRUE); @@ -1363,10 +1390,31 @@ static gint configure_area(GtkWidget *widget, } midend_force_redraw(fe->me); +} +static gint configure_area(GtkWidget *widget, + GdkEventConfigure *event, gpointer data) +{ + frontend *fe = (frontend *)data; + resize_puzzle_to_area(fe, event->width, event->height); + fe->awaiting_resize_ack = FALSE; return TRUE; } +#if GTK_CHECK_VERSION(3,0,0) +static void window_size_alloc(GtkWidget *widget, GtkAllocation *allocation, + gpointer data) +{ + frontend *fe = (frontend *)data; + if (fe->awaiting_resize_ack) { + GtkAllocation a; + gtk_widget_get_allocation(fe->area, &a); + resize_puzzle_to_area(fe, a.width, a.height); + fe->awaiting_resize_ack = FALSE; + } +} +#endif + static gint timer_func(gpointer data) { frontend *fe = (frontend *)data; @@ -1881,8 +1929,7 @@ static void changed_preset(frontend *fe) struct preset_menu_entry *entry = (struct preset_menu_entry *)g_object_get_data( G_OBJECT(gs->data), "user-data"); - - if (entry && entry->id != n) + if (!entry || entry->id != n) gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(gs->data), FALSE); else @@ -1890,7 +1937,7 @@ static void changed_preset(frontend *fe) } if (found) gtk_check_menu_item_set_active( - GTK_CHECK_MENU_ITEM(found->data), FALSE); + GTK_CHECK_MENU_ITEM(found->data), TRUE); } fe->preset_threaded = FALSE; @@ -1996,6 +2043,7 @@ static void resize_fe(frontend *fe) #if GTK_CHECK_VERSION(3,0,0) gtk_window_resize(GTK_WINDOW(fe->window), x, y + window_extra_height(fe)); + fe->awaiting_resize_ack = TRUE; #else fe->drawing_area_shrink_pending = FALSE; gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y); @@ -2522,6 +2570,10 @@ static frontend *new_window(char *arg, int argtype, char **error) } #endif +#if GTK_CHECK_VERSION(3,0,0) + fe->awaiting_resize_ack = FALSE; +#endif + fe->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(fe->window), thegame.name); @@ -2786,6 +2838,10 @@ static frontend *new_window(char *arg, int argtype, char **error) G_CALLBACK(configure_area), fe); g_signal_connect(G_OBJECT(fe->window), "configure_event", G_CALLBACK(configure_window), fe); +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(fe->window), "size_allocate", + G_CALLBACK(window_size_alloc), fe); +#endif gtk_widget_add_events(GTK_WIDGET(fe->area), GDK_BUTTON_PRESS_MASK |