xed-window: Rework the fullscreen toolbar

The animation used for hiding/showing the fullscreen toolbar is totally broken
under HiDPI. Port to GtkRevealer and GtkEventBox to get the proper behaviour.
This commit is contained in:
JosephMcc 2017-12-04 00:46:02 -08:00
parent bc18f166a3
commit 78ca6d13e0
2 changed files with 44 additions and 168 deletions

View File

@ -66,9 +66,9 @@ struct _XedWindowPrivate
/* Widgets for fullscreen mode */ /* Widgets for fullscreen mode */
GtkWidget *fullscreen_controls; GtkWidget *fullscreen_controls;
GtkWidget *fullscreen_controls_container; GtkWidget *fullscreen_overlay;
guint fullscreen_animation_timeout_id; GtkWidget *fullscreen_eventbox;
gboolean fullscreen_animation_enter; GtkWidget *fullscreen_revealer;
/* statusbar and context ids for statusbar messages */ /* statusbar and context ids for statusbar messages */
GtkWidget *statusbar; GtkWidget *statusbar;

View File

@ -35,8 +35,6 @@
#define TAB_WIDTH_DATA "XedWindowTabWidthData" #define TAB_WIDTH_DATA "XedWindowTabWidthData"
#define LANGUAGE_DATA "XedWindowLanguageData" #define LANGUAGE_DATA "XedWindowLanguageData"
#define FULLSCREEN_ANIMATION_SPEED 4
#define XED_WINDOW_DEFAULT_WIDTH 650 #define XED_WINDOW_DEFAULT_WIDTH 650
#define XED_WINDOW_DEFAULT_HEIGHT 500 #define XED_WINDOW_DEFAULT_HEIGHT 500
@ -207,18 +205,6 @@ xed_window_dispose (GObject *object)
window->priv->dispose_has_run = TRUE; window->priv->dispose_has_run = TRUE;
} }
if (window->priv->fullscreen_animation_timeout_id != 0)
{
g_source_remove (window->priv->fullscreen_animation_timeout_id);
window->priv->fullscreen_animation_timeout_id = 0;
}
if (window->priv->fullscreen_controls != NULL)
{
gtk_widget_destroy (window->priv->fullscreen_controls);
window->priv->fullscreen_controls = NULL;
}
if (window->priv->recents_handler_id != 0) if (window->priv->recents_handler_id != 0)
{ {
GtkRecentManager *recent_manager; GtkRecentManager *recent_manager;
@ -2636,143 +2622,22 @@ drop_uris_cb (GtkWidget *widget,
load_uris_from_drop (window, uri_list); load_uris_from_drop (window, uri_list);
} }
static void
fullscreen_controls_show (XedWindow *window)
{
GdkScreen *screen;
GdkRectangle fs_rect;
gint min_h, nat_h;
screen = gtk_window_get_screen (GTK_WINDOW (window));
gdk_screen_get_monitor_geometry (
screen, gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET(window))),
&fs_rect);
gtk_widget_get_preferred_height (window->priv->fullscreen_controls_container, &min_h, &nat_h);
gtk_window_resize (GTK_WINDOW (window->priv->fullscreen_controls), fs_rect.width, nat_h);
gtk_window_move (GTK_WINDOW (window->priv->fullscreen_controls), fs_rect.x, fs_rect.y - nat_h + 1);
gtk_widget_show_all (window->priv->fullscreen_controls);
}
static gboolean static gboolean
run_fullscreen_animation (gpointer data) on_fullscreen_controls_enter_notify_event (GtkWidget *widget,
{
XedWindow *window = XED_WINDOW(data);
GdkScreen *screen;
GdkRectangle fs_rect;
gint x, y;
screen = gtk_window_get_screen (GTK_WINDOW(window));
gdk_screen_get_monitor_geometry (screen,
gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET(window))),
&fs_rect);
gtk_window_get_position (GTK_WINDOW(window->priv->fullscreen_controls), &x, &y);
if (window->priv->fullscreen_animation_enter)
{
if (y == fs_rect.y)
{
window->priv->fullscreen_animation_timeout_id = 0;
return FALSE;
}
else
{
gtk_window_move (GTK_WINDOW(window->priv->fullscreen_controls), x, y + 1);
return TRUE;
}
}
else
{
gint w, h;
gtk_window_get_size (GTK_WINDOW(window->priv->fullscreen_controls), &w, &h);
if (y == fs_rect.y - h + 1)
{
window->priv->fullscreen_animation_timeout_id = 0;
return FALSE;
}
else
{
gtk_window_move (GTK_WINDOW(window->priv->fullscreen_controls), x, y - 1);
return TRUE;
}
}
}
static void
show_hide_fullscreen_toolbar (XedWindow *window,
gboolean show,
gint height)
{
GtkSettings *settings;
gboolean enable_animations;
settings = gtk_widget_get_settings (GTK_WIDGET(window));
g_object_get (G_OBJECT(settings), "gtk-enable-animations", &enable_animations, NULL);
if (enable_animations)
{
window->priv->fullscreen_animation_enter = show;
if (window->priv->fullscreen_animation_timeout_id == 0)
{
window->priv->fullscreen_animation_timeout_id = g_timeout_add (FULLSCREEN_ANIMATION_SPEED,
(GSourceFunc) run_fullscreen_animation, window);
}
}
else
{
GdkRectangle fs_rect;
GdkScreen *screen;
screen = gtk_window_get_screen (GTK_WINDOW(window));
gdk_screen_get_monitor_geometry (screen,
gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET(window))),
&fs_rect);
if (show)
{
gtk_window_move (GTK_WINDOW(window->priv->fullscreen_controls), fs_rect.x, fs_rect.y);
}
else
{
gtk_window_move (GTK_WINDOW(window->priv->fullscreen_controls), fs_rect.x, fs_rect.y - height + 1);
}
}
}
static gboolean
on_fullscreen_controls_enter_notify_event (GtkWidget *widget,
GdkEventCrossing *event, GdkEventCrossing *event,
XedWindow *window) XedWindow *window)
{ {
show_hide_fullscreen_toolbar (window, TRUE, 0); gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls), TRUE);
return FALSE; return FALSE;
} }
static gboolean static gboolean
on_fullscreen_controls_leave_notify_event (GtkWidget *widget, on_fullscreen_controls_leave_notify_event (GtkWidget *widget,
GdkEventCrossing *event, GdkEventCrossing *event,
XedWindow *window) XedWindow *window)
{ {
GdkDisplay *display; gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls), FALSE);
GdkScreen *screen;
gint w, h;
gint x, y;
display = gdk_display_get_default ();
screen = gtk_window_get_screen (GTK_WINDOW(window));
gtk_window_get_size (GTK_WINDOW(window->priv->fullscreen_controls), &w, &h);
gdk_display_get_pointer (display, &screen, &x, &y, NULL);
/* gtk seems to emit leave notify when clicking on tool items,
* work around it by checking the coordinates
*/
if (y >= h)
{
show_hide_fullscreen_toolbar (window, FALSE, h);
}
return FALSE; return FALSE;
} }
@ -2783,6 +2648,9 @@ fullscreen_controls_build (XedWindow *window)
XedWindowPrivate *priv = window->priv; XedWindowPrivate *priv = window->priv;
GtkAction *action; GtkAction *action;
GtkWidget *box; GtkWidget *box;
GtkWidget *toolbar;
GtkWidget *toolitem;
GtkWidget *toolbox;
GtkWidget *fullscreen_btn; GtkWidget *fullscreen_btn;
GtkWidget *separator; GtkWidget *separator;
GtkWidget *button; GtkWidget *button;
@ -2792,17 +2660,23 @@ fullscreen_controls_build (XedWindow *window)
return; return;
} }
priv->fullscreen_controls = gtk_window_new (GTK_WINDOW_POPUP); priv->fullscreen_controls = gtk_revealer_new ();
gtk_widget_set_valign (priv->fullscreen_controls, GTK_ALIGN_START);
gtk_container_add (GTK_CONTAINER (priv->fullscreen_eventbox), priv->fullscreen_controls);
gtk_window_set_transient_for (GTK_WINDOW (priv->fullscreen_controls), GTK_WINDOW (&window->window)); toolbar = gtk_toolbar_new ();
toolitem = gtk_tool_item_new ();
gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (toolitem), 0);
window->priv->fullscreen_controls_container = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); toolbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_set_border_width (GTK_CONTAINER (window->priv->fullscreen_controls_container), 6); gtk_style_context_add_class (gtk_widget_get_style_context (toolbar), "primary-toolbar");
gtk_container_add (GTK_CONTAINER (priv->fullscreen_controls), window->priv->fullscreen_controls_container); gtk_container_add (GTK_CONTAINER (toolitem), toolbox);
gtk_container_add (GTK_CONTAINER (priv->fullscreen_controls), toolbar);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_vexpand (box, FALSE); gtk_widget_set_vexpand (box, FALSE);
gtk_box_pack_start (GTK_BOX (window->priv->fullscreen_controls_container), box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (toolbox), box, FALSE, FALSE, 0);
action = gtk_action_group_get_action (window->priv->always_sensitive_action_group, "FileNew"); action = gtk_action_group_get_action (window->priv->always_sensitive_action_group, "FileNew");
button = create_toolbar_button (action); button = create_toolbar_button (action);
@ -2858,13 +2732,15 @@ fullscreen_controls_build (XedWindow *window)
fullscreen_btn = create_toolbar_button (action); fullscreen_btn = create_toolbar_button (action);
gtk_box_pack_end (GTK_BOX (box), fullscreen_btn, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (box), fullscreen_btn, FALSE, FALSE, 0);
gtk_widget_show_all (window->priv->fullscreen_controls_container); gtk_widget_show_all (toolbox);
g_signal_connect(priv->fullscreen_controls, "enter-notify-event", g_signal_connect (priv->fullscreen_eventbox, "enter-notify-event",
G_CALLBACK (on_fullscreen_controls_enter_notify_event), window); G_CALLBACK (on_fullscreen_controls_enter_notify_event), window);
g_signal_connect(priv->fullscreen_controls, "leave-notify-event", g_signal_connect (priv->fullscreen_eventbox, "leave-notify-event",
G_CALLBACK (on_fullscreen_controls_leave_notify_event), window); G_CALLBACK (on_fullscreen_controls_leave_notify_event), window);
gtk_widget_set_size_request (priv->fullscreen_eventbox, -1, 1);
} }
static void static void
@ -3531,14 +3407,7 @@ check_window_is_active (XedWindow *window,
{ {
if (window->priv->window_state & GDK_WINDOW_STATE_FULLSCREEN) if (window->priv->window_state & GDK_WINDOW_STATE_FULLSCREEN)
{ {
if (gtk_window_is_active (GTK_WINDOW(window))) gtk_widget_set_visible (window->priv->fullscreen_eventbox, gtk_window_is_active (GTK_WINDOW (window)));
{
gtk_widget_show (window->priv->fullscreen_controls);
}
else
{
gtk_widget_hide (window->priv->fullscreen_controls);
}
} }
} }
@ -3606,7 +3475,6 @@ xed_window_init (XedWindow *window)
window->priv->inhibition_cookie = 0; window->priv->inhibition_cookie = 0;
window->priv->dispose_has_run = FALSE; window->priv->dispose_has_run = FALSE;
window->priv->fullscreen_controls = NULL; window->priv->fullscreen_controls = NULL;
window->priv->fullscreen_animation_timeout_id = 0;
window->priv->editor_settings = g_settings_new ("org.x.editor.preferences.editor"); window->priv->editor_settings = g_settings_new ("org.x.editor.preferences.editor");
window->priv->ui_settings = g_settings_new ("org.x.editor.preferences.ui"); window->priv->ui_settings = g_settings_new ("org.x.editor.preferences.ui");
@ -3623,9 +3491,16 @@ xed_window_init (XedWindow *window)
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), "xed-window"); gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), "xed-window");
main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), main_box); window->priv->fullscreen_overlay = gtk_overlay_new ();
gtk_container_add (GTK_CONTAINER (window->priv->fullscreen_overlay), main_box);
gtk_container_add (GTK_CONTAINER (window), window->priv->fullscreen_overlay);
gtk_widget_show (window->priv->fullscreen_overlay);
gtk_widget_show (main_box); gtk_widget_show (main_box);
window->priv->fullscreen_eventbox = gtk_event_box_new ();
gtk_widget_set_valign (window->priv->fullscreen_eventbox, GTK_ALIGN_START);
gtk_overlay_add_overlay (GTK_OVERLAY (window->priv->fullscreen_overlay), window->priv->fullscreen_eventbox);
/* Add menu bar and toolbar bar */ /* Add menu bar and toolbar bar */
create_menu_bar_and_toolbar (window, main_box); create_menu_bar_and_toolbar (window, main_box);
@ -4324,7 +4199,8 @@ _xed_window_fullscreen (XedWindow *window)
gtk_widget_hide (window->priv->statusbar); gtk_widget_hide (window->priv->statusbar);
fullscreen_controls_build (window); fullscreen_controls_build (window);
fullscreen_controls_show (window);
gtk_widget_show_all (window->priv->fullscreen_eventbox);
} }
void void
@ -4361,7 +4237,7 @@ _xed_window_unfullscreen (XedWindow *window)
} }
g_signal_handlers_unblock_by_func (window->priv->statusbar, statusbar_visibility_changed, window); g_signal_handlers_unblock_by_func (window->priv->statusbar, statusbar_visibility_changed, window);
gtk_widget_hide (window->priv->fullscreen_controls); gtk_widget_hide (window->priv->fullscreen_eventbox);
} }
gboolean gboolean