Sort headers using clang-tidy
[geeqie.git] / src / fullscreen.cc
index fc8a216..5caed5a 100644 (file)
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "main.h"
 #include "fullscreen.h"
 
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <config.h>
+
+#include "compat.h"
+#include "debug.h"
+#include "image-load.h"
 #include "image.h"
+#include "intl.h"
 #include "misc.h"
+#include "options.h"
 #include "ui-fileops.h"
 #include "ui-misc.h"
 #include "window.h"
-#include "image-load.h"
-
-enum {
-       FULLSCREEN_CURSOR_HIDDEN = 1 << 0,
-       FULLSCREEN_CURSOR_NORMAL = 1 << 1,
-       FULLSCREEN_CURSOR_BUSY   = 1 << 2
-};
 
+namespace {
 
 /*
  *----------------------------------------------------------------------------
@@ -42,16 +46,29 @@ enum {
  *----------------------------------------------------------------------------
  */
 
-static void clear_mouse_cursor(GtkWidget *widget, gint state)
+#define FULL_SCREEN_HIDE_MOUSE_DELAY 3000
+#define FULL_SCREEN_BUSY_MOUSE_DELAY 200
+
+enum {
+       FULLSCREEN_CURSOR_HIDDEN = 1 << 0,
+       FULLSCREEN_CURSOR_NORMAL = 1 << 1,
+       FULLSCREEN_CURSOR_BUSY   = 1 << 2
+};
+
+void clear_mouse_cursor(GtkWidget *widget, gint state)
 {
        GdkWindow *window = gtk_widget_get_window(widget);
+       GdkDisplay *display;
+
        if (!window) return;
 
+       display = gdk_display_get_default();
+
        if (state & FULLSCREEN_CURSOR_BUSY)
                {
                GdkCursor *cursor;
 
-               cursor = gdk_cursor_new(GDK_WATCH);
+               cursor = gdk_cursor_new_for_display(display, GDK_WATCH);
                gdk_window_set_cursor(window, cursor);
                g_object_unref(G_OBJECT(cursor));
                }
@@ -63,13 +80,13 @@ static void clear_mouse_cursor(GtkWidget *widget, gint state)
                {
                GdkCursor *cursor;
 
-               cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
+               cursor = gdk_cursor_new_for_display(display, GDK_BLANK_CURSOR);
                gdk_window_set_cursor(window, cursor);
                g_object_unref(G_OBJECT(cursor));
                }
 }
 
-static gboolean fullscreen_hide_mouse_cb(gpointer data)
+gboolean fullscreen_hide_mouse_cb(gpointer data)
 {
        auto fs = static_cast<FullScreenData *>(data);
 
@@ -83,7 +100,7 @@ static gboolean fullscreen_hide_mouse_cb(gpointer data)
        return FALSE;
 }
 
-static void fullscreen_hide_mouse_disable(FullScreenData *fs)
+void fullscreen_hide_mouse_disable(FullScreenData *fs)
 {
        if (fs->hide_mouse_id)
                {
@@ -92,13 +109,13 @@ static void fullscreen_hide_mouse_disable(FullScreenData *fs)
                }
 }
 
-static void fullscreen_hide_mouse_reset(FullScreenData *fs)
+void fullscreen_hide_mouse_reset(FullScreenData *fs)
 {
        fullscreen_hide_mouse_disable(fs);
        fs->hide_mouse_id = g_timeout_add(FULL_SCREEN_HIDE_MOUSE_DELAY, fullscreen_hide_mouse_cb, fs);
 }
 
-static gboolean fullscreen_mouse_moved(GtkWidget *UNUSED(widget), GdkEventMotion *UNUSED(event), gpointer data)
+gboolean fullscreen_mouse_moved(GtkWidget *, GdkEventMotion *, gpointer data)
 {
        auto fs = static_cast<FullScreenData *>(data);
 
@@ -112,7 +129,7 @@ static gboolean fullscreen_mouse_moved(GtkWidget *UNUSED(widget), GdkEventMotion
        return FALSE;
 }
 
-static void fullscreen_busy_mouse_disable(FullScreenData *fs)
+void fullscreen_busy_mouse_disable(FullScreenData *fs)
 {
        if (fs->busy_mouse_id)
                {
@@ -121,7 +138,7 @@ static void fullscreen_busy_mouse_disable(FullScreenData *fs)
                }
 }
 
-static void fullscreen_mouse_set_busy(FullScreenData *fs, gboolean busy)
+void fullscreen_mouse_set_busy(FullScreenData *fs, gboolean busy)
 {
        fullscreen_busy_mouse_disable(fs);
 
@@ -139,7 +156,7 @@ static void fullscreen_mouse_set_busy(FullScreenData *fs, gboolean busy)
        clear_mouse_cursor(fs->window, fs->cursor_state);
 }
 
-static gboolean fullscreen_mouse_set_busy_cb(gpointer data)
+gboolean fullscreen_mouse_set_busy_cb(gpointer data)
 {
        auto fs = static_cast<FullScreenData *>(data);
 
@@ -148,7 +165,7 @@ static gboolean fullscreen_mouse_set_busy_cb(gpointer data)
        return FALSE;
 }
 
-static void fullscreen_mouse_set_busy_idle(FullScreenData *fs)
+void fullscreen_mouse_set_busy_idle(FullScreenData *fs)
 {
        if (!fs->busy_mouse_id)
                {
@@ -157,7 +174,7 @@ static void fullscreen_mouse_set_busy_idle(FullScreenData *fs)
                }
 }
 
-static void fullscreen_image_update_cb(ImageWindow *UNUSED(imd), gpointer data)
+void fullscreen_image_update_cb(ImageWindow *, gpointer data)
 {
        auto fs = static_cast<FullScreenData *>(data);
 
@@ -168,7 +185,7 @@ static void fullscreen_image_update_cb(ImageWindow *UNUSED(imd), gpointer data)
                }
 }
 
-static void fullscreen_image_complete_cb(ImageWindow *UNUSED(imd), gboolean preload, gpointer data)
+void fullscreen_image_complete_cb(ImageWindow *, gboolean preload, gpointer data)
 {
        auto fs = static_cast<FullScreenData *>(data);
 
@@ -178,7 +195,7 @@ static void fullscreen_image_complete_cb(ImageWindow *UNUSED(imd), gboolean prel
 #define XSCREENSAVER_BINARY    "xscreensaver-command"
 #define XSCREENSAVER_COMMAND   "xscreensaver-command -deactivate >&- 2>&- &"
 
-static void fullscreen_saver_deactivate()
+void fullscreen_saver_deactivate()
 {
        static gboolean checked = FALSE;
        static gboolean found = FALSE;
@@ -195,7 +212,7 @@ static void fullscreen_saver_deactivate()
                }
 }
 
-static gboolean fullscreen_saver_block_cb(gpointer UNUSED(data))
+gboolean fullscreen_saver_block_cb(gpointer)
 {
        if (options->fullscreen.disable_saver)
                {
@@ -205,7 +222,7 @@ static gboolean fullscreen_saver_block_cb(gpointer UNUSED(data))
        return TRUE;
 }
 
-static gboolean fullscreen_delete_cb(GtkWidget *UNUSED(widget), GdkEventAny *UNUSED(event), gpointer data)
+gboolean fullscreen_delete_cb(GtkWidget *, GdkEventAny *, gpointer data)
 {
        auto fs = static_cast<FullScreenData *>(data);
 
@@ -213,13 +230,225 @@ static gboolean fullscreen_delete_cb(GtkWidget *UNUSED(widget), GdkEventAny *UNU
        return TRUE;
 }
 
+
+/*
+ *----------------------------------------------------------------------------
+ * full screen preferences and utils
+ *----------------------------------------------------------------------------
+ */
+
+/**
+ * @struct ScreenData
+ * screen numbers for fullscreen_prefs are as follows: \n
+ *   0  use default display size \n
+ * 101  screen 0, monitor 0 \n
+ * 102  screen 0, monitor 1 \n
+ * 201  screen 1, monitor 0 \n
+ */
+struct ScreenData {
+       gint number;
+       std::string description;
+       GdkRectangle geometry;
+};
+
+GdkRectangle get_screen_default_geometry(GdkScreen *screen)
+{
+       GdkRectangle geometry;
+
+       geometry.x = 0;
+       geometry.y = 0;
+       geometry.width = gdk_screen_get_width(screen);
+       geometry.height = gdk_screen_get_height(screen);
+
+       return geometry;
+}
+
+std::vector<ScreenData> fullscreen_prefs_list()
+{
+       std::vector<ScreenData> list;
+       GdkDisplay *display;
+       GdkScreen *screen;
+       gint monitors;
+
+       display = gdk_display_get_default();
+       screen = gdk_display_get_default_screen(display);
+       monitors = gdk_display_get_n_monitors(display);
+
+       for (gint j = -1; j < monitors; j++)
+               {
+               GdkRectangle rect;
+               gchar *name;
+               gchar *subname;
+
+               name = gdk_screen_make_display_name(screen);
+
+               if (j < 0)
+                       {
+                       rect = get_screen_default_geometry(screen);
+                       subname = g_strdup(_("Full size"));
+                       }
+               else
+                       {
+                       auto monitor = gdk_display_get_monitor(display, j);
+                       gdk_monitor_get_geometry(monitor, &rect);
+                       subname = g_strdup(gdk_monitor_get_model(monitor));
+                       if (subname == nullptr)
+                               {
+                               subname = g_strdup_printf("%s %d", _("Monitor"), j + 1);
+                               }
+                       }
+
+               ScreenData sd;
+               sd.number = 100 + j + 1;
+               sd.description = std::string(_("Screen")) + " " + name + ", " + subname;
+               sd.geometry = rect;
+
+               DEBUG_1("Screen %d %30s %4d,%4d (%4dx%4d)",
+                       sd.number, sd.description.c_str(), sd.geometry.x, sd.geometry.y, sd.geometry.width, sd.geometry.height);
+
+               list.push_back(sd);
+
+               g_free(name);
+               g_free(subname);
+               }
+
+       return list;
+}
+
+/* screen_num is interpreted as such:
+ *  -1  window manager determines size and position, fallback is (1) active monitor
+ *   0  full size of screen containing widget
+ *   1  size of monitor containing widget
+ * 100  full size of screen 1 (screen, monitor counts start at 1)
+ * 101  size of monitor 1 on screen 1
+ * 203  size of monitor 3 on screen 2
+ * returns:
+ * dest_screen: screen to place widget [use gtk_window_set_screen()]
+ * same_region: the returned region will overlap the current location of widget.
+ */
+GdkRectangle fullscreen_prefs_get_geometry(gint screen_num, GtkWidget *widget, GdkScreen *&dest_screen, gboolean &same_region)
+{
+       if (screen_num >= 100)
+               {
+               std::vector<ScreenData> list = fullscreen_prefs_list();
+               auto it = std::find_if(list.cbegin(), list.cend(), [screen_num](const ScreenData &sd){ return sd.number == screen_num; });
+               if (it != list.cend())
+                       {
+                       GdkDisplay *display = gdk_display_get_default();
+
+                       dest_screen = gdk_display_get_default_screen(display);
+                       same_region = (!widget || !gtk_widget_get_window(widget) ||
+                                      (dest_screen == gtk_widget_get_screen(widget) &&
+                                       (it->number%100 == 0 ||
+                                        it->number%100 == gdk_screen_get_monitor_at_window(dest_screen, gtk_widget_get_window(widget)) + 1)));
+                       return it->geometry;
+                       }
+               }
+       else if (screen_num < 0) screen_num = 1;
+
+       GdkRectangle geometry;
+
+       if (screen_num != 1 || !widget || !gtk_widget_get_window(widget))
+               {
+               if (widget)
+                       {
+                       dest_screen = gtk_widget_get_screen(widget);
+                       }
+               else
+                       {
+                       dest_screen = gdk_screen_get_default();
+                       }
+
+               geometry = get_screen_default_geometry(dest_screen);
+               }
+       else
+               {
+               GdkDisplay *display;
+               GdkMonitor *monitor;
+
+               display = gtk_widget_get_display(widget);
+               monitor = gdk_display_get_monitor_at_window(display, gtk_widget_get_window(widget));
+
+               gdk_monitor_get_geometry(monitor, &geometry);
+
+               dest_screen = gtk_widget_get_screen(widget);
+               }
+
+       same_region = TRUE;
+       return geometry;
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+gint fullscreen_prefs_find_screen_for_widget_unused(GtkWidget *widget)
+{
+       GdkScreen *screen;
+       gint monitor;
+       gint n;
+
+       if (!widget || !gtk_widget_get_window(widget)) return 0;
+
+       screen = gtk_widget_get_screen(widget);
+       monitor = gdk_screen_get_monitor_at_window(screen, gtk_widget_get_window(widget));
+
+       n = 100 + monitor + 1;
+
+       DEBUG_1("Screen appears to be %d", n);
+
+       return n;
+}
+#pragma GCC diagnostic pop
+
+enum {
+       FS_MENU_COLUMN_NAME = 0,
+       FS_MENU_COLUMN_VALUE
+};
+
+#define BUTTON_ABOVE_KEY  "button_above"
+
+void fullscreen_prefs_selection_cb(GtkWidget *combo, gpointer data)
+{
+       auto value = static_cast<gint *>(data);
+       GtkTreeModel *store;
+       GtkTreeIter iter;
+       GtkWidget *button;
+
+       if (!value) return;
+
+       store = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
+       if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter)) return;
+       gtk_tree_model_get(store, &iter, FS_MENU_COLUMN_VALUE, value, -1);
+
+       button = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(combo), BUTTON_ABOVE_KEY));
+       if (button)
+               {
+               gtk_widget_set_sensitive(button, *value != -1);
+               }
+}
+
+void fullscreen_prefs_selection_add(GtkListStore *store, const gchar *text, gint value)
+{
+       GtkTreeIter iter;
+
+       gtk_list_store_append(store, &iter);
+       gtk_list_store_set(store, &iter, FS_MENU_COLUMN_NAME, text,
+                                        FS_MENU_COLUMN_VALUE, value, -1);
+}
+
+} // namespace
+
+
+/*
+ *----------------------------------------------------------------------------
+ * full screen functions
+ *----------------------------------------------------------------------------
+ */
+
 FullScreenData *fullscreen_start(GtkWidget *window, ImageWindow *imd,
-                                void (*stop_func)(FullScreenData *, gpointer), gpointer stop_data)
+                                FullScreenData::StopFunc stop_func, gpointer stop_data)
 {
        FullScreenData *fs;
        GdkScreen *screen;
-       gint x, y;
-       gint w, h;
        GdkGeometry geometry;
 
        if (!window || !imd) return nullptr;
@@ -235,10 +464,9 @@ FullScreenData *fullscreen_start(GtkWidget *window, ImageWindow *imd,
        fs->stop_data = stop_data;
 
        DEBUG_1("full screen requests screen %d", options->fullscreen.screen);
-       fullscreen_prefs_get_geometry(options->fullscreen.screen, window, &x, &y, &w, &h,
-                                     &screen, &fs->same_region);
+       GdkRectangle rect = fullscreen_prefs_get_geometry(options->fullscreen.screen, window, screen, fs->same_region);
 
-       fs->window = window_new(GTK_WINDOW_TOPLEVEL, "fullscreen", nullptr, nullptr, _("Full screen"));
+       fs->window = window_new("fullscreen", nullptr, nullptr, _("Full screen"));
        DEBUG_NAME(fs->window);
 
        g_signal_connect(G_OBJECT(fs->window), "delete_event",
@@ -249,13 +477,14 @@ FullScreenData *fullscreen_start(GtkWidget *window, ImageWindow *imd,
        gtk_container_set_border_width(GTK_CONTAINER(fs->window), 0);
 
        /* keep window above others, if requested */
-       if (options->fullscreen.above) {
-               gtk_window_set_keep_above(GTK_WINDOW(fs->window), TRUE);
-       }
+       if (options->fullscreen.above)
+               {
+               gq_gtk_window_set_keep_above(GTK_WINDOW(fs->window), TRUE);
+               }
 
        /* set default size and position, so the window appears where it was before */
-       gtk_window_set_default_size(GTK_WINDOW(fs->window), w, h);
-       gtk_window_move(GTK_WINDOW(fs->window), x, y);
+       gtk_window_set_default_size(GTK_WINDOW(fs->window), rect.width, rect.height);
+       gq_gtk_window_move(GTK_WINDOW(fs->window), rect.x, rect.y);
 
        /* By setting USER_POS and USER_SIZE, most window managers will
         * not request positioning of the full screen window (for example twm).
@@ -266,8 +495,8 @@ FullScreenData *fullscreen_start(GtkWidget *window, ImageWindow *imd,
         */
        geometry.min_width = 1;
        geometry.min_height = 1;
-       geometry.base_width = w;
-       geometry.base_height = h;
+       geometry.base_width = rect.width;
+       geometry.base_height = rect.height;
        geometry.win_gravity = GDK_GRAVITY_STATIC;
        gtk_window_set_geometry_hints(GTK_WINDOW(fs->window), fs->window, &geometry,
                        static_cast<GdkWindowHints>(GDK_HINT_WIN_GRAVITY | GDK_HINT_USER_POS | GDK_HINT_USER_SIZE));
@@ -293,7 +522,7 @@ FullScreenData *fullscreen_start(GtkWidget *window, ImageWindow *imd,
 
        fs->imd = image_new(FALSE);
 
-       gtk_container_add(GTK_CONTAINER(fs->window), fs->imd->widget);
+       gq_gtk_container_add(GTK_WIDGET(fs->window), fs->imd->widget);
 
        image_background_set_color_from_options(fs->imd, TRUE);
        image_set_delay_flip(fs->imd, options->fullscreen.clean_flip);
@@ -318,9 +547,10 @@ FullScreenData *fullscreen_start(GtkWidget *window, ImageWindow *imd,
                image_copy_from_image(fs->imd, fs->normal_imd);
                }
 
-       if (options->stereo.enable_fsmode) {
+       if (options->stereo.enable_fsmode)
+               {
                image_stereo_set(fs->imd, options->stereo.fsmode);
-       }
+               }
 
        gtk_widget_show(fs->window);
 
@@ -373,7 +603,7 @@ void fullscreen_stop(FullScreenData *fs)
 
        if (fs->stop_func) fs->stop_func(fs, fs->stop_data);
 
-       gtk_widget_destroy(fs->window);
+       gq_gtk_widget_destroy(fs->window);
 
        gtk_window_present(GTK_WINDOW(fs->normal_window));
 
@@ -387,273 +617,13 @@ void fullscreen_stop(FullScreenData *fs)
  *----------------------------------------------------------------------------
  */
 
-GList *fullscreen_prefs_list()
-{
-       GList *list = nullptr;
-       GdkDisplay *display;
-       gint number;
-       gint i;
-
-       display = gdk_display_get_default();
-       number = gdk_display_get_n_screens(display);
-
-       for (i = 0; i < number; i++)
-               {
-               GdkScreen *screen;
-               gint monitors;
-               gint j;
-
-               screen = gdk_display_get_screen(display, i);
-               monitors = gdk_screen_get_n_monitors(screen);
-
-               for (j = -1; j < monitors; j++)
-                       {
-                       ScreenData *sd;
-                       GdkRectangle rect;
-                       gchar *name;
-                       gchar *subname;
-
-                       name = gdk_screen_make_display_name(screen);
-
-                       if (j < 0)
-                               {
-                               rect.x = 0;
-                               rect.y = 0;
-                               rect.width = gdk_screen_get_width(screen);
-                               rect.height = gdk_screen_get_height(screen);
-                               subname = g_strdup(_("Full size"));
-                               }
-                       else
-                               {
-                               gdk_screen_get_monitor_geometry(screen, j, &rect);
-                               subname = gdk_screen_get_monitor_plug_name(screen, j);
-                               if (subname == nullptr)
-                                       {
-                                       subname = g_strdup_printf("%s %d", _("Monitor"), j + 1);
-                                       }
-                               }
-
-                       sd = g_new0(ScreenData, 1);
-                       sd->number = (i+1) * 100 + j + 1;
-                       sd->description = g_strdup_printf("%s %s, %s", _("Screen"), name, subname);
-                       sd->x = rect.x;
-                       sd->y = rect.y;
-                       sd->width = rect.width;
-                       sd->height = rect.height;
-
-                       DEBUG_1("Screen %d %30s %4d,%4d (%4dx%4d)",
-                                         sd->number, sd->description, sd->x, sd->y, sd->width, sd->height);
-
-                       list = g_list_append(list, sd);
-
-                       g_free(name);
-                       g_free(subname);
-                       }
-               }
-
-       return list;
-}
-
-void fullscreen_prefs_list_free(GList *list)
-{
-       GList *work;
-
-       work = list;
-       while (work)
-               {
-               auto sd = static_cast<ScreenData *>(work->data);
-               work = work->next;
-
-               g_free(sd->description);
-               g_free(sd);
-               }
-
-       g_list_free(list);
-}
-
-ScreenData *fullscreen_prefs_list_find(GList *list, gint screen)
-{
-       GList *work;
-
-       work = list;
-       while (work)
-               {
-               auto sd = static_cast<ScreenData *>(work->data);
-               work = work->next;
-
-               if (sd->number == screen) return sd;
-               }
-
-       return nullptr;
-}
-
-/* screen is interpreted as such:
- *  -1  window manager determines size and position, fallback is (1) active monitor
- *   0  full size of screen containing widget
- *   1  size of monitor containing widget
- * 100  full size of screen 1 (screen, monitor counts start at 1)
- * 101  size of monitor 1 on screen 1
- * 203  size of monitor 3 on screen 2
- * returns:
- * dest_screen: screen to place widget [use gtk_window_set_screen()]
- * same_region: the returned region will overlap the current location of widget.
- */
-void fullscreen_prefs_get_geometry(gint screen, GtkWidget *widget, gint *x, gint *y, gint *width, gint *height,
-                                  GdkScreen **dest_screen, gboolean *same_region)
-{
-       GList *list;
-       ScreenData *sd;
-
-       list = fullscreen_prefs_list();
-       if (screen >= 100)
-               {
-               sd = fullscreen_prefs_list_find(list, screen);
-               }
-       else
-               {
-               sd = nullptr;
-               if (screen < 0) screen = 1;
-               }
-
-       if (sd)
-               {
-               GdkDisplay *display;
-               GdkScreen *screen;
-               gint n;
-
-               display = gdk_display_get_default();
-               n = sd->number / 100 - 1;
-               if (n >= 0 && n < gdk_display_get_n_screens(display))
-                       {
-                       screen = gdk_display_get_screen(display, n);
-                       }
-               else
-                       {
-                       screen = gdk_display_get_default_screen(display);
-                       }
-
-               if (x) *x = sd->x;
-               if (y) *y = sd->y;
-               if (width) *width = sd->width;
-               if (height) *height = sd->height;
-
-               if (dest_screen) *dest_screen = screen;
-               if (same_region) *same_region = (!widget || !gtk_widget_get_window(widget) ||
-                                       (screen == gtk_widget_get_screen(widget) &&
-                                       (sd->number%100 == 0 ||
-                                        sd->number%100 == gdk_screen_get_monitor_at_window(screen, gtk_widget_get_window(widget))+1)));
-
-               }
-       else if (screen != 1 || !widget || !gtk_widget_get_window(widget))
-               {
-               GdkScreen *screen;
-
-               if (widget)
-                       {
-                       screen = gtk_widget_get_screen(widget);
-                       }
-               else
-                       {
-                       screen = gdk_screen_get_default();
-                       }
-
-               if (x) *x = 0;
-               if (y) *y = 0;
-               if (width) *width = gdk_screen_get_width(screen);
-               if (height) *height = gdk_screen_get_height(screen);
-
-               if (dest_screen) *dest_screen = screen;
-               if (same_region) *same_region = TRUE;
-               }
-       else
-               {
-               GdkScreen *screen;
-               gint monitor;
-               GdkRectangle rect;
-
-               screen = gtk_widget_get_screen(widget);
-               monitor = gdk_screen_get_monitor_at_window(screen, gtk_widget_get_window(widget));
-
-               gdk_screen_get_monitor_geometry(screen, monitor, &rect);
-
-               if (x) *x = rect.x;
-               if (y) *y = rect.y;
-               if (width) *width = rect.width;
-               if (height) *height = rect.height;
-
-               if (dest_screen) *dest_screen = screen;
-               if (same_region) *same_region = TRUE;
-               }
-
-       fullscreen_prefs_list_free(list);
-}
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-gint fullscreen_prefs_find_screen_for_widget_unused(GtkWidget *widget)
-{
-       GdkScreen *screen;
-       gint monitor;
-       gint n;
-
-       if (!widget || !gtk_widget_get_window(widget)) return 0;
-
-       screen = gtk_widget_get_screen(widget);
-       monitor = gdk_screen_get_monitor_at_window(screen, gtk_widget_get_window(widget));
-
-       n = (gdk_screen_get_number(screen)+1) * 100 + monitor + 1;
-
-       DEBUG_1("Screen appears to be %d", n);
-
-       return n;
-}
-#pragma GCC diagnostic pop
-
-enum {
-       FS_MENU_COLUMN_NAME = 0,
-       FS_MENU_COLUMN_VALUE
-};
-
-#define BUTTON_ABOVE_KEY  "button_above"
-
-static void fullscreen_prefs_selection_cb(GtkWidget *combo, gpointer data)
-{
-       auto value = static_cast<gint *>(data);
-       GtkTreeModel *store;
-       GtkTreeIter iter;
-       GtkWidget *button;
-
-       if (!value) return;
-
-       store = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
-       if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter)) return;
-       gtk_tree_model_get(store, &iter, FS_MENU_COLUMN_VALUE, value, -1);
-
-       button = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(combo), BUTTON_ABOVE_KEY));
-       if (button)
-               {
-               gtk_widget_set_sensitive(button, *value != -1);
-               }
-}
-
-static void fullscreen_prefs_selection_add(GtkListStore *store, const gchar *text, gint value)
-{
-       GtkTreeIter iter;
-
-       gtk_list_store_append(store, &iter);
-       gtk_list_store_set(store, &iter, FS_MENU_COLUMN_NAME, text,
-                                        FS_MENU_COLUMN_VALUE, value, -1);
-}
-
-GtkWidget *fullscreen_prefs_selection_new(const gchar *text, gint *screen_value, gboolean *UNUSED(above_value))
+GtkWidget *fullscreen_prefs_selection_new(const gchar *text, gint *screen_value, gboolean *)
 {
        GtkWidget *vbox;
        GtkWidget *hbox;
        GtkWidget *combo;
        GtkListStore *store;
        GtkCellRenderer *renderer;
-       GList *list;
-       GList *work;
        gint current = 0;
        gint n;
 
@@ -680,23 +650,18 @@ GtkWidget *fullscreen_prefs_selection_new(const gchar *text, gint *screen_value,
        if (*screen_value == 1) current = 2;
 
        n = 3;
-       list = fullscreen_prefs_list();
-       work = list;
-       while (work)
+       std::vector<ScreenData> list = fullscreen_prefs_list();
+       for (const ScreenData &sd : list)
                {
-               auto sd = static_cast<ScreenData *>(work->data);
-
-               fullscreen_prefs_selection_add(store, sd->description, sd->number);
-               if (*screen_value == sd->number) current = n;
+               fullscreen_prefs_selection_add(store, sd.description.c_str(), sd.number);
+               if (*screen_value == sd.number) current = n;
 
-               work = work->next;
                n++;
                }
-       fullscreen_prefs_list_free(list);
 
        gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
 
-       gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0);
+       gq_gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0);
        gtk_widget_show(combo);
 
        g_signal_connect(G_OBJECT(combo), "changed",