From: Adrien Plazas <kekun.plazas@laposte.net>
Date: Tue, 10 Dec 2019 10:04:30 +0100
Subject: window: Port it to phones

Fixes https://source.puri.sm/Librem5/Apps_Issues/issues/150.
---
 shell/ev-window.c | 193 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 113 insertions(+), 80 deletions(-)

diff --git a/shell/ev-window.c b/shell/ev-window.c
index 9a6dd2d..3ddd52e 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -135,8 +135,9 @@ typedef struct {
 
 	GtkWidget *main_box;
 	GtkWidget *toolbar;
-	GtkWidget *hpaned;
+	GtkWidget *flap;
 	GtkWidget *view_box;
+	GtkWidget *sidebar_stack;
 	GtkWidget *sidebar;
 	GtkWidget *search_box;
 	GtkWidget *search_bar;
@@ -263,7 +264,7 @@ typedef struct {
 #define GS_LAST_PICTURES_DIRECTORY "pictures-directory"
 #define GS_ALLOW_LINKS_CHANGE_ZOOM "allow-links-change-zoom"
 
-#define SIDEBAR_DEFAULT_SIZE    132
+#define SIDEBAR_DEFAULT_SIZE    246
 #define LINKS_SIDEBAR_ID "links"
 #define THUMBNAILS_SIDEBAR_ID "thumbnails"
 #define ATTACHMENTS_SIDEBAR_ID "attachments"
@@ -300,9 +301,6 @@ static const gchar *document_print_settings[] = {
 };
 
 static void	ev_window_update_actions_sensitivity    (EvWindow         *ev_window);
-static void     ev_window_sidebar_visibility_changed_cb (EvSidebar        *ev_sidebar,
-							 GParamSpec       *pspec,
-							 EvWindow         *ev_window);
 static void     ev_window_set_page_mode                 (EvWindow         *window,
 							 EvWindowPageMode  page_mode);
 static void	ev_window_load_job_cb  			(EvJob            *job,
@@ -684,7 +682,8 @@ update_chrome_visibility (EvWindow *window)
 	sidebar = (priv->chrome & EV_CHROME_SIDEBAR) != 0 && priv->document && !presentation;
 
 	set_widget_visibility (priv->toolbar, toolbar);
-	set_widget_visibility (priv->sidebar, sidebar);
+	set_widget_visibility (priv->sidebar, TRUE);
+	hdy_flap_set_reveal_flap (HDY_FLAP (priv->flap), sidebar);
 }
 
 static void
@@ -1288,15 +1287,11 @@ static void
 setup_sidebar_from_metadata (EvWindow *window)
 {
 	gchar *page_id;
-	gint   sidebar_size;
 	EvWindowPrivate *priv = GET_PRIVATE (window);
 
 	if (!priv->metadata)
 		return;
 
-	if (ev_metadata_get_int (priv->metadata, "sidebar_size", &sidebar_size))
-		gtk_paned_set_position (GTK_PANED (priv->hpaned), sidebar_size);
-
 	if (ev_metadata_get_string (priv->metadata, "sidebar_page", &page_id))
 		ev_window_sidebar_set_current_page (window, page_id);
 }
@@ -1591,10 +1586,6 @@ ev_window_setup_default (EvWindow *ev_window)
 			    g_settings_get_boolean (settings, "show-sidebar"));
 	update_chrome_visibility (ev_window);
 
-	/* Sidebar */
-	gtk_paned_set_position (GTK_PANED (priv->hpaned),
-				g_settings_get_int (settings, "sidebar-size"));
-
 	/* Document model */
 	ev_document_model_set_continuous (model, g_settings_get_boolean (settings, "continuous"));
 	ev_document_model_set_dual_page (model, g_settings_get_boolean (settings, "dual-page"));
@@ -1713,7 +1704,7 @@ ev_window_setup_document (EvWindow *ev_window)
 
 	if (EV_WINDOW_IS_PRESENTATION (priv))
 		gtk_widget_grab_focus (priv->presentation_view);
-	else if (!gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (priv->search_bar)))
+	else if (!hdy_search_bar_get_search_mode (HDY_SEARCH_BAR (priv->search_bar)))
 		gtk_widget_grab_focus (priv->view);
 
 	return FALSE;
@@ -2024,7 +2015,7 @@ ev_window_reload_job_cb (EvJob    *job,
 	}
 
 	/* Restart the search after reloading */
-	if (gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (priv->search_bar)))
+	if (hdy_search_bar_get_search_mode (HDY_SEARCH_BAR (priv->search_bar)))
 		ev_search_box_restart (EV_SEARCH_BOX (priv->search_box));
 
 	ev_window_clear_reload_job (ev_window);
@@ -2555,7 +2546,7 @@ ev_window_open_recent_view (EvWindow *ev_window)
 	if (priv->recent_view)
 		return;
 
-	gtk_widget_hide (priv->hpaned);
+	gtk_widget_hide (priv->flap);
 
 	priv->recent_view = EV_RECENT_VIEW (ev_recent_view_new ());
 	g_signal_connect_object (priv->recent_view,
@@ -2584,7 +2575,7 @@ ev_window_destroy_recent_view (EvWindow *ev_window)
 
 	gtk_widget_destroy (GTK_WIDGET (priv->recent_view));
 	priv->recent_view = NULL;
-	gtk_widget_show (priv->hpaned);
+	gtk_widget_show (priv->flap);
 }
 
 static void
@@ -4447,7 +4438,7 @@ ev_window_cmd_edit_find_next (GSimpleAction *action,
 	if (EV_WINDOW_IS_PRESENTATION (priv))
 		return;
 
-	search_mode_enabled = gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (priv->search_bar));
+	search_mode_enabled = hdy_search_bar_get_search_mode (HDY_SEARCH_BAR (priv->search_bar));
 	ev_window_show_find_bar (ev_window, FALSE);
 
 	/* Use idle to make sure view allocation happens before find */
@@ -4476,7 +4467,7 @@ ev_window_cmd_edit_find_previous (GSimpleAction *action,
 	if (EV_WINDOW_IS_PRESENTATION (priv))
 		return;
 
-	search_mode_enabled = gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (priv->search_bar));
+	search_mode_enabled = hdy_search_bar_get_search_mode (HDY_SEARCH_BAR (priv->search_bar));
 	ev_window_show_find_bar (ev_window, FALSE);
 
 	/* Use idle to make sure view allocation happens before find */
@@ -4497,18 +4488,6 @@ ev_window_cmd_edit_copy (GSimpleAction *action,
 	ev_view_copy (EV_VIEW (priv->view));
 }
 
-static void
-ev_window_sidebar_position_change_cb (GObject    *object,
-				      GParamSpec *pspec,
-				      EvWindow   *ev_window)
-{
-	EvWindowPrivate *priv = GET_PRIVATE (ev_window);
-
-	if (priv->metadata && !ev_window_is_empty (ev_window))
-		ev_metadata_set_int (priv->metadata, "sidebar_size",
-				     gtk_paned_get_position (GTK_PANED (object)));
-}
-
 static void
 ev_window_update_links_model (EvWindow *window)
 {
@@ -4700,7 +4679,7 @@ ev_window_run_presentation (EvWindow *window)
 			    priv->presentation_view,
 			    TRUE, TRUE, 0);
 
-	gtk_widget_hide (priv->hpaned);
+	gtk_widget_hide (priv->flap);
 	update_chrome_visibility (window);
 
 	gtk_widget_grab_focus (priv->presentation_view);
@@ -4735,7 +4714,7 @@ ev_window_stop_presentation (EvWindow *window,
 			      priv->presentation_view);
 	priv->presentation_view = NULL;
 
-	gtk_widget_show (priv->hpaned);
+	gtk_widget_show (priv->flap);
 	update_chrome_visibility (window);
 	if (unfullscreen_window)
 		gtk_window_unfullscreen (GTK_WINDOW (window));
@@ -4924,9 +4903,7 @@ ev_window_cmd_edit_save_settings (GSimpleAction *action,
 		g_settings_set_double (settings, "zoom", zoom);
 	}
 	g_settings_set_boolean (settings, "show-sidebar",
-				gtk_widget_get_visible (priv->sidebar));
-	g_settings_set_int (settings, "sidebar-size",
-			    gtk_paned_get_position (GTK_PANED (priv->hpaned)));
+				hdy_flap_get_reveal_flap (HDY_FLAP (priv->flap)));
 	g_settings_set_string (settings, "sidebar-page",
 			       ev_window_sidebar_get_current_page_id (ev_window));
 	g_settings_set_boolean (settings, "enable-spellchecking",
@@ -5195,7 +5172,7 @@ ev_window_cmd_escape (GSimpleAction *action,
 
 	ev_view_autoscroll_stop (EV_VIEW (priv->view));
 
-	if (gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (priv->search_bar)))
+	if (hdy_search_bar_get_search_mode (HDY_SEARCH_BAR (priv->search_bar)))
 		ev_window_close_find_bar (window);
 	else if (ev_document_model_get_fullscreen (priv->model))
 		ev_window_stop_fullscreen (window, TRUE);
@@ -5450,14 +5427,12 @@ ev_window_sidebar_current_page_changed_cb (EvSidebar  *ev_sidebar,
 }
 
 static void
-ev_window_sidebar_visibility_changed_cb (EvSidebar  *ev_sidebar,
-					 GParamSpec *pspec,
-					 EvWindow   *ev_window)
+flap_reveal_changed_cb (EvWindow *ev_window)
 {
 	EvWindowPrivate *priv = GET_PRIVATE (ev_window);
 
 	if (!EV_WINDOW_IS_PRESENTATION (priv)) {
-		gboolean visible = gtk_widget_get_visible (GTK_WIDGET (ev_sidebar));
+		gboolean visible = hdy_flap_get_reveal_flap (HDY_FLAP (priv->flap));
 
 		g_action_group_change_action_state (G_ACTION_GROUP (ev_window), "show-side-pane",
 						    g_variant_new_boolean (visible));
@@ -5467,6 +5442,10 @@ ev_window_sidebar_visibility_changed_cb (EvSidebar  *ev_sidebar,
 						 visible);
 		if (!visible)
 			gtk_widget_grab_focus (priv->view);
+
+		update_chrome_flag (ev_window, EV_CHROME_SIDEBAR, visible);
+		update_chrome_visibility (ev_window);
+		ev_toolbar_set_sidebar_visible (EV_TOOLBAR (priv->toolbar), visible);
 	}
 }
 
@@ -5801,12 +5780,12 @@ search_next_cb (EvSearchBox *search_box,
 }
 
 static void
-search_bar_search_mode_enabled_changed (GtkSearchBar *search_bar,
+search_bar_search_mode_enabled_changed (HdySearchBar *search_bar,
 					GParamSpec   *param,
 					EvWindow     *ev_window)
 {
 	EvWindowPrivate *priv = GET_PRIVATE (ev_window);
-	gboolean enabled = gtk_search_bar_get_search_mode (search_bar);
+	gboolean enabled = hdy_search_bar_get_search_mode (search_bar);
 
 	ev_view_find_set_highlight_search (EV_VIEW (priv->view), enabled);
 	ev_window_update_actions_sensitivity (ev_window);
@@ -5830,7 +5809,8 @@ ev_window_show_find_bar (EvWindow *ev_window,
 {
 	EvWindowPrivate *priv = GET_PRIVATE (ev_window);
 
-	if (gtk_widget_get_visible (priv->find_sidebar)) {
+	if (gtk_stack_get_visible_child (GTK_STACK (priv->sidebar_stack)) == priv->find_sidebar) {
+		hdy_flap_set_reveal_flap (HDY_FLAP (priv->flap), TRUE);
 		gtk_widget_grab_focus (priv->search_box);
 		return;
 	}
@@ -5846,13 +5826,10 @@ ev_window_show_find_bar (EvWindow *ev_window,
 	ev_history_freeze (priv->history);
 
 	g_object_ref (priv->sidebar);
-	gtk_container_remove (GTK_CONTAINER (priv->hpaned), priv->sidebar);
-	gtk_paned_pack1 (GTK_PANED (priv->hpaned),
-			 priv->find_sidebar, FALSE, FALSE);
-	gtk_widget_show (priv->find_sidebar);
+	gtk_stack_set_visible_child (GTK_STACK (priv->sidebar_stack), priv->find_sidebar);
 
 
-	gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->search_bar), TRUE);
+	hdy_search_bar_set_search_mode (HDY_SEARCH_BAR (priv->search_bar), TRUE);
 	gtk_widget_grab_focus (priv->search_box);
 	g_action_group_change_action_state (G_ACTION_GROUP (ev_window), "toggle-find", g_variant_new_boolean (TRUE));
 
@@ -5870,17 +5847,13 @@ ev_window_close_find_bar (EvWindow *ev_window)
 {
 	EvWindowPrivate *priv = GET_PRIVATE (ev_window);
 
-	if (!gtk_widget_get_visible (priv->find_sidebar))
+	if (gtk_stack_get_visible_child (GTK_STACK (priv->sidebar_stack)) != priv->find_sidebar)
 		return;
 
 	g_object_ref (priv->find_sidebar);
-	gtk_container_remove (GTK_CONTAINER (priv->hpaned),
-			      priv->find_sidebar);
-	gtk_paned_pack1 (GTK_PANED (priv->hpaned),
-			 priv->sidebar, FALSE, FALSE);
-	gtk_widget_hide (priv->find_sidebar);
+	gtk_stack_set_visible_child (GTK_STACK (priv->sidebar_stack), priv->sidebar);
 
-	gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->search_bar), FALSE);
+	hdy_search_bar_set_search_mode (HDY_SEARCH_BAR (priv->search_bar), FALSE);
 	gtk_widget_grab_focus (priv->view);
 	g_action_group_change_action_state (G_ACTION_GROUP (ev_window), "toggle-find", g_variant_new_boolean (FALSE));
 
@@ -6556,6 +6529,48 @@ window_state_event_cb (EvWindow *window, GdkEventWindowState *event, gpointer du
 	return FALSE;
 }
 
+static void
+window_size_allocate_cb (EvWindow *window)
+{
+	EvWindowPrivate *priv = GET_PRIVATE (window);
+	gboolean is_maximized, is_fullscreen;
+	gboolean is_narrow, is_mobile_landscape, is_mobile;
+	int width, height;
+	GdkDisplay *display;
+	GdkWindow *surface;
+	GdkMonitor *monitor = NULL;
+	GdkRectangle geometry = {};
+
+	gtk_window_get_size (GTK_WINDOW (window), &width, &height);
+
+	/* Get the monitor to guess whether we are on a mobile or not. If not found,
+	* fallback to the window size.
+	*/
+	display = gtk_widget_get_display (GTK_WIDGET (window));
+	surface = gtk_widget_get_window (GTK_WIDGET (window));
+
+	if (display != NULL && surface != NULL)
+		monitor = gdk_display_get_monitor_at_window (display, surface);
+
+	if (monitor != NULL)
+		gdk_monitor_get_geometry (monitor, &geometry);
+	else
+		geometry.height = height;
+
+	is_maximized = gtk_window_is_maximized (GTK_WINDOW (window));
+	is_fullscreen = GDK_IS_WINDOW (surface) && (gdk_window_get_state (surface) & GDK_WINDOW_STATE_FULLSCREEN) > 0;
+
+	is_narrow = width <= 600;
+	is_mobile_landscape = geometry.height <= 400 &&
+	                      (is_maximized || is_fullscreen);
+
+	is_mobile = is_narrow || is_mobile_landscape;
+
+	hdy_flap_set_fold_policy (HDY_FLAP (priv->flap),
+				  is_mobile ? HDY_FLAP_FOLD_POLICY_ALWAYS : HDY_FLAP_FOLD_POLICY_AUTO);
+	ev_toolbar_set_mobile (EV_TOOLBAR (priv->toolbar), is_mobile);
+}
+
 static gboolean
 window_configure_event_cb (EvWindow *window, GdkEventConfigure *event, gpointer dummy)
 {
@@ -7384,7 +7399,9 @@ ev_window_init (EvWindow *ev_window)
 	GtkBuilder *builder;
 	GError *error = NULL;
 	GtkWidget *sidebar_widget;
+	GtkWidget *separator;
 	GtkWidget *overlay;
+	GtkWidget *clamp;
 	GtkWidget *searchbar_revealer;
 	GObject *mpkeys;
 	guint page_cache_mb;
@@ -7401,6 +7418,8 @@ ev_window_init (EvWindow *ev_window)
 			  G_CALLBACK (window_configure_event_cb), NULL);
 	g_signal_connect (ev_window, "window_state_event",
 			  G_CALLBACK (window_state_event_cb), NULL);
+	g_signal_connect (ev_window, "size-allocate",
+			  G_CALLBACK (window_size_allocate_cb), NULL);
 
 	priv = GET_PRIVATE (ev_window);
 
@@ -7494,13 +7513,15 @@ ev_window_init (EvWindow *ev_window)
 			    priv->annots_toolbar, FALSE, TRUE, 0);
 
 	/* Search Bar */
-	priv->search_bar = gtk_search_bar_new ();
+	priv->search_bar = hdy_search_bar_new ();
+
+	clamp = hdy_clamp_new ();
+	gtk_container_add (GTK_CONTAINER (priv->search_bar), clamp);
+	gtk_widget_show (clamp);
 
 	priv->search_box = ev_search_box_new (priv->model);
 	search_entry = GTK_ENTRY (ev_search_box_get_entry (EV_SEARCH_BOX (priv->search_box)));
-	gtk_entry_set_width_chars (search_entry, 32);
-	gtk_entry_set_max_length (search_entry, 512);
-	gtk_container_add (GTK_CONTAINER (priv->search_bar),
+	gtk_container_add (GTK_CONTAINER (clamp),
 			   priv->search_box);
 	gtk_widget_show (priv->search_box);
 
@@ -7514,7 +7535,7 @@ ev_window_init (EvWindow *ev_window)
 	gtk_container_add (GTK_CONTAINER (searchbar_revealer), priv->search_bar);
 	gtk_widget_show (GTK_WIDGET (searchbar_revealer));
 
-	/* We don't use gtk_search_bar_connect_entry, because it clears the entry when the
+	/* We don't use hdy_search_bar_connect_entry, because it clears the entry when the
 	 * search is closed, but we want to keep the current search.
 	 */
 	gtk_box_pack_start (GTK_BOX (priv->main_box),
@@ -7522,22 +7543,26 @@ ev_window_init (EvWindow *ev_window)
 	gtk_widget_show (priv->search_bar);
 
 	/* Add the main area */
-	priv->hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
-	g_signal_connect (priv->hpaned,
-			  "notify::position",
-			  G_CALLBACK (ev_window_sidebar_position_change_cb),
-			  ev_window);
-	
-	gtk_paned_set_position (GTK_PANED (priv->hpaned), SIDEBAR_DEFAULT_SIZE);
-	gtk_box_pack_start (GTK_BOX (priv->main_box), priv->hpaned,
+	priv->flap = hdy_flap_new ();
+	hdy_flap_set_swipe_to_open (HDY_FLAP (priv->flap), FALSE);
+	hdy_flap_set_locked (HDY_FLAP (priv->flap), TRUE);
+	gtk_box_pack_start (GTK_BOX (priv->main_box), priv->flap,
 			    TRUE, TRUE, 0);
-	gtk_widget_show (priv->hpaned);
+	gtk_widget_show (priv->flap);
 	
+	priv->sidebar_stack = gtk_stack_new ();
+	hdy_flap_set_flap (HDY_FLAP (priv->flap), priv->sidebar_stack);
+	gtk_widget_set_size_request (priv->sidebar_stack, SIDEBAR_DEFAULT_SIZE, -1);
+	gtk_widget_set_hexpand (priv->sidebar_stack, FALSE);
+	gtk_widget_set_hexpand_set (priv->sidebar_stack, TRUE);
+	gtk_style_context_add_class (gtk_widget_get_style_context (priv->sidebar_stack),
+	                             "background");
+	gtk_widget_show (priv->sidebar_stack);
+
 	priv->sidebar = ev_sidebar_new ();
 	ev_sidebar_set_model (EV_SIDEBAR (priv->sidebar),
 			      priv->model);
-	gtk_paned_pack1 (GTK_PANED (priv->hpaned),
-			 priv->sidebar, FALSE, FALSE);
+	gtk_container_add (GTK_CONTAINER (priv->sidebar_stack), priv->sidebar);
 	gtk_widget_show (priv->sidebar);
 
 	/* Stub sidebar, for now */
@@ -7620,6 +7645,10 @@ ev_window_init (EvWindow *ev_window)
 			      LAYERS_SIDEBAR_ID, _("Layers"),
 			      LAYERS_SIDEBAR_ICON);
 
+	separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
+	hdy_flap_set_separator (HDY_FLAP (priv->flap), separator);
+	gtk_widget_show (separator);
+
 	priv->view_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
 
 	overlay = gtk_overlay_new ();
@@ -7639,8 +7668,10 @@ ev_window_init (EvWindow *ev_window)
 			    TRUE, TRUE, 0);
 	gtk_widget_show (overlay);
 
-	gtk_paned_add2 (GTK_PANED (priv->hpaned),
-			priv->view_box);
+	hdy_flap_set_content (HDY_FLAP (priv->flap), priv->view_box);
+	hdy_flap_set_reveal_flap (HDY_FLAP (priv->flap), FALSE);
+	gtk_widget_set_size_request (priv->view_box, 360, -1);
+	gtk_widget_set_hexpand (priv->view_box, TRUE);
 	gtk_widget_show (priv->view_box);
 
 	priv->view = ev_view_new ();
@@ -7712,6 +7743,8 @@ ev_window_init (EvWindow *ev_window)
 			  "result-activated",
 			  G_CALLBACK (find_sidebar_result_activated_cb),
 			  ev_window);
+	gtk_container_add (GTK_CONTAINER (priv->sidebar_stack), priv->find_sidebar);
+	gtk_widget_show (priv->find_sidebar);
 
 	/* We own a ref on these widgets, as we can swap them in and out */
 	g_object_ref (priv->view);
@@ -7763,10 +7796,10 @@ ev_window_init (EvWindow *ev_window)
 			  ev_window);
 
      	/* Connect sidebar signals */
-	g_signal_connect (priv->sidebar,
-			  "notify::visible",
-			  G_CALLBACK (ev_window_sidebar_visibility_changed_cb),
-			  ev_window);
+	g_signal_connect_swapped (priv->flap,
+	                          "notify::reveal-flap",
+	                          G_CALLBACK (flap_reveal_changed_cb),
+	                          ev_window);
 	g_signal_connect (priv->sidebar,
 			  "notify::current-page",
 			  G_CALLBACK (ev_window_sidebar_current_page_changed_cb),
@@ -7995,5 +8028,5 @@ ev_window_set_divider_position (EvWindow *ev_window,
 
 	priv = GET_PRIVATE (ev_window);
 
-	gtk_paned_set_position (GTK_PANED (priv->hpaned), sidebar_width);
+	gtk_widget_set_size_request (priv->sidebar_stack, sidebar_width, -1);
 }
