Merge branch 'matthiasc/for-master' into 'master'

action muxer fixes

See merge request GNOME/gtk!3678
This commit is contained in:
Matthias Clasen 2021-06-17 17:53:16 +00:00
commit 1bda665662
18 changed files with 133 additions and 51 deletions

View File

@ -721,7 +721,6 @@ static const char ui_info[] =
" <item>"
" <attribute name='label'>_New</attribute>"
" <attribute name='action'>app.new</attribute>"
" <attribute name='accel'>&lt;Primary&gt;n</attribute>"
" </item>"
" <item>"
" <attribute name='label'>_Open</attribute>"
@ -730,12 +729,10 @@ static const char ui_info[] =
" <item>"
" <attribute name='label'>_Save</attribute>"
" <attribute name='action'>app.save</attribute>"
" <attribute name='accel'>&lt;Primary&gt;s</attribute>"
" </item>"
" <item>"
" <attribute name='label'>Save _As...</attribute>"
" <attribute name='action'>app.save-as</attribute>"
" <attribute name='accel'>&lt;Primary&gt;s</attribute>"
" </item>"
" </section>"
" <section>"
@ -756,7 +753,6 @@ static const char ui_info[] =
" <item>"
" <attribute name='label'>_Quit</attribute>"
" <attribute name='action'>app.quit</attribute>"
" <attribute name='accel'>&lt;Primary&gt;q</attribute>"
" </item>"
" </section>"
" </submenu>"
@ -766,7 +762,6 @@ static const char ui_info[] =
" <item>"
" <attribute name='label'>_About Print Editor</attribute>"
" <attribute name='action'>app.about</attribute>"
" <attribute name='accel'>&lt;Primary&gt;a</attribute>"
" </item>"
" </section>"
" </submenu>"
@ -794,6 +789,15 @@ startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *menubar;
struct {
const char *action_and_target;
const char *accelerators[2];
} accels[] = {
{ "app.new", { "<Control>n", NULL } },
{ "app.quit", { "<Control>q", NULL } },
{ "app.save", { "<Control>s", NULL } },
{ "app.about", { "<Control>a", NULL } },
};
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, ui_info, -1, NULL);
@ -802,6 +806,9 @@ startup (GApplication *app)
gtk_application_set_menubar (GTK_APPLICATION (app), menubar);
for (int i = 0; i < G_N_ELEMENTS (accels); i++)
gtk_application_set_accels_for_action (GTK_APPLICATION (app), accels[i].action_and_target, accels[i].accelerators);
g_object_unref (builder);
}

View File

@ -1997,6 +1997,7 @@ activate (GApplication *app)
const char *accelerators[2];
} accels[] = {
{ "app.about", { "F1", NULL } },
{ "app.shortcuts", { "<Control>question", NULL } },
{ "app.quit", { "<Control>q", NULL } },
{ "app.open-in", { "<Control>n", NULL } },
{ "win.dark", { "<Control>d", NULL } },

View File

@ -197,6 +197,17 @@ text_buffer_changed_cb (GtkTextBuffer *buffer,
}
}
static void
fullscreen_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
if (gtk_window_is_fullscreen (GTK_WINDOW (object)))
gtk_button_set_icon_name (GTK_BUTTON (user_data), "view-restore-symbolic");
else
gtk_button_set_icon_name (GTK_BUTTON (user_data), "view-fullscreen-symbolic");
}
static GActionEntry win_entries[] = {
{ "copy", window_copy, NULL, NULL, NULL },
{ "paste", window_paste, NULL, NULL, NULL },
@ -214,7 +225,6 @@ new_window (GApplication *app,
GtkWidget *window, *grid, *scrolled, *view;
GtkWidget *toolbar;
GtkWidget *button;
GtkWidget *sw, *box, *label;
window = gtk_application_window_new (GTK_APPLICATION (app));
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
@ -226,6 +236,7 @@ new_window (GApplication *app,
gtk_window_set_child (GTK_WINDOW (window), grid);
toolbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_add_css_class (toolbar, "toolbar");
button = gtk_toggle_button_new ();
gtk_button_set_icon_name (GTK_BUTTON (button), "format-justify-left");
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::left");
@ -241,21 +252,18 @@ new_window (GApplication *app,
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::right");
gtk_box_append (GTK_BOX (toolbar), button);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_widget_set_halign (box, GTK_ALIGN_END);
label = gtk_label_new ("Fullscreen:");
gtk_box_append (GTK_BOX (box), label);
sw = gtk_switch_new ();
gtk_widget_set_valign (sw, GTK_ALIGN_CENTER);
gtk_actionable_set_action_name (GTK_ACTIONABLE (sw), "win.fullscreen");
gtk_box_append (GTK_BOX (box), sw);
gtk_box_append (GTK_BOX (toolbar), box);
button = gtk_toggle_button_new ();
gtk_button_set_icon_name (GTK_BUTTON (button), "view-fullscreen-symbolic");
gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.fullscreen");
gtk_box_append (GTK_BOX (toolbar), button);
g_signal_connect (window, "notify::fullscreened", G_CALLBACK (fullscreen_changed), button);
gtk_grid_attach (GTK_GRID (grid), toolbar, 0, 0, 1, 1);
scrolled = gtk_scrolled_window_new ();
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (scrolled), TRUE);
view = gtk_text_view_new ();
g_object_set_data ((GObject*)window, "bloatpad-text", view);
@ -345,6 +353,7 @@ static void
combo_changed (GtkComboBox *combo,
gpointer user_data)
{
GtkDialog *dialog = user_data;
GtkEntry *entry = g_object_get_data (user_data, "entry");
const char *action;
char **accels;
@ -360,6 +369,17 @@ combo_changed (GtkComboBox *combo,
g_strfreev (accels);
gtk_editable_set_text (GTK_EDITABLE (entry), str);
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, FALSE);
}
static void
entry_changed (GtkEntry *entry,
GParamSpec *pspec,
gpointer user_data)
{
GtkDialog *dialog = user_data;
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, TRUE);
}
static void
@ -373,7 +393,7 @@ response (GtkDialog *dialog,
const char *str;
char **accels;
if (response_id == GTK_RESPONSE_CLOSE)
if (response_id == GTK_RESPONSE_CANCEL)
{
gtk_window_destroy (GTK_WINDOW (dialog));
return;
@ -389,6 +409,8 @@ response (GtkDialog *dialog,
gtk_application_set_accels_for_action (gtk_window_get_application (user_data), action, (const char **) accels);
g_strfreev (accels);
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, FALSE);
}
static void
@ -403,22 +425,41 @@ edit_accels (GSimpleAction *action,
GtkWidget *dialog;
int i;
dialog = gtk_dialog_new ();
dialog = gtk_dialog_new_with_buttons ("Accelerators",
NULL,
GTK_DIALOG_USE_HEADER_BAR,
"Close", GTK_RESPONSE_CANCEL,
"Set", GTK_RESPONSE_APPLY,
NULL);
gtk_window_set_application (GTK_WINDOW (dialog), app);
actions = gtk_application_list_action_descriptions (app);
combo = gtk_combo_box_text_new ();
g_object_set (gtk_dialog_get_content_area (GTK_DIALOG (dialog)),
"margin-top", 10,
"margin-bottom", 10,
"margin-start", 10,
"margin-end", 10,
"spacing", 10,
NULL);
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), combo);
for (i = 0; actions[i]; i++)
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), actions[i], actions[i]);
g_signal_connect (combo, "changed", G_CALLBACK (combo_changed), dialog);
entry = gtk_entry_new ();
gtk_widget_set_hexpand (entry, TRUE);
g_signal_connect (entry, "notify::text", G_CALLBACK (entry_changed), dialog);
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), entry);
gtk_dialog_add_button (GTK_DIALOG (dialog), "Close", GTK_RESPONSE_CLOSE);
gtk_dialog_add_button (GTK_DIALOG (dialog), "Set", GTK_RESPONSE_APPLY);
g_signal_connect (dialog, "response", G_CALLBACK (response), dialog);
g_object_set_data (G_OBJECT (dialog), "combo", combo);
g_object_set_data (G_OBJECT (dialog), "entry", entry);
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
gtk_widget_show (dialog);
}

View File

@ -4,5 +4,10 @@
<gresource prefix="/org/gtk/bloatpad">
<file preprocess="xml-stripblanks">gtk/menus.ui</file>
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
<file>icons/16x16/actions/format-justify-center-symbolic.symbolic.png</file>
<file>icons/16x16/actions/format-justify-left-symbolic.symbolic.png</file>
<file>icons/16x16/actions/format-justify-right-symbolic.symbolic.png</file>
<file>icons/16x16/actions/view-fullscreen-symbolic.symbolic.png</file>
<file>icons/16x16/actions/view-restore-symbolic.symbolic.png</file>
</gresource>
</gresources>

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

View File

@ -132,7 +132,6 @@ activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *frame;
GtkWidget *drawing_area;
GtkGesture *drag;
GtkGesture *press;
@ -142,14 +141,11 @@ activate (GtkApplication *app,
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
frame = gtk_frame_new (NULL);
gtk_window_set_child (GTK_WINDOW (window), frame);
drawing_area = gtk_drawing_area_new ();
/* set a minimum size */
gtk_widget_set_size_request (drawing_area, 100, 100);
gtk_frame_set_child (GTK_FRAME (frame), drawing_area);
gtk_window_set_child (GTK_WINDOW (window), drawing_area);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), draw_cb, NULL, NULL);

View File

@ -12,7 +12,7 @@ new_window (GApplication *app,
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (window), TRUE);
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
gtk_window_set_title (GTK_WINDOW (window), "Sunny");
gtk_window_set_icon_name (GTK_WINDOW (window), "sunny");
gtk_window_set_icon_name (GTK_WINDOW (window), "weather-clear-symbolic");
header = gtk_header_bar_new ();
gtk_window_set_titlebar (GTK_WINDOW (window), header);
@ -78,7 +78,7 @@ show_about (GSimpleAction *action,
gtk_show_about_dialog (NULL,
"program-name", "Sunny",
"title", "About Sunny",
"logo-icon-name", "sunny",
"logo-icon-name", "weather-clear-symbolic",
"comments", "A cheap Bloatpad clone.",
NULL);
}

View File

@ -443,10 +443,9 @@ notify_observers_added (GtkActionMuxer *muxer,
if (!action->watchers)
continue;
if (action_muxer_query_action (muxer, action_name,
NULL, NULL, NULL, NULL, NULL,
FALSE))
continue;
for (node = action ? action->watchers : NULL; node; node = node->next)
gtk_action_observer_primary_accel_changed (node->data, GTK_ACTION_OBSERVABLE (muxer),
action_name, NULL);
gtk_action_observable_register_observer (GTK_ACTION_OBSERVABLE (parent), action_name, GTK_ACTION_OBSERVER (muxer));
@ -967,21 +966,14 @@ gtk_action_muxer_register_observer (GtkActionObservable *observable,
if (action_muxer_query_action (muxer, name,
&enabled, &parameter_type,
NULL, NULL, &state, FALSE))
NULL, NULL, &state, TRUE))
{
gtk_action_muxer_action_added (muxer, name, parameter_type, enabled, state);
g_clear_pointer (&state, g_variant_unref);
}
else if (muxer->parent)
{
if (action_muxer_query_action (muxer->parent, name,
&enabled, &parameter_type,
NULL, NULL, &state, FALSE))
{
gtk_action_muxer_action_added (muxer, name, parameter_type, enabled, state);
g_clear_pointer (&state, g_variant_unref);
}
if (muxer->parent)
{
gtk_action_observable_register_observer (GTK_ACTION_OBSERVABLE (muxer->parent),
name,
GTK_ACTION_OBSERVER (muxer));
@ -1143,6 +1135,10 @@ gtk_action_muxer_observer_action_added (GtkActionObserver *observer,
gboolean enabled,
GVariant *state)
{
if (action_muxer_query_action (GTK_ACTION_MUXER (observer), action_name,
NULL, NULL, NULL, NULL, NULL, FALSE))
return;
gtk_action_muxer_action_added (GTK_ACTION_MUXER (observer),
action_name,
parameter_type,
@ -1155,6 +1151,10 @@ gtk_action_muxer_observer_action_removed (GtkActionObserver *observer,
GtkActionObservable *observable,
const char *action_name)
{
if (action_muxer_query_action (GTK_ACTION_MUXER (observer), action_name,
NULL, NULL, NULL, NULL, NULL, FALSE))
return;
gtk_action_muxer_action_removed (GTK_ACTION_MUXER (observer), action_name);
}
@ -1164,6 +1164,10 @@ gtk_action_muxer_observer_action_enabled_changed (GtkActionObserver *observer,
const char *action_name,
gboolean enabled)
{
if (action_muxer_query_action (GTK_ACTION_MUXER (observer), action_name,
NULL, NULL, NULL, NULL, NULL, FALSE))
return;
gtk_action_muxer_action_enabled_changed (GTK_ACTION_MUXER (observer), action_name, enabled);
}
@ -1173,6 +1177,10 @@ gtk_action_muxer_observer_action_state_changed (GtkActionObserver *observer,
const char *action_name,
GVariant *state)
{
if (action_muxer_query_action (GTK_ACTION_MUXER (observer), action_name,
NULL, NULL, NULL, NULL, NULL, FALSE))
return;
gtk_action_muxer_action_state_changed (GTK_ACTION_MUXER (observer), action_name, state);
}

View File

@ -158,15 +158,17 @@ gtk_action_observer_action_removed (GtkActionObserver *observer,
* gtk_action_observer_primary_accel_changed:
* @observer: a `GtkActionObserver`
* @observable: the source of the event
* @action_name: the name of the action
* @action_and_target: detailed action of the changed accel, in action and target format
* @action_name: (nullable): the name of the action
* @action_and_target: (nullable): detailed action of the changed accel, in action and target format
*
* This function is called when an action that the observer is
* registered to receive events for has one of its accelerators changed.
*
* Accelerator changes are reported for all targets associated with the
* action. The @action_and_target string should be used to check if the
* action. The @action_and_target string should be used to check if the
* reported target is the one that the observer is interested in.
*
* Either @action_name or @action_and_target may be %NULL.
*/
void
gtk_action_observer_primary_accel_changed (GtkActionObserver *observer,

View File

@ -463,8 +463,12 @@ gtk_menu_tracker_item_primary_accel_changed (GtkActionObserver *observer,
const char *action_and_target)
{
GtkMenuTrackerItem *self = GTK_MENU_TRACKER_ITEM (observer);
const char *action;
if (g_str_equal (action_and_target, self->action_and_target))
action = strrchr (self->action_and_target, '|') + 1;
if ((action_and_target && g_str_equal (action_and_target, self->action_and_target)) ||
(action_name && g_str_equal (action_name, action)))
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_ACCEL]);
}

View File

@ -78,6 +78,7 @@
#include "gtkwidgetprivate.h"
#include "gtknative.h"
#include "gtkdebug.h"
#include "gtkmodelbuttonprivate.h"
#include <gdk/gdk.h>
@ -480,16 +481,17 @@ update_accel (GtkShortcut *shortcut,
g_free (accel);
}
static void
gtk_shortcut_controller_set_widget (GtkEventController *controller,
GtkWidget *widget)
void
gtk_shortcut_controller_update_accels (GtkShortcutController *self)
{
GtkShortcutController *self = GTK_SHORTCUT_CONTROLLER (controller);
GListModel *shortcuts = self->shortcuts;
GtkWidget *widget;
GtkActionMuxer *muxer;
guint i, p;
GTK_EVENT_CONTROLLER_CLASS (gtk_shortcut_controller_parent_class)->set_widget (controller, widget);
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (self));
if (!widget || GTK_IS_MODEL_BUTTON (widget))
return;
muxer = _gtk_widget_get_action_muxer (widget, TRUE);
for (i = 0, p = g_list_model_get_n_items (shortcuts); i < p; i++)
@ -499,6 +501,17 @@ gtk_shortcut_controller_set_widget (GtkEventController *controller,
update_accel (shortcut, muxer, TRUE);
g_object_unref (shortcut);
}
}
static void
gtk_shortcut_controller_set_widget (GtkEventController *controller,
GtkWidget *widget)
{
GtkShortcutController *self = GTK_SHORTCUT_CONTROLLER (controller);
GTK_EVENT_CONTROLLER_CLASS (gtk_shortcut_controller_parent_class)->set_widget (controller, widget);
gtk_shortcut_controller_update_accels (self);
if (_gtk_widget_get_root (widget))
gtk_shortcut_controller_root (self);

View File

@ -25,4 +25,6 @@
void gtk_shortcut_controller_root (GtkShortcutController *controller);
void gtk_shortcut_controller_unroot (GtkShortcutController *controller);
void gtk_shortcut_controller_update_accels (GtkShortcutController *self);
#endif /* __GTK_SHORTCUT_CONTROLLER_H__ */

View File

@ -54,7 +54,7 @@
#include "gtknativeprivate.h"
#include "gtksettings.h"
#include "gtkshortcut.h"
#include "gtkshortcutcontroller.h"
#include "gtkshortcutcontrollerprivate.h"
#include "gtkshortcutmanager.h"
#include "gtkshortcuttrigger.h"
#include "gtksnapshot.h"
@ -2376,6 +2376,8 @@ handle_keys_changed (gpointer data)
priv->keys_changed_handler = 0;
}
if (priv->application_shortcut_controller)
gtk_shortcut_controller_update_accels (GTK_SHORTCUT_CONTROLLER (priv->application_shortcut_controller));
g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
return FALSE;

View File

@ -318,7 +318,6 @@ do_it (GObject *object,
int
main (int argc, char *argv[])
{
GtkWidget *window;
gboolean done = FALSE;
if (argc < 2)
@ -355,6 +354,8 @@ main (int argc, char *argv[])
#ifdef GDK_WINDOWING_WAYLAND
if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ()))
{
GtkWidget *window;
window = gtk_window_new ();
gtk_window_present (GTK_WINDOW (window));
handler = g_signal_connect (window, "notify::is-active", G_CALLBACK (do_it), NULL);