From: Adrien Plazas 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 d8970e3..93ce02c 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; @@ -264,7 +265,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" @@ -294,9 +295,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, @@ -667,7 +665,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 @@ -1280,15 +1279,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); } @@ -1583,10 +1578,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")); @@ -1705,7 +1696,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 G_SOURCE_REMOVE; @@ -2023,7 +2014,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); @@ -2536,7 +2527,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, @@ -2565,7 +2556,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 @@ -4099,9 +4090,7 @@ ev_window_save_settings (EvWindow *ev_window) 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", @@ -4536,7 +4525,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 */ @@ -4565,7 +4554,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 */ @@ -4586,18 +4575,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) { @@ -4805,7 +4782,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); @@ -4840,7 +4817,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)); @@ -5208,7 +5185,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); @@ -5463,14 +5440,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)); @@ -5480,6 +5455,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); } } @@ -5829,12 +5808,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); @@ -5858,7 +5837,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; } @@ -5874,13 +5854,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)); @@ -5898,17 +5875,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)); @@ -6514,6 +6487,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) { @@ -7409,7 +7424,9 @@ ev_window_init (EvWindow *ev_window) GtkBuilder *builder; GError *error = NULL; GtkWidget *sidebar_widget; + GtkWidget *separator; GtkWidget *overlay; + GtkWidget *clamp; GObject *mpkeys; guint page_cache_mb; gboolean allow_links_change_zoom; @@ -7425,6 +7442,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); @@ -7512,17 +7531,19 @@ 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); - /* 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), @@ -7530,22 +7551,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 */ @@ -7628,6 +7653,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 (); @@ -7647,8 +7676,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 (); @@ -7734,6 +7765,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); @@ -7785,10 +7818,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), @@ -7969,5 +8002,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); }