+/* Tracking of window sizes */
+static int toplevel_width = 640, toplevel_height = 480;
+static int mini_width = 480, mini_height = 140;
+static struct timeval last_mode_switch;
+
+static void main_minimode(const char attribute((unused)) *event,
+ void attribute((unused)) *evendata,
+ void attribute((unused)) *callbackdata) {
+ if(full_mode) {
+ gtk_window_resize(GTK_WINDOW(toplevel), toplevel_width, toplevel_height);
+ gtk_widget_show(tabs);
+ gtk_widget_hide(playing_mini);
+ /* Show the queue (bit confusing otherwise!) */
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(tabs), 0);
+ } else {
+ gtk_window_resize(GTK_WINDOW(toplevel), mini_width, mini_height);
+ gtk_widget_hide(tabs);
+ gtk_widget_show(playing_mini);
+ }
+ xgettimeofday(&last_mode_switch, NULL);
+}
+
+/* Called when the window size is allocate */
+static void toplevel_size_allocate(GtkWidget attribute((unused)) *w,
+ GtkAllocation *a,
+ gpointer attribute((unused)) user_data) {
+ struct timeval now;
+ xgettimeofday(&now, NULL);
+ if(tvdouble(tvsub(now, last_mode_switch)) < 0.5) {
+ /* Suppress size-allocate signals that are within half a second of a mode
+ * switch: they are quite likely to be the result of re-arranging widgets
+ * within the old size, not the application of the new size. Yes, this is
+ * a disgusting hack! */
+ return; /* OMG too soon! */
+ }
+ if(full_mode) {
+ toplevel_width = a->width;
+ toplevel_height = a->height;
+ } else {
+ mini_width = a->width;
+ mini_height = a->height;
+ }
+}
+
+/* Periodically check the toplevel's size
+ * (the hack in toplevel_size_allocate() means we could in principle
+ * miss a user-initiated resize)
+ */
+static void check_toplevel_size(const char attribute((unused)) *event,
+ void attribute((unused)) *evendata,
+ void attribute((unused)) *callbackdata) {
+ GtkAllocation a;
+ gtk_window_get_size(GTK_WINDOW(toplevel), &a.width, &a.height);
+ toplevel_size_allocate(NULL, &a, NULL);
+}
+
+static void hack_window_title(const char attribute((unused)) *event,
+ void attribute((unused)) *eventdata,
+ void attribute((unused)) *callbackdata) {
+ char *p;
+ const char *note;
+ static const char *last_note = 0;
+
+ if(!(last_state & DISORDER_CONNECTED))
+ note = "(disconnected)";
+ else if(last_state & DISORDER_TRACK_PAUSED)
+ note = "(paused)";
+ else if(playing_track) {
+ byte_asprintf(&p, "'%s' by %s, from '%s'",
+ namepart(playing_track->track, "display", "title"),
+ namepart(playing_track->track, "display", "artist"),
+ namepart(playing_track->track, "display", "album"));
+ note = p;
+ } else if(!(last_state & DISORDER_PLAYING_ENABLED))
+ note = "(playing disabled)";
+ else if(!(last_state & DISORDER_RANDOM_ENABLED))
+ note = "(random play disabled)";
+ else
+ note = "(nothing to play for unknown reason)";
+
+ if(last_note && !strcmp(note, last_note))
+ return;
+ last_note = xstrdup(note);
+ byte_asprintf(&p, "Disobedience: %s", note);
+ gtk_window_set_title(GTK_WINDOW(toplevel), p);
+}
+