...
 
Commits (16)
==============
Version 3.30.2
==============
Changes in this release:
• Fix build dependency to properly check for gtk+ >= 3.24. This was already
necessary at runtime, as subtle bugs would have occurred with older
releases.
• app-window now uses GtkEventControllerMotion to provide improved tracking
of the app window fullscreen toolbar.
• Shortcut placement was tweaked in menu popover
• Fixes for shift+tab and ctrl+shift+d keyboard shortcuts
• Various build fixes for -Bsymbolic and assertions
==============
Version 3.30.1
==============
......
libdazzle (3.30.2-1) unstable; urgency=medium
* New upstream release
* debian/control.in:
- updated gtk requirement
-- Sebastien Bacher <seb128@ubuntu.com> Tue, 13 Nov 2018 11:06:48 +0100
libdazzle (3.30.1-2) unstable; urgency=medium
* Use xvfb-run -a since it is helpful on some buildds
......
......@@ -15,7 +15,7 @@ Build-Depends: at-spi2-core <!nocheck>,
gtk-doc-tools,
libgirepository1.0-dev,
libglib2.0-dev (>= 2.56.0),
libgtk-3-dev,
libgtk-3-dev (>= 3.24),
meson,
wamerican <!nocheck>,
xauth <!nocheck>,
......
......@@ -11,7 +11,7 @@ Build-Depends: at-spi2-core <!nocheck>,
gtk-doc-tools,
libgirepository1.0-dev,
libglib2.0-dev (>= 2.56.0),
libgtk-3-dev,
libgtk-3-dev (>= 3.24),
meson,
wamerican <!nocheck>,
xauth <!nocheck>,
......
project('libdazzle', 'c',
version: '3.30.1',
version: '3.30.2',
license: 'GPLv3+',
meson_version: '>= 0.40.1',
default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ],
......@@ -128,6 +128,28 @@ endif
add_project_arguments(global_c_args, language: 'c')
release_args = []
global_link_args = []
test_link_args = [
'-Wl,-z,relro',
'-Wl,-z,now',
]
if not get_option('buildtype').startswith('debug')
# TODO: Maybe reuse 'b_ndebug' option
add_global_arguments(['-DG_DISABLE_CAST_CHECKS'], language: 'c')
release_args += [ '-DG_DISABLE_ASSERT' ]
test_link_args += [
'-Wl,-Bsymbolic',
'-fno-plt',
]
endif
foreach link_arg: test_link_args
if cc.links('int main () { return 0; }', name: link_arg, args: link_arg)
global_link_args += link_arg
endif
endforeach
add_project_link_arguments(global_link_args, language: 'c')
# Setup various paths that subdirectory meson.build files need
package_subdir = get_option('package_subdir') # When used as subproject
libdir = join_paths(get_option('libdir'), package_subdir)
......
......@@ -48,10 +48,10 @@ typedef struct
{
GtkStack *titlebar_container;
GtkRevealer *titlebar_revealer;
GtkEventBox *event_box;
GtkOverlay *overlay;
gulong motion_notify_handler;
GtkEventController *motion_controller;
gulong motion_controller_handler;
guint fullscreen_source;
guint fullscreen_reveal_source;
......@@ -128,20 +128,17 @@ revealer_set_reveal_child_now (GtkRevealer *revealer,
gtk_revealer_set_transition_type (revealer, GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN);
}
static gboolean
dzl_application_window_event_box_motion (DzlApplicationWindow *self,
GdkEventMotion *motion,
GtkEventBox *event_box)
static void
dzl_application_window_motion_cb (DzlApplicationWindow *self,
gdouble x,
gdouble y,
GtkEventControllerMotion *controller)
{
DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
GtkWidget *widget = NULL;
GtkWidget *focus;
gint x = 0;
gint y = 0;
g_assert (DZL_IS_APPLICATION_WINDOW (self));
g_assert (motion != NULL);
g_assert (GTK_IS_EVENT_BOX (event_box));
g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (controller));
/*
* If we are focused in the revealer, ignore this. We will have already
......@@ -150,28 +147,17 @@ dzl_application_window_event_box_motion (DzlApplicationWindow *self,
focus = gtk_window_get_focus (GTK_WINDOW (self));
if (focus != NULL &&
dzl_gtk_widget_is_ancestor_or_relative (focus, GTK_WIDGET (priv->titlebar_revealer)))
return GDK_EVENT_PROPAGATE;
/* The widget is stored in GdkWindow user_data */
gdk_window_get_user_data (motion->window, (gpointer *)&widget);
if (widget == NULL)
return GDK_EVENT_PROPAGATE;
return;
/* If the headerbar is underneath the pointer or we are within a
* small distance of the edge of the window (and monitor), ensure
* that the titlebar is displayed and queue our next dismissal.
*/
if (dzl_gtk_widget_is_ancestor_or_relative (widget, GTK_WIDGET (priv->titlebar_revealer)) ||
gtk_widget_translate_coordinates (widget, GTK_WIDGET (self), motion->x, motion->y, &x, &y))
if (y <= SHOW_HEADER_WITHIN_DISTANCE)
{
if (y < SHOW_HEADER_WITHIN_DISTANCE)
{
gtk_revealer_set_reveal_child (priv->titlebar_revealer, TRUE);
dzl_application_window_queue_dismissal (self);
}
gtk_revealer_set_reveal_child (priv->titlebar_revealer, TRUE);
dzl_application_window_queue_dismissal (self);
}
return GDK_EVENT_PROPAGATE;
}
static gboolean
......@@ -205,7 +191,7 @@ dzl_application_window_complete_fullscreen (DzlApplicationWindow *self)
if (priv->fullscreen)
{
/* Only listen for motion notify events while in fullscreen mode. */
g_signal_handler_unblock (priv->event_box, priv->motion_notify_handler);
gtk_event_controller_set_propagation_phase (priv->motion_controller, GTK_PHASE_CAPTURE);
if (titlebar && gtk_widget_is_ancestor (titlebar, GTK_WIDGET (priv->titlebar_container)))
{
......@@ -219,7 +205,7 @@ dzl_application_window_complete_fullscreen (DzlApplicationWindow *self)
else
{
/* Motion events are no longer needed */
g_signal_handler_block (priv->event_box, priv->motion_notify_handler);
gtk_event_controller_set_propagation_phase (priv->motion_controller, GTK_PHASE_NONE);
if (gtk_widget_is_ancestor (titlebar, GTK_WIDGET (priv->titlebar_revealer)))
{
......@@ -245,11 +231,7 @@ dzl_application_window_real_set_fullscreen (DzlApplicationWindow *self,
priv->fullscreen = fullscreen;
if (priv->fullscreen_source != 0)
{
g_source_remove (priv->fullscreen_source);
priv->fullscreen_source = 0;
}
dzl_clear_source (&priv->fullscreen_source);
if (priv->fullscreen)
{
......@@ -308,11 +290,7 @@ dzl_application_window_set_focus (GtkWindow *window,
if (dzl_gtk_widget_is_ancestor_or_relative (widget, GTK_WIDGET (priv->titlebar_revealer)))
{
/* Disable transition while the revealer is focused */
if (priv->fullscreen_reveal_source != 0)
{
g_source_remove (priv->fullscreen_reveal_source);
priv->fullscreen_reveal_source = 0;
}
dzl_clear_source (&priv->fullscreen_reveal_source);
/* If this was just focused, we might need to make it visible */
gtk_revealer_set_reveal_child (priv->titlebar_revealer, TRUE);
......@@ -323,11 +301,7 @@ dzl_application_window_set_focus (GtkWindow *window,
* the titlebar immediately to get out of the users way.
*/
gtk_revealer_set_reveal_child (priv->titlebar_revealer, FALSE);
if (priv->fullscreen_reveal_source != 0)
{
g_source_remove (priv->fullscreen_reveal_source);
priv->fullscreen_reveal_source = 0;
}
dzl_clear_source (&priv->fullscreen_reveal_source);
}
}
}
......@@ -342,7 +316,7 @@ dzl_application_window_add (GtkContainer *container,
g_assert (DZL_IS_APPLICATION_WINDOW (self));
g_assert (GTK_IS_WIDGET (widget));
gtk_container_add (GTK_CONTAINER (priv->event_box), widget);
gtk_container_add (GTK_CONTAINER (priv->overlay), widget);
}
static gboolean
......@@ -367,6 +341,29 @@ dzl_application_window_key_press_event (GtkWidget *widget,
return ret;
}
static gboolean
dzl_application_window_window_state_event (GtkWidget *widget,
GdkEventWindowState *event)
{
DzlApplicationWindow *self = (DzlApplicationWindow *)widget;
DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
gboolean ret;
g_assert (DZL_IS_APPLICATION_WINDOW (self));
g_assert (event != NULL);
ret = GTK_WIDGET_CLASS (dzl_application_window_parent_class)->window_state_event (widget, event);
/* Clear our fullscreen state if the window-manager un-fullscreened us.
* This fixes an issue on gnome 3.30 (and other window managers) that can
* clear the fullscreen state out from under the app.
*/
if (priv->fullscreen && (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) == 0)
dzl_application_window_set_fullscreen (self, FALSE);
return ret;
}
static void
dzl_application_window_destroy (GtkWidget *widget)
{
......@@ -375,15 +372,10 @@ dzl_application_window_destroy (GtkWidget *widget)
g_assert (DZL_IS_APPLICATION_WINDOW (self));
if (priv->event_box != NULL)
{
g_signal_handler_disconnect (priv->event_box, priv->motion_notify_handler);
priv->motion_notify_handler = 0;
}
g_clear_object (&priv->motion_controller);
g_clear_pointer ((GtkWidget **)&priv->titlebar_container, gtk_widget_destroy);
g_clear_pointer ((GtkWidget **)&priv->titlebar_revealer, gtk_widget_destroy);
g_clear_pointer ((GtkWidget **)&priv->event_box, gtk_widget_destroy);
g_clear_pointer ((GtkWidget **)&priv->overlay, gtk_widget_destroy);
dzl_clear_source (&priv->fullscreen_source);
......@@ -443,6 +435,7 @@ dzl_application_window_class_init (DzlApplicationWindowClass *klass)
widget_class->destroy = dzl_application_window_destroy;
widget_class->key_press_event = dzl_application_window_key_press_event;
widget_class->window_state_event = dzl_application_window_window_state_event;
container_class->add = dzl_application_window_add;
......@@ -490,6 +483,7 @@ dzl_application_window_init (DzlApplicationWindow *self)
priv->overlay = g_object_new (GTK_TYPE_OVERLAY,
"visible", TRUE,
NULL);
gtk_widget_set_events (GTK_WIDGET (priv->overlay), GDK_POINTER_MOTION_MASK);
g_signal_connect (priv->overlay,
"destroy",
G_CALLBACK (gtk_widget_destroyed),
......@@ -497,23 +491,13 @@ dzl_application_window_init (DzlApplicationWindow *self)
GTK_CONTAINER_CLASS (dzl_application_window_parent_class)->add (GTK_CONTAINER (self),
GTK_WIDGET (priv->overlay));
priv->event_box = g_object_new (GTK_TYPE_EVENT_BOX,
"above-child", FALSE,
"visible", TRUE,
"visible-window", TRUE,
NULL);
gtk_widget_set_events (GTK_WIDGET (priv->event_box), GDK_POINTER_MOTION_MASK);
g_signal_connect (priv->event_box,
"destroy",
G_CALLBACK (gtk_widget_destroyed),
&priv->event_box);
priv->motion_notify_handler =
g_signal_connect_swapped (priv->event_box,
"motion-notify-event",
G_CALLBACK (dzl_application_window_event_box_motion),
priv->motion_controller = gtk_event_controller_motion_new (GTK_WIDGET (priv->overlay));
priv->motion_controller_handler =
g_signal_connect_swapped (priv->motion_controller,
"motion",
G_CALLBACK (dzl_application_window_motion_cb),
self);
g_signal_handler_block (priv->event_box, priv->motion_notify_handler);
gtk_container_add (GTK_CONTAINER (priv->overlay), GTK_WIDGET (priv->event_box));
gtk_event_controller_set_propagation_phase (priv->motion_controller, GTK_PHASE_NONE);
priv->titlebar_revealer = g_object_new (GTK_TYPE_REVEALER,
"valign", GTK_ALIGN_START,
......
......@@ -86,7 +86,7 @@ libdazzle_sources = [
libdazzle_deps = [
dependency('gio-2.0', version: '>=2.56.0'),
dependency('gmodule-2.0'),
dependency('gtk+-3.0'),
dependency('gtk+-3.0', version: '>=3.24.0'),
cc.find_library('m', required: false),
cc.find_library('rt', required: false),
]
......@@ -102,7 +102,7 @@ libdazzle = shared_library(
libdazzle_sources,
soversion: 0,
c_args: libdazzle_args,
c_args: libdazzle_args + release_args,
dependencies: libdazzle_deps,
include_directories: [ root_inc, src_inc ],
install: true,
......
......@@ -812,6 +812,9 @@ dzl_shortcut_manager_run_fallbacks (DzlShortcutManager *self,
const DzlShortcutChord *chord)
{
DzlShortcutManagerPrivate *priv = dzl_shortcut_manager_get_instance_private (self);
static DzlShortcutChord *inspector_chord;
DZL_ENTRY;
g_assert (DZL_IS_SHORTCUT_MANAGER (self));
g_assert (GTK_IS_WIDGET (widget));
......@@ -827,14 +830,23 @@ dzl_shortcut_manager_run_fallbacks (DzlShortcutManager *self,
dzl_shortcut_chord_get_nth_key (chord, 0, &keyval, &state);
/* Special case shift-tab, which is shown as ISO_Left_Tab when
* we converted into a Dazzle chord.
*/
if (keyval == GDK_KEY_ISO_Left_Tab && state == 0)
{
if (gtk_bindings_activate (G_OBJECT (toplevel), keyval, GDK_SHIFT_MASK))
DZL_RETURN (TRUE);
}
/* See if the toplevel activates this, like Tab, etc */
if (gtk_bindings_activate (G_OBJECT (toplevel), keyval, state))
return TRUE;
DZL_RETURN (TRUE);
/* See if there is a mnemonic active that should be activated */
if (GTK_IS_WINDOW (toplevel) &&
gtk_window_mnemonic_activate (GTK_WINDOW (toplevel), keyval, state))
return TRUE;
DZL_RETURN (TRUE);
/*
* See if we have something defined for this theme that
......@@ -851,7 +863,24 @@ dzl_shortcut_manager_run_fallbacks (DzlShortcutManager *self,
dzl_g_action_name_parse_full (action, &prefix, &name, &target);
if (dzl_gtk_widget_action (toplevel, prefix, name, target))
return TRUE;
DZL_RETURN (TRUE);
}
/*
* If we this is the ctrl+shift+d keybinding to activate the inspector,
* then try to see if we should handle that manually.
*/
if G_UNLIKELY (inspector_chord == NULL)
inspector_chord = dzl_shortcut_chord_new_from_string ("<ctrl><shift>d");
if (dzl_shortcut_chord_equal (chord, inspector_chord))
{
g_autoptr(GSettings) settings = g_settings_new ("org.gtk.Settings.Debug");
if (g_settings_get_boolean (settings, "enable-inspector-keybinding"))
{
gtk_window_set_interactive_debugging (TRUE);
DZL_RETURN (TRUE);
}
}
/*
......@@ -883,13 +912,13 @@ dzl_shortcut_manager_run_fallbacks (DzlShortcutManager *self,
}
if (dzl_gtk_widget_action (widget, prefix, name, param))
return TRUE;
DZL_RETURN (TRUE);
}
}
}
}
return FALSE;
DZL_RETURN (FALSE);
}
/**
......
......@@ -180,10 +180,10 @@ dzl_shortcut_simple_label_init (DzlShortcutSimpleLabel *self)
self->accel_label = g_object_new (GTK_TYPE_LABEL,
"hexpand", TRUE,
"halign", GTK_ALIGN_START,
"halign", GTK_ALIGN_END,
"margin-start", 12,
"visible", TRUE,
"xalign", 0.0f,
"xalign", 1.0f,
NULL);
dzl_gtk_widget_add_style_class (GTK_WIDGET (self->accel_label), "dim-label");
gtk_container_add_with_properties (GTK_CONTAINER (self), GTK_WIDGET (self->accel_label),
......