Compare commits
168 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eccbd4fe5f | |||
| 3b967f1242 | |||
| 1a4c988a22 | |||
| d936a9ae89 | |||
| 67e6d1087e | |||
| 29bafd1e15 | |||
| 65697e3324 | |||
| bceca277ea | |||
| 16c8fb52df | |||
| d702bfe7b7 | |||
| 596c9a3c0b | |||
| c675d1c9e1 | |||
| bd490ed511 | |||
| bcf180642d | |||
| 5882e22f89 | |||
| 6f25168db3 | |||
| 2a4b5862ae | |||
| 7037ff8f3d | |||
| 1c9a486d60 | |||
| eb9284e9ca | |||
| 77e3b72b15 | |||
| 05cb7e7412 | |||
| 299422994a | |||
| b1d90cc171 | |||
| af2207bc0b | |||
| 522bbc182d | |||
| 65233726f8 | |||
| 19227d9789 | |||
| 8915d60900 | |||
| ed52c029a0 | |||
| 7b1201cd4d | |||
| 3f940715e4 | |||
| f6225901e8 | |||
| eff4b6377d | |||
| a18647af0e | |||
| c7df0c907a | |||
| b74407a343 | |||
| cd5c39834d | |||
| 574a25b09c | |||
| 6e0b13b81f | |||
| bea8025fb5 | |||
| 965d0e04d1 | |||
| d7c54920ee | |||
| 33a8108f19 | |||
| 78d254370c | |||
| 377ec33069 | |||
| 2952ba07e1 | |||
| 62b7ea7611 | |||
| c9eca55c5e | |||
| 435bc269e9 | |||
| 0d2a7f876b | |||
| 737400ddbc | |||
| 134e159bc9 | |||
| 6f0b47681b | |||
| d53981fdbb | |||
| e09beee62a | |||
| 724ec3ca92 | |||
| 3ce6a710a3 | |||
| e41596d6a1 | |||
| 0fa4d54316 | |||
| e7cbb7a76c | |||
| b2a23a9a90 | |||
| 6878c2bae0 | |||
| 5b8f1aa2ee | |||
| 6b4a82224c | |||
| 1f30b7742b | |||
| 54e7a94d70 | |||
| f1919c706f | |||
| 26b17473aa | |||
| 99eee5cea9 | |||
| 074a0014c1 | |||
| 091cac00b2 | |||
| 175e3d751d | |||
| 83e9361005 | |||
| 17bb1248b5 | |||
| 8211e79be9 | |||
| d5282862e5 | |||
| 26b6d18563 | |||
| 31fb5cc2d4 | |||
| 90301c6813 | |||
| ccdf50aafd | |||
| af5c80248d | |||
| 1d81a58cf1 | |||
| 09cec2e6a1 | |||
| efed2641f4 | |||
| 97a5ca74d2 | |||
| 5b5b215dea | |||
| 7a06859f38 | |||
| 24fa104b61 | |||
| 89861faa04 | |||
| 5fd94e2027 | |||
| 1f4d02740e | |||
| 0023b9036b | |||
| 89d1f8c3ca | |||
| 7d9364655d | |||
| 86d2fcef16 | |||
| 5f8543fe81 | |||
| aae7816557 | |||
| 6fbf13965c | |||
| 484e330e4a | |||
| f27ecde1e2 | |||
| c06d1a69ae | |||
| cf9deb7cf5 | |||
| 40beb69487 | |||
| f1cadee196 | |||
| f6594ff073 | |||
| 478fdaa632 | |||
| 6c472ed2b8 | |||
| 30942c4e3d | |||
| bf7d1e7b5a | |||
| 92e21c3f1c | |||
| 8880d27460 | |||
| 59d50be737 | |||
| 6d73443131 | |||
| fe3796ed5b | |||
| 89f7b974f2 | |||
| 0ae958d45b | |||
| 3d1fdf77dc | |||
| 0ae71cacb4 | |||
| 218d635ca2 | |||
| 7553d0c471 | |||
| f4880f5df5 | |||
| 3ccdad76de | |||
| e464c08545 | |||
| 56e95ddfc8 | |||
| 65052a5d6c | |||
| 1364eb2f62 | |||
| aa8ada3fed | |||
| 3643a9fe86 | |||
| 25f4bb2e17 | |||
| 3b62d9c027 | |||
| c92938b378 | |||
| c98313016e | |||
| e43839114d | |||
| b6c1786165 | |||
| 3a40555202 | |||
| ff604e1906 | |||
| 34974a8a66 | |||
| 7c15daf99e | |||
| b9467a4dc7 | |||
| 5a1c37a8c8 | |||
| b75bc8aa64 | |||
| ed4c08d9b3 | |||
| 929cdd9259 | |||
| 78049f452a | |||
| cf2ef4863b | |||
| 2bd348558e | |||
| 0f6d83bb5f | |||
| 7e20232607 | |||
| dcc55e3a73 | |||
| 59fd48cee0 | |||
| c848b9014b | |||
| 1e16cb088a | |||
| f4cf43359d | |||
| 6c8a5f5e2f | |||
| da64d687d1 | |||
| aab803b7ae | |||
| 936aba884a | |||
| e1200230c4 | |||
| d3ad816d63 | |||
| eea1388cf4 | |||
| f3747d1776 | |||
| 6277f2fccc | |||
| 931b0b3752 | |||
| 6f3e608331 | |||
| 1f58e0ed6b | |||
| 7a45768efe | |||
| 3a56da60dd |
@@ -32,6 +32,7 @@ xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||
--timeout-multiplier 2 \
|
||||
--print-errorlogs \
|
||||
--suite=gtk \
|
||||
--no-suite=gtk:gsk \
|
||||
--no-suite=gtk:a11y
|
||||
|
||||
# Save the exit code
|
||||
|
||||
@@ -12,13 +12,13 @@ Overview of Changes in GTK+ 3.96.0
|
||||
* The use of global coordinates in GDK apis has been reduced. This
|
||||
work is still incomplete
|
||||
|
||||
* Events have been simplified and are just used for input
|
||||
- expose events have been replaced by a GdkSurface::render signal
|
||||
- configure events have been replaced by a GdkSurface::size-changed signal
|
||||
- map events have been replaced by a GdkSurface::mapped property
|
||||
- gdk_event_handler_set has been replaced by a GdkSurface::event signal
|
||||
- key events no longer contain a string
|
||||
- events on unmapped widgets are ignored
|
||||
* Events have been simplified and are used just for input
|
||||
- expose events have been replaced by a GdkSurface::render signal
|
||||
- configure events have been replaced by a GdkSurface::size-changed signal
|
||||
- map events have been replaced by a GdkSurface::mapped property
|
||||
- gdk_event_handler_set has been replaced by a GdkSurface::event signal
|
||||
- key events no longer contain a string
|
||||
- events on unmapped widgets are ignored
|
||||
|
||||
* Warping the pointer is no longer supported
|
||||
|
||||
@@ -36,11 +36,11 @@ Overview of Changes in GTK+ 3.96.0
|
||||
|
||||
* A number of list models have been introduced, for internal use
|
||||
and as public api:
|
||||
- GtkMapListModel
|
||||
- GtkSliceListModel
|
||||
- GtkSortListModel
|
||||
- GtkSelectionModel
|
||||
- GtkSingleSelection
|
||||
- GtkMapListModel
|
||||
- GtkSliceListModel
|
||||
- GtkSortListModel
|
||||
- GtkSelectionModel
|
||||
- GtkSingleSelection
|
||||
|
||||
* Support for tabular menus and combo boxes has been dropped
|
||||
|
||||
@@ -70,9 +70,13 @@ Overview of Changes in GTK+ 3.96.0
|
||||
|
||||
* GtkWidget can now use a GtkLayoutManager for size allocation.
|
||||
Layout managers can optionally use layout children holding layout
|
||||
properties. GtkBinLayout, GtkBoxLayout, GtkGridLayout, GtkFixedLayout
|
||||
and GtkCustomLayout are currently available, more layout manager
|
||||
implementations will appear in the future.
|
||||
properties. A number of layout managers are available:
|
||||
- GtkBinLayout
|
||||
- GtkBoxLayout
|
||||
- GtkGridLayout
|
||||
- GtkFixedLayout
|
||||
- GtkCustomLayout
|
||||
More layout manager implementations will appear in the future.
|
||||
|
||||
* GtkAssistant, GtkStack and GtkNotebook now have publicly
|
||||
accessible page objects for their children. The page objects
|
||||
@@ -82,8 +86,11 @@ Overview of Changes in GTK+ 3.96.0
|
||||
child properties have been removed, converted to regular properties,
|
||||
moved to layout properties or moved to child meta objects.
|
||||
|
||||
* GtkListBox has gained a ::show-separators property that gets
|
||||
translated into a CSS style class.
|
||||
|
||||
* A number of X11-specific GtkWindow and GdkSurface apis have been
|
||||
removed
|
||||
removed or changed to backend APIs.
|
||||
|
||||
* GtkBuilder can specify object-valued properties inline.
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ do_expander (GtkWidget *do_widget)
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *area;
|
||||
GtkWidget *expander;
|
||||
GtkWidget *label;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *tv;
|
||||
GtkTextBuffer *buffer;
|
||||
@@ -50,13 +51,19 @@ do_expander (GtkWidget *do_widget)
|
||||
|
||||
area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (window));
|
||||
|
||||
label = gtk_widget_get_last_child (area);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), FALSE);
|
||||
gtk_widget_set_vexpand (label, FALSE);
|
||||
|
||||
expander = gtk_expander_new ("Details:");
|
||||
gtk_widget_set_vexpand (expander, TRUE);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), 100);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
|
||||
tv = gtk_text_view_new ();
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
|
||||
|
||||
+1
-11
@@ -101,51 +101,41 @@ do_menus (GtkWidget *do_widget)
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
gtk_widget_show (box);
|
||||
|
||||
box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (box), box1);
|
||||
gtk_widget_show (box1);
|
||||
|
||||
menubar = gtk_menu_bar_new ();
|
||||
gtk_widget_set_hexpand (menubar, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box1), menubar);
|
||||
gtk_widget_show (menubar);
|
||||
|
||||
menu = create_menu (2);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("test\nline2");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("foo");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("bar");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_container_add (GTK_CONTAINER (box1), box2);
|
||||
gtk_widget_show (box2);
|
||||
|
||||
button = gtk_button_new_with_label ("Flip");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (change_orientation), menubar);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
gtk_widget_show (button);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK(gtk_widget_destroy), window);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_widget_grab_default (button);
|
||||
gtk_widget_show (button);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (window), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -76,8 +76,7 @@ do_password_entry (GtkWidget *do_widget)
|
||||
gtk_widget_set_sensitive (button, FALSE);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
|
||||
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_window_set_default (GTK_WINDOW (window), button);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (window), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -99,8 +99,7 @@ do_tagged_entry (GtkWidget *do_widget)
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
|
||||
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_window_set_default (GTK_WINDOW (window), button);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (window), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
subdir('gtk-demo')
|
||||
subdir('icon-browser')
|
||||
subdir('node-editor')
|
||||
subdir('widget-factory')
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <node-editor-application.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
return g_application_run (G_APPLICATION (node_editor_application_new ()), argc, argv);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
node_editor_sources = [
|
||||
'main.c',
|
||||
'node-editor-application.c',
|
||||
'node-editor-window.c',
|
||||
]
|
||||
|
||||
node_editor_resources = gnome.compile_resources('node_editor_resources',
|
||||
'node-editor.gresource.xml',
|
||||
source_dir: '.')
|
||||
|
||||
executable('gtk4-node-editor',
|
||||
node_editor_sources, node_editor_resources,
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false)
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "node-editor-application.h"
|
||||
|
||||
#include "node-editor-window.h"
|
||||
|
||||
struct _NodeEditorApplication
|
||||
{
|
||||
GtkApplication parent;
|
||||
};
|
||||
|
||||
struct _NodeEditorApplicationClass
|
||||
{
|
||||
GtkApplicationClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(NodeEditorApplication, node_editor_application, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
node_editor_application_init (NodeEditorApplication *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
quit_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer data)
|
||||
{
|
||||
g_application_quit (G_APPLICATION (data));
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] =
|
||||
{
|
||||
{ "quit", quit_activated, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
node_editor_application_startup (GApplication *app)
|
||||
{
|
||||
const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||
|
||||
G_APPLICATION_CLASS (node_editor_application_parent_class)->startup (app);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
app);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
|
||||
"app.quit",
|
||||
quit_accels);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_application_activate (GApplication *app)
|
||||
{
|
||||
NodeEditorWindow *win;
|
||||
|
||||
win = node_editor_window_new (NODE_EDITOR_APPLICATION (app));
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_application_open (GApplication *app,
|
||||
GFile **files,
|
||||
gint n_files,
|
||||
const gchar *hint)
|
||||
{
|
||||
NodeEditorWindow *win;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_files; i++)
|
||||
{
|
||||
win = node_editor_window_new (NODE_EDITOR_APPLICATION (app));
|
||||
node_editor_window_load (win, files[i]);
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_application_class_init (NodeEditorApplicationClass *class)
|
||||
{
|
||||
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
|
||||
|
||||
application_class->startup = node_editor_application_startup;
|
||||
application_class->activate = node_editor_application_activate;
|
||||
application_class->open = node_editor_application_open;
|
||||
}
|
||||
|
||||
NodeEditorApplication *
|
||||
node_editor_application_new (void)
|
||||
{
|
||||
return g_object_new (NODE_EDITOR_APPLICATION_TYPE,
|
||||
"application-id", "org.gtk.gtk4.NodeEditor",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __NODE_EDITOR_APPLICATION_H__
|
||||
#define __NODE_EDITOR_APPLICATION_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define NODE_EDITOR_APPLICATION_TYPE (node_editor_application_get_type ())
|
||||
#define NODE_EDITOR_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NODE_EDITOR_APPLICATION_TYPE, NodeEditorApplication))
|
||||
|
||||
|
||||
typedef struct _NodeEditorApplication NodeEditorApplication;
|
||||
typedef struct _NodeEditorApplicationClass NodeEditorApplicationClass;
|
||||
|
||||
|
||||
GType node_editor_application_get_type (void);
|
||||
NodeEditorApplication *node_editor_application_new (void);
|
||||
|
||||
|
||||
#endif /* __NODE_EDITOR_APPLICATION_H__ */
|
||||
@@ -1,431 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "node-editor-window.h"
|
||||
|
||||
#include "gsk/gskrendernodeparserprivate.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gsize start_chars;
|
||||
gsize end_chars;
|
||||
char *message;
|
||||
} TextViewError;
|
||||
|
||||
struct _NodeEditorWindow
|
||||
{
|
||||
GtkApplicationWindow parent;
|
||||
|
||||
GtkWidget *picture;
|
||||
GtkWidget *text_view;
|
||||
GtkTextBuffer *text_buffer;
|
||||
|
||||
GArray *errors;
|
||||
};
|
||||
|
||||
struct _NodeEditorWindowClass
|
||||
{
|
||||
GtkApplicationWindowClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(NodeEditorWindow, node_editor_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
static void
|
||||
text_view_error_free (TextViewError *e)
|
||||
{
|
||||
g_free (e->message);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_current_text (GtkTextBuffer *buffer)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
|
||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
||||
gtk_text_buffer_get_end_iter (buffer, &end);
|
||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||
|
||||
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
deserialize_error_func (const GtkCssSection *section,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
const GtkCssLocation *start_location = gtk_css_section_get_start_location (section);
|
||||
const GtkCssLocation *end_location = gtk_css_section_get_end_location (section);
|
||||
NodeEditorWindow *self = user_data;
|
||||
GtkTextIter start_iter, end_iter;
|
||||
TextViewError text_view_error;
|
||||
|
||||
gtk_text_buffer_get_iter_at_line_offset (self->text_buffer, &start_iter,
|
||||
start_location->lines,
|
||||
start_location->line_chars);
|
||||
gtk_text_buffer_get_iter_at_line_offset (self->text_buffer, &end_iter,
|
||||
end_location->lines,
|
||||
end_location->line_chars);
|
||||
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "error",
|
||||
&start_iter, &end_iter);
|
||||
|
||||
text_view_error.start_chars = start_location->chars;
|
||||
text_view_error.end_chars = end_location->chars;
|
||||
text_view_error.message = g_strdup (error->message);
|
||||
g_array_append_val (self->errors, text_view_error);
|
||||
}
|
||||
|
||||
static void
|
||||
text_changed (GtkTextBuffer *buffer,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
char *text;
|
||||
GBytes *bytes;
|
||||
|
||||
g_array_remove_range (self->errors, 0, self->errors->len);
|
||||
text = get_current_text (self->text_buffer);
|
||||
bytes = g_bytes_new_take (text, strlen (text));
|
||||
|
||||
/* If this is too slow, go fix the parser performance */
|
||||
node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
|
||||
g_bytes_unref (bytes);
|
||||
if (node)
|
||||
{
|
||||
/* XXX: Is this code necessary or can we have API to turn nodes into paintables? */
|
||||
GtkSnapshot *snapshot;
|
||||
GdkPaintable *paintable;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gsk_render_node_get_bounds (node, &bounds);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- bounds.origin.x, - bounds.origin.y));
|
||||
gtk_snapshot_append_node (snapshot, node);
|
||||
gsk_render_node_unref (node);
|
||||
paintable = gtk_snapshot_free_to_paintable (snapshot, &bounds.size);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (self->picture), paintable);
|
||||
g_clear_object (&paintable);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_picture_set_paintable (GTK_PICTURE (self->picture), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
text_view_query_tooltip_cb (GtkWidget *widget,
|
||||
int x,
|
||||
int y,
|
||||
gboolean keyboard_tip,
|
||||
GtkTooltip *tooltip,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
GtkTextIter iter;
|
||||
guint i;
|
||||
|
||||
if (keyboard_tip)
|
||||
{
|
||||
gint offset;
|
||||
|
||||
g_object_get (self->text_buffer, "cursor-position", &offset, NULL);
|
||||
gtk_text_buffer_get_iter_at_offset (self->text_buffer, &iter, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
gint bx, by, trailing;
|
||||
|
||||
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (self->text_view), GTK_TEXT_WINDOW_TEXT,
|
||||
x, y, &bx, &by);
|
||||
gtk_text_view_get_iter_at_position (GTK_TEXT_VIEW (self->text_view), &iter, &trailing, bx, by);
|
||||
}
|
||||
|
||||
for (i = 0; i < self->errors->len; i ++)
|
||||
{
|
||||
const TextViewError *e = &g_array_index (self->errors, TextViewError, i);
|
||||
GtkTextIter start_iter, end_iter;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (self->text_buffer, &start_iter, e->start_chars);
|
||||
gtk_text_buffer_get_iter_at_offset (self->text_buffer, &end_iter, e->end_chars);
|
||||
|
||||
if (gtk_text_iter_in_range (&iter, &start_iter, &end_iter))
|
||||
{
|
||||
gtk_tooltip_set_text (tooltip, e->message);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
node_editor_window_load (NodeEditorWindow *self,
|
||||
GFile *file)
|
||||
{
|
||||
GtkTextIter end;
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, NULL);
|
||||
if (bytes == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
|
||||
{
|
||||
g_bytes_unref (bytes);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_text_buffer_get_end_iter (self->text_buffer, &end);
|
||||
gtk_text_buffer_insert (self->text_buffer,
|
||||
&end,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
open_response_cb (GtkWidget *dialog,
|
||||
gint response,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
gtk_widget_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||
node_editor_window_load (self, file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
open_cb (GtkWidget *button,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_file_chooser_dialog_new ("Open node file",
|
||||
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
"_Load", GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), ".");
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), self);
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
save_response_cb (GtkWidget *dialog,
|
||||
gint response,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
gtk_widget_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
char *text, *filename;
|
||||
GError *error = NULL;
|
||||
|
||||
text = get_current_text (self->text_buffer);
|
||||
|
||||
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||
if (!g_file_set_contents (filename, text, -1, &error))
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
"Saving failed");
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%s", error->message);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
save_cb (GtkWidget *button,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_file_chooser_dialog_new ("Save node",
|
||||
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
"_Save", GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), ".");
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (save_response_cb), self);
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
create_texture (NodeEditorWindow *self)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
GtkSnapshot *snapshot;
|
||||
GskRenderer *renderer;
|
||||
GskRenderNode *node;
|
||||
GdkTexture *texture;
|
||||
|
||||
paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture));
|
||||
if (paintable == NULL ||
|
||||
gdk_paintable_get_intrinsic_width (paintable) <= 0 ||
|
||||
gdk_paintable_get_intrinsic_height (paintable) <= 0)
|
||||
return NULL;
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gdk_paintable_snapshot (paintable, snapshot, gdk_paintable_get_intrinsic_width (paintable), gdk_paintable_get_intrinsic_height (paintable));
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
/* ahem */
|
||||
renderer = GTK_ROOT_GET_IFACE (gtk_widget_get_root (GTK_WIDGET (self)))->get_renderer (gtk_widget_get_root (GTK_WIDGET (self)));
|
||||
texture = gsk_renderer_render_texture (renderer, node, NULL);
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
export_image_response_cb (GtkWidget *dialog,
|
||||
gint response,
|
||||
GdkTexture *texture)
|
||||
{
|
||||
gtk_widget_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||
if (!gdk_texture_save_to_png (texture, filename))
|
||||
{
|
||||
GtkWidget *message_dialog;
|
||||
|
||||
message_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog))),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
"Exporting to image failed");
|
||||
g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (message_dialog);
|
||||
}
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
export_image_cb (GtkWidget *button,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GtkWidget *dialog;
|
||||
|
||||
texture = create_texture (self);
|
||||
if (texture == NULL)
|
||||
return;
|
||||
|
||||
dialog = gtk_file_chooser_dialog_new ("",
|
||||
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
"_Save", GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (export_image_response_cb), texture);
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_finalize (GObject *object)
|
||||
{
|
||||
NodeEditorWindow *self = (NodeEditorWindow *)object;
|
||||
|
||||
g_array_free (self->errors, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (node_editor_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->finalize = node_editor_window_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/gtk4/node-editor/node-editor-window.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, text_buffer);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, text_view);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, picture);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, text_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, text_view_query_tooltip_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, open_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, save_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, export_image_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_init (NodeEditorWindow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->errors = g_array_new (FALSE, TRUE, sizeof (TextViewError));
|
||||
g_array_set_clear_func (self->errors, (GDestroyNotify)text_view_error_free);
|
||||
}
|
||||
|
||||
NodeEditorWindow *
|
||||
node_editor_window_new (NodeEditorApplication *application)
|
||||
{
|
||||
return g_object_new (NODE_EDITOR_WINDOW_TYPE,
|
||||
"application", application,
|
||||
NULL);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __NODE_EDITOR_WINDOW_H__
|
||||
#define __NODE_EDITOR_WINDOW_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "node-editor-application.h"
|
||||
|
||||
#define NODE_EDITOR_WINDOW_TYPE (node_editor_window_get_type ())
|
||||
#define NODE_EDITOR_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NODE_EDITOR_WINDOW_TYPE, NodeEditorWindow))
|
||||
|
||||
|
||||
typedef struct _NodeEditorWindow NodeEditorWindow;
|
||||
typedef struct _NodeEditorWindowClass NodeEditorWindowClass;
|
||||
|
||||
|
||||
GType node_editor_window_get_type (void);
|
||||
|
||||
NodeEditorWindow * node_editor_window_new (NodeEditorApplication *application);
|
||||
|
||||
gboolean node_editor_window_load (NodeEditorWindow *self,
|
||||
GFile *file);
|
||||
|
||||
#endif /* __NODE_EDITOR_WINDOW_H__ */
|
||||
@@ -1,99 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkTextTagTable" id="tags">
|
||||
<child type="tag">
|
||||
<object class="GtkTextTag">
|
||||
<property name="name">error</property>
|
||||
<property name="underline">error</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkTextBuffer" id="text_buffer">
|
||||
<property name="tag-table">tags</property>
|
||||
<signal name="changed" handler="text_changed"/>
|
||||
</object>
|
||||
<template class="NodeEditorWindow" parent="GtkApplicationWindow">
|
||||
<style>
|
||||
<class name="devel"/>
|
||||
</style>
|
||||
<property name="title" translatable="yes">GTK Node Editor</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="title" translatable="yes">GTK Node Editor</property>
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
<property name="tooltip-text">Open node file</property>
|
||||
<signal name="clicked" handler="open_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-save-symbolic</property>
|
||||
<property name="tooltip-text">Save to node file</property>
|
||||
<signal name="clicked" handler="save_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">insert-image-symbolic</property>
|
||||
<property name="tooltip-text">Export to image</property>
|
||||
<signal name="clicked" handler="export_image_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">GTK Node Editor</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<property name="shrink-child2">false</property>
|
||||
<property name="position">400</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="expand">1</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="text_view">
|
||||
<property name="buffer">text_buffer</property>
|
||||
<property name="wrap-mode">word</property>
|
||||
<property name="monospace">1</property>
|
||||
<property name="has-focus">1</property>
|
||||
<property name="top-margin">6</property>
|
||||
<property name="left-margin">6</property>
|
||||
<property name="right-margin">6</property>
|
||||
<property name="bottom-margin">6</property>
|
||||
<property name="has-tooltip">1</property>
|
||||
<signal name="query-tooltip" handler="text_view_query_tooltip_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="expand">1</property>
|
||||
<property name="min-content-height">100</property>
|
||||
<property name="min-content-width">100</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkPicture" id="picture">
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/gtk4/node-editor">
|
||||
<file preprocess="xml-stripblanks">node-editor-window.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@@ -2880,6 +2880,17 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<child>
|
||||
<object class="GtkNotebook">
|
||||
<property name="show-border">0</property>
|
||||
<child type="action-end">
|
||||
<object class="GtkMenuButton">
|
||||
<property name="valign">center</property>
|
||||
<property name="popover">notebook_info_popover2</property>
|
||||
<property name="icon-name">emblem-important-symbolic</property>
|
||||
<property name="relief">none</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="tab-expand">1</property>
|
||||
@@ -3143,6 +3154,7 @@ bad things might happen.</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="yes">Zelda</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<property name="default-widget">act_action_dialog</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
@@ -3164,8 +3176,6 @@ bad things might happen.</property>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="act_action_dialog">
|
||||
<property name="can-default">1</property>
|
||||
<property name="has-default">1</property>
|
||||
<property name="label" translatable="yes">_Act</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
@@ -3303,6 +3313,7 @@ bad things might happen.</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="yes">Choose one</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<property name="default-widget">select_selection_dialog</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
@@ -3324,8 +3335,6 @@ bad things might happen.</property>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="select_selection_dialog">
|
||||
<property name="can-default">1</property>
|
||||
<property name="has-default">1</property>
|
||||
<property name="label" translatable="yes">_Select</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
@@ -3386,6 +3395,7 @@ bad things might happen.</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
@@ -3398,22 +3408,52 @@ bad things might happen.</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander">
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Extra Info</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="placeholder-text">Tell me anything…</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="halign">end</property>
|
||||
<property name="icon-name">emblem-system-symbolic</property>
|
||||
<property name="menu-model">gear_menu</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="open_popover_button">
|
||||
<property name="halign">end</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="label">_Open</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="can-default">1</property>
|
||||
<style>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
@@ -3439,8 +3479,9 @@ bad things might happen.</property>
|
||||
</widgets>
|
||||
</object>
|
||||
<object class="GtkPopover" id="notebook_info_popover">
|
||||
<property name="modal">0</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="notebook_info_label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">No updates at this time</property>
|
||||
<accessibility>
|
||||
<role type="static"/>
|
||||
@@ -3448,4 +3489,39 @@ bad things might happen.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="notebook_info_popover3">
|
||||
<property name="modal">0</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">You're in too deep!</property>
|
||||
<accessibility>
|
||||
<role type="static"/>
|
||||
</accessibility>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="notebook_info_popover2">
|
||||
<property name="modal">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hidden gems:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="valign">center</property>
|
||||
<property name="popover">notebook_info_popover3</property>
|
||||
<property name="icon-name">emblem-important-symbolic</property>
|
||||
<property name="relief">none</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -231,6 +231,7 @@ gdk_surface_get_scale_factor
|
||||
gdk_surface_set_opaque_region
|
||||
gdk_surface_create_gl_context
|
||||
gdk_surface_create_vulkan_context
|
||||
gdk_surface_create_cairo_context
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_surface_queue_expose
|
||||
@@ -988,7 +989,6 @@ gdk_wayland_device_get_wl_seat
|
||||
gdk_wayland_display_get_wl_compositor
|
||||
gdk_wayland_display_get_wl_display
|
||||
gdk_wayland_display_query_registry
|
||||
gdk_wayland_surface_new_subsurface
|
||||
gdk_wayland_surface_get_wl_surface
|
||||
GdkWaylandSurfaceExported
|
||||
gdk_wayland_surface_export_handle
|
||||
|
||||
@@ -62,6 +62,7 @@ gsk_outset_shadow_node_get_spread
|
||||
gsk_outset_shadow_node_get_blur_radius
|
||||
gsk_cairo_node_new
|
||||
gsk_cairo_node_get_draw_context
|
||||
gsk_cairo_node_peek_surface
|
||||
gsk_container_node_new
|
||||
gsk_container_node_get_n_children
|
||||
gsk_container_node_get_child
|
||||
@@ -88,6 +89,7 @@ GskShadow
|
||||
gsk_shadow_node_new
|
||||
gsk_shadow_node_peek_shadow
|
||||
gsk_shadow_node_get_n_shadows
|
||||
gsk_shadow_node_get_child
|
||||
GskBlendMode
|
||||
gsk_blend_node_new
|
||||
gsk_blend_node_get_bottom_child
|
||||
@@ -103,6 +105,7 @@ gsk_text_node_peek_glyphs
|
||||
gsk_text_node_peek_color
|
||||
gsk_text_node_get_x
|
||||
gsk_text_node_get_y
|
||||
gsk_text_node_get_num_glyphs
|
||||
gsk_blur_node_new
|
||||
gsk_blur_node_get_child
|
||||
gsk_blur_node_get_radius
|
||||
@@ -162,6 +165,7 @@ gsk_transform_to_translate
|
||||
gsk_transform_transform
|
||||
gsk_transform_invert
|
||||
gsk_transform_matrix
|
||||
gsk_transform_matrix_with_category
|
||||
gsk_transform_translate
|
||||
gsk_transform_translate_3d
|
||||
gsk_transform_rotate
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<refentry id="chap-actions">
|
||||
<refmeta>
|
||||
<refentrytitle>The GTK Action Model</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>GTK Library</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>The GTK Action Model</refname>
|
||||
<refpurpose>
|
||||
How actions are used in GTK
|
||||
</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
|
||||
<refsect1 id="actions-overview">
|
||||
<title>Overview of actions in GTK</title>
|
||||
|
||||
<para>
|
||||
This chapter describes in detail how GTK uses actions to connect
|
||||
activatable UI elements to callbacks. GTK inherits the underlying
|
||||
architecture of GAction and GMenu for describing abstract actions
|
||||
and menus from the GIO library.
|
||||
</para>
|
||||
|
||||
<refsect2>
|
||||
<title>Basics about actions</title>
|
||||
|
||||
<para>
|
||||
A GAction is essentially a way to tell the toolkit about a
|
||||
piece of functionality in your program, and to give it a name.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions are purely functional. They do not contain any
|
||||
presentational information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An action has four pieces of information associated with it:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
a name as an identifier (usually all-lowercase, untranslated
|
||||
English string)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
an enabled flag indicating if the action can be activated or
|
||||
not (like the "sensitive" property on widgets)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
an optional state value, for stateful actions (like a boolean
|
||||
for toggles)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
an optional parameter type, used when activating the action
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An action supports two operations. You can activate it, which
|
||||
requires passing a parameter of the correct type
|
||||
And you can request to change the actions state (for stateful
|
||||
actions) to a new state value of the correct type.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here are some rules about an action:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
the name is immutable (in the sense that it will never
|
||||
change) and it is never %NULL
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
the enabled flag can change
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
the parameter type is immutable
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
the parameter type is optional: it can be %NULL
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
if the parameter type is %NULL then action activation must
|
||||
be done without a parameter (ie: a %NULL GVariant pointer)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
if the parameter type is non-%NULL then the parameter must
|
||||
have this type
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
the state can change, but it cannot change type
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
if the action was stateful when it was created, it will
|
||||
always have a state and it will always have exactly the same
|
||||
type (such as boolean or string)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
if the action was stateless when it was created, it can never
|
||||
have a state
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
you can only request state changes on stateful actions and it
|
||||
is only possible to request that the state change to a value
|
||||
of the same type as the existing state
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An action does not have any sort of presentational information
|
||||
such as a label, an icon or a way of creating a widget from it.
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Action state and parameters</title>
|
||||
|
||||
<para>
|
||||
Most actions in your application will be stateless actions with
|
||||
no parameters. These typically appear as menu items with no
|
||||
special decoration. An example is "quit".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Stateful actions are used to represent an action which has a
|
||||
closely-associated state of some kind. A good example is a
|
||||
"fullscreen" action. For this case, you'd expect to see a
|
||||
checkmark next to the menu item when the fullscreen option
|
||||
is active. This is usually called a toggle action, and it has
|
||||
a boolean state. By convention, toggle actions have no parameter
|
||||
type for activation: activating the action always toggles the
|
||||
state.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another common case is to have an action representing a
|
||||
enumeration of possible values of a given type (typically
|
||||
string). This is often called a radio action and is usually
|
||||
represented in the user interface with radio buttons or radio
|
||||
menu items, or sometimes a combobox. A good example is
|
||||
"text-justify" with possible values "left", "center", and
|
||||
"right". By convention, these types of actions have a parameter
|
||||
type equal to their state type, and activating them with a
|
||||
particular parameter value is equivalent to changing their
|
||||
state to that value.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This approach to handling radio buttons is different than many
|
||||
other action systems such as GtkAction. With GAction, there is
|
||||
only one action for "text-justify" and "left", "center" and
|
||||
"right" are possible states on that action. There are not three
|
||||
separate "justify-left", "justify-center" and "justify-right"
|
||||
actions.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The final common type of action is a stateless action with a
|
||||
parameter. This is typically used for actions like
|
||||
"open-bookmark" where the parameter to the action would be
|
||||
the identifier of the bookmark to open.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Because some types of actions cannot be invoked without a
|
||||
parameter, it is often important to specify a parameter when
|
||||
referring to the action from a place where it will be invoked
|
||||
(such as from a radio button that sets the state to a particular
|
||||
value or from a menu item that opens a specific bookmark). In
|
||||
these contexts, the value used for the action parameter is
|
||||
typically called the target of the action.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Even though toggle actions have a state, they do not have a
|
||||
parameter. Therefore, a target value is not needed when
|
||||
referring to them — they will always be toggled on activation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Most APIs that allow using a GAction (such as GMenuModel and
|
||||
GtkActionable) allow use of detailed action names. This is a
|
||||
convenient way of specifying an action name and an action target
|
||||
with a single string.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the case that the action target is a string with no unusual
|
||||
characters (ie: only alpha-numeric, plus '-' and '.') then you
|
||||
can use a detailed action name of the form "justify::left" to
|
||||
specify the justify action with a target of left.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the case that the action target is not a string, or contains
|
||||
unusual characters, you can use the more general format
|
||||
"action-name(5)", where the "5" here is any valid text-format
|
||||
GVariant (ie: a string that can be parsed by g_variant_parse()).
|
||||
Another example is "open-bookmark('http://gnome.org/')".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can convert between detailed action names and split-out
|
||||
action names and target values using g_action_parse_detailed_action_name()
|
||||
and g_action_print_detailed_action_name() but usually you will
|
||||
not need to. Most APIs will provide both ways of specifying
|
||||
actions with targets.
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Action scopes</title>
|
||||
|
||||
<para>
|
||||
Actions are always scoped to a particular object on which they
|
||||
operate.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In GTK, actions are typically scoped to either an application
|
||||
or a window, but any widget can have actions associated with it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions scoped to windows should be the actions that
|
||||
specifically impact that window. These are actions like
|
||||
"fullscreen" and "close", or in the case that a window contains
|
||||
a document, "save" and "print".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions that impact the application as a whole rather than one
|
||||
specific window are scoped to the application. These are actions
|
||||
like "about" and "preferences".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If a particular action is scoped to a window then it is scoped
|
||||
to a specific window. Another way of saying this: if your
|
||||
application has a "fullscreen" action that applies to windows
|
||||
and it has three windows, then it will have three fullscreen
|
||||
actions: one for each window.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Having a separate action per-window allows for each window to
|
||||
have a separate state for each instance of the action as well
|
||||
as being able to control the enabled state of the action on a
|
||||
per-window basis.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions are added to their relevant scope (application or
|
||||
window) either using the GActionMap interface, or by using
|
||||
gtk_widget_insert_action_group().
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Action groups and action maps</title>
|
||||
|
||||
<para>
|
||||
Actions rarely occurs in isolation. It is common to have groups
|
||||
of related actions, which are represented by instances of the
|
||||
GActionGroup interface.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Action maps are a variant of action groups that allow to change
|
||||
the name of the action as it is looked up. In GTK, the convention
|
||||
is to add a prefix to the action name to indicate the scope of
|
||||
the actions, such as "app." for the actions with application scope
|
||||
or "win." for those with window scope.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When referring to actions on a GActionMap only the name of the
|
||||
action itself is used (ie: "quit", not "app.quit"). The
|
||||
"app.quit" form is only used when referring to actions from
|
||||
places like a GMenu or GtkActionable widget where the scope
|
||||
of the action is not already known.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
GtkApplication and GtkApplicationWindow implement the GActionMap
|
||||
interface, so you can just add actions directly to them. For
|
||||
other widgets, use gtk_widget_insert_action_group() to add
|
||||
actions to it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you want to insert several actions at the same time, it is
|
||||
typically faster and easier to use GActionEntry.
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Connecting actions to widgets</title>
|
||||
|
||||
<para>
|
||||
Any widget that implements the GtkActionable interface can
|
||||
be connected to an action just by setting the ::action-name
|
||||
property. If the action has a parameter, you will also need
|
||||
to set the ::action-target property.
|
||||
Widgets that implement GtkAction include GtkSwitch, GtkButton,
|
||||
GtkMenuItem and their respective subclasses.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another of obtaining widgets that are connected to actions is
|
||||
to create a menu using a GMenu menu model. GMenu provides an
|
||||
abstract way to describe typical menus: nested groups of items
|
||||
where each item can have a label, and icon, and an action.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Typical uses of GMenu inside GTK are to set up an application
|
||||
menu or menubar with gtk_application_set_app_menu() or
|
||||
gtk_application_set_menubar(). Another, maybe more common use
|
||||
is to create a popover for a menubutton, using
|
||||
gtk_menu_button_set_menu_model().
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Unlike traditional menus, those created from menu models don't
|
||||
have keyboard accelerators associated with menu items. Instead,
|
||||
GtkApplication offers the gtk_application_set_accels_for_action()
|
||||
API to associate keyboard shortcuts with actions.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Activation</title>
|
||||
|
||||
<para>
|
||||
When a widget with a connected action is activated, GTK finds
|
||||
the action to activate by walking up the widget hierarchy,
|
||||
looking for a matching action, ending up at the GtkApplication.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Built-in Actions</title>
|
||||
|
||||
<para>
|
||||
GTK uses actions for its own purposes in a number places. These
|
||||
built-in actions can sometimes be activated by applications, and
|
||||
you should avoid naming conflicts with them when creating your
|
||||
own actions.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>default.activate</term>
|
||||
<listitem><para>Activates the default widget in a context
|
||||
(typically a GtkWindow, GtkDialog or GtkPopover)
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
</refsect1>
|
||||
</refentry>
|
||||
@@ -12,7 +12,7 @@
|
||||
<refnamediv>
|
||||
<refname>The GTK Drawing Model</refname>
|
||||
<refpurpose>
|
||||
The GTK drawing model in detail
|
||||
How widgets draw
|
||||
</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
<xi:include href="xml/getting_started.xml"/>
|
||||
<xi:include href="resources.sgml" />
|
||||
<xi:include href="xml/question_index.sgml" />
|
||||
<xi:include href="drawing-model.xml" />
|
||||
<xi:include href="xml/drawing-model.xml" />
|
||||
<xi:include href="xml/input-handling.xml" />
|
||||
<xi:include href="xml/actions.xml" />
|
||||
</part>
|
||||
|
||||
<part id="gtkobjects">
|
||||
|
||||
@@ -1779,7 +1779,6 @@ GtkMenu
|
||||
GtkArrowPlacement
|
||||
gtk_menu_new
|
||||
gtk_menu_new_from_model
|
||||
gtk_menu_set_display
|
||||
gtk_menu_reorder_child
|
||||
gtk_menu_popup_at_rect
|
||||
gtk_menu_popup_at_widget
|
||||
@@ -4433,7 +4432,6 @@ gtk_widget_event
|
||||
gtk_widget_activate
|
||||
gtk_widget_is_focus
|
||||
gtk_widget_grab_focus
|
||||
gtk_widget_grab_default
|
||||
gtk_widget_set_name
|
||||
gtk_widget_get_name
|
||||
gtk_widget_set_sensitive
|
||||
@@ -4504,8 +4502,6 @@ gtk_widget_compute_point
|
||||
gtk_widget_contains
|
||||
GtkPickFlags
|
||||
gtk_widget_pick
|
||||
gtk_widget_get_can_default
|
||||
gtk_widget_set_can_default
|
||||
gtk_widget_get_can_focus
|
||||
gtk_widget_set_can_focus
|
||||
gtk_widget_get_focus_on_click
|
||||
@@ -4538,13 +4534,15 @@ gtk_widget_get_realized
|
||||
gtk_widget_get_mapped
|
||||
gtk_widget_device_is_shadowed
|
||||
gtk_widget_get_modifier_mask
|
||||
gtk_widget_insert_action_group
|
||||
gtk_widget_get_opacity
|
||||
gtk_widget_set_opacity
|
||||
gtk_widget_get_overflow
|
||||
gtk_widget_set_overflow
|
||||
gtk_widget_insert_action_group
|
||||
gtk_widget_list_action_prefixes
|
||||
gtk_widget_get_action_group
|
||||
gtk_widget_activate_action
|
||||
gtk_widget_activate_default
|
||||
gtk_widget_measure
|
||||
gtk_widget_snapshot_child
|
||||
gtk_widget_get_next_sibling
|
||||
@@ -4647,8 +4645,6 @@ gtk_window_set_resizable
|
||||
gtk_window_get_resizable
|
||||
gtk_window_add_accel_group
|
||||
gtk_window_remove_accel_group
|
||||
gtk_window_activate_focus
|
||||
gtk_window_activate_default
|
||||
gtk_window_set_modal
|
||||
gtk_window_set_default_size
|
||||
gtk_window_set_hide_on_close
|
||||
@@ -4671,7 +4667,7 @@ gtk_window_propagate_key_event
|
||||
gtk_window_get_focus
|
||||
gtk_window_set_focus
|
||||
gtk_window_get_default_widget
|
||||
gtk_window_set_default
|
||||
gtk_window_set_default_widget
|
||||
gtk_window_present
|
||||
gtk_window_present_with_time
|
||||
gtk_window_close
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
]>
|
||||
<refentry id="chap-input-handling">
|
||||
<refmeta>
|
||||
<refentrytitle>The GTK Input and Event Handling Model</refentrytitle>
|
||||
<refentrytitle>The GTK Input Model</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>GTK Library</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>The GTK Input and Event Handling Model</refname>
|
||||
<refname>The GTK Input Model</refname>
|
||||
<refpurpose>
|
||||
GTK input and event handling in detail
|
||||
input and event handling in detail
|
||||
</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
@@ -52,13 +52,12 @@
|
||||
with any pointing device or keyboard.
|
||||
</para>
|
||||
|
||||
<!-- input events: button, touch, key, motion, etc -->
|
||||
<para>
|
||||
When a user interacts with an input device (e.g. moves a mouse or presses
|
||||
a key on the keyboard), GTK receives events from the windowing system.
|
||||
These are typically directed at a specific window - for pointer events,
|
||||
the window under the pointer (grabs complicate this), for keyboard events,
|
||||
the window with the keyboard focus.
|
||||
These are typically directed at a specific surface - for pointer events,
|
||||
the surface under the pointer (grabs complicate this), for keyboard events,
|
||||
the surface with the keyboard focus.
|
||||
</para>
|
||||
<para>
|
||||
GDK translates these raw windowing system events into #GdkEvents.
|
||||
@@ -81,9 +80,10 @@
|
||||
</simplelist>
|
||||
</para>
|
||||
<para>
|
||||
When GTK is initialized, it sets up an event handler function with
|
||||
gdk_event_handler_set(), which receives all of these input events
|
||||
(as well as others, for instance window management related events).
|
||||
When GTK creates a GdkSurface, it connects to the ::event signal
|
||||
on it, which receives all of these input events. Surfaces have
|
||||
have signals and properties, e.g. to deal with window management
|
||||
related events.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
@@ -91,8 +91,8 @@
|
||||
<title>Event propagation</title>
|
||||
|
||||
<para>
|
||||
For widgets which have a #GdkSurface set, events are received from the
|
||||
windowing system and passed to gtk_main_do_event(). See its documentation
|
||||
The function which initially receives input events on the GTK
|
||||
side is gtk_main_do_event(). See its documentation
|
||||
for details of what it does: compression of enter/leave events,
|
||||
identification of the widget receiving the event, pushing the event onto a
|
||||
stack for gtk_get_current_event(), and propagating the event to the
|
||||
@@ -120,62 +120,55 @@
|
||||
|
||||
<para>
|
||||
An event is propagated to a widget using gtk_propagate_event().
|
||||
Propagation differs between event types: key events (%GDK_KEY_PRESS,
|
||||
%GDK_KEY_RELEASE) are delivered to the top-level #GtkWindow; other events
|
||||
are propagated down and up the widget hierarchy in three phases (see
|
||||
#GtkPropagationPhase).
|
||||
Propagation goes down and up the widget hierarchy in three phases
|
||||
(see #GtkPropagationPhase) towards a target widget.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For key events, the top-level window’s default #GtkWindow::key-press-event
|
||||
and #GtkWindow::key-release-event signal handlers handle mnemonics and
|
||||
accelerators first. Other key presses are then passed to
|
||||
gtk_window_propagate_key_event() which propagates the event upwards from
|
||||
the window’s current focus widget (gtk_window_get_focus()) to the
|
||||
top-level.
|
||||
For key events, the top-level window gets a first shot at activating
|
||||
mnemonics and accelerators. If that does not consume the events,
|
||||
the target widget for event propagation is window's current focus
|
||||
widget (see gtk_window_get_focus()).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For other events, in the first phase (the “capture” phase) the event is
|
||||
delivered to each widget from the top-most (for example, the top-level
|
||||
For pointer events, the target widget is determined by picking
|
||||
the widget at the events coordinates (see gtk_window_pick()).
|
||||
</para>
|
||||
|
||||
<para>In the first phase (the “capture” phase) the event is
|
||||
delivered to each widget from the top-most (the top-level
|
||||
#GtkWindow or grab widget) down to the target #GtkWidget.
|
||||
<link linkend="event-controllers-and-gestures">Gestures</link> that are
|
||||
attached with %GTK_PHASE_CAPTURE get a chance to react to the event.
|
||||
<link linkend="event-controllers-and-gestures">Event
|
||||
controllers</link> that are attached with %GTK_PHASE_CAPTURE
|
||||
get a chance to react to the event.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
After the “capture” phase, the widget that was intended to be the
|
||||
destination of the event will run gestures attached to it with
|
||||
%GTK_PHASE_TARGET. This is known as the “target” phase, and only
|
||||
happens on that widget.
|
||||
destination of the event will run event controllers attached to
|
||||
it with %GTK_PHASE_TARGET. This is known as the “target” phase,
|
||||
and only happens on that widget.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Next, the #GtkWidget::event signal is emitted.
|
||||
Handling these signals was the primary way to handle input in GTK widgets
|
||||
before gestures were introduced. The signal is emitted from
|
||||
the target widget up to the top-level, as part of the “bubble” phase.
|
||||
In the last phase (the “bubble” phase), the event is delivered
|
||||
to each widget from the target to the top-most, and event
|
||||
controllers attached with %GTK_PHASE_BUBBLE are run.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The default handlers for the event signals send the event
|
||||
to gestures that are attached with %GTK_PHASE_BUBBLE. Therefore,
|
||||
gestures in the “bubble” phase are only used if the widget does
|
||||
not have its own event handlers, or takes care to chain up to the
|
||||
default #GtkWidget handlers.
|
||||
Events are not delivered to a widget which is insensitive or
|
||||
unmapped.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Events are not delivered to a widget which is insensitive or unmapped.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Any time during the propagation phase, a widget may indicate that a
|
||||
received event was consumed and propagation should therefore be stopped.
|
||||
In traditional event handlers, this is hinted by returning %GDK_EVENT_STOP.
|
||||
If gestures are used, this may happen when the widget tells the gesture
|
||||
to claim the event touch sequence (or the pointer events) for its own. See the
|
||||
"gesture states" section below to know more of the latter.
|
||||
Any time during the propagation phase, a controller may indicate
|
||||
that a received event was consumed and propagation should
|
||||
therefore be stopped. If gestures are used, this may happen
|
||||
when the gesture claims the event touch sequence (or the
|
||||
pointer events) for its own. See the “gesture states” section
|
||||
below to learn more about gestures and sequences.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
@@ -183,27 +176,10 @@
|
||||
<title>Touch events</title>
|
||||
|
||||
<para>
|
||||
Touch events are emitted as events of type %GDK_TOUCH_BEGIN, %GDK_TOUCH_UPDATE or
|
||||
%GDK_TOUCH_END, those events contain an “event sequence” that univocally identifies
|
||||
the physical touch until it is lifted from the device.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On some windowing platforms, multitouch devices perform pointer emulation, this works
|
||||
by granting a “pointer emulating” hint to one of the currently interacting touch
|
||||
sequences, which will be reported on every #GdkEventTouch event from that sequence. By
|
||||
default, if a widget didn't request touch events by setting %GDK_TOUCH_MASK on its
|
||||
event mask and didn't override #GtkWidget::touch-event, GTK will transform these
|
||||
“pointer emulating” events into semantically similar #GdkEventButton and #GdkEventMotion
|
||||
events. Depending on %GDK_TOUCH_MASK being in the event mask or not, non-pointer-emulating
|
||||
sequences could still trigger gestures or just get filtered out, regardless of the widget
|
||||
not handling those directly.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the widget sets %GDK_TOUCH_MASK on its event mask and doesn't chain up on
|
||||
#GtkWidget::touch-event, only touch events will be received, and no pointer emulation
|
||||
will be performed.
|
||||
Touch events are emitted as events of type %GDK_TOUCH_BEGIN,
|
||||
%GDK_TOUCH_UPDATE or %GDK_TOUCH_END, those events contain an
|
||||
“event sequence” that univocally identifies the physical touch
|
||||
until it is lifted from the device.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
@@ -211,43 +187,66 @@
|
||||
<title>Grabs</title>
|
||||
|
||||
<para>
|
||||
Grabs are a method to claim all input events from a device, they happen
|
||||
either implicitly on pointer and touch devices, or explicitly. Implicit grabs
|
||||
happen on user interaction, when a #GdkEventButtonPress happens, all events from
|
||||
then on, until after the corresponding #GdkEventButtonRelease, will be reported
|
||||
to the widget that got the first event. Likewise, on touch events, every
|
||||
#GdkEventSequence will deliver only events to the widget that received its
|
||||
%GDK_TOUCH_BEGIN event.
|
||||
Grabs are a method to claim all input events from a device,
|
||||
they happen either implicitly on pointer and touch devices,
|
||||
or explicitly. Implicit grabs happen on user interaction, when
|
||||
a #GdkEventButtonPress happens, all events from then on, until
|
||||
after the corresponding #GdkEventButtonRelease, will be reported
|
||||
to the widget that got the first event. Likewise, on touch events,
|
||||
every #GdkEventSequence will deliver only events to the widget
|
||||
that received its %GDK_TOUCH_BEGIN event.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Explicit grabs happen programatically (both activation and deactivation),
|
||||
and can be either system-wide (GDK grabs) or application-wide (GTK grabs).
|
||||
On the windowing platforms that support it, GDK grabs will prevent any
|
||||
interaction with any other application/window/widget than the grabbing one,
|
||||
whereas GTK grabs will be effective only within the application (across all
|
||||
its windows), still allowing for interaction with other applications.
|
||||
Explicit grabs happen programatically (both activation and
|
||||
deactivation), and can be either system-wide (GDK grabs) or
|
||||
application-wide (GTK grabs). On the windowing platforms that
|
||||
support it, GDK grabs will prevent any interaction with any other
|
||||
application/window/widget than the grabbing one, whereas GTK grabs
|
||||
will be effective only within the application (across all its
|
||||
windows), still allowing for interaction with other applications.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
But one important aspect of grabs is that they may potentially happen at any
|
||||
point somewhere else, even while the pointer/touch device is already grabbed.
|
||||
This makes it necessary for widgets to handle the cancellation of any ongoing
|
||||
interaction. Depending on whether a GTK or GDK grab is causing this, the
|
||||
widget will respectively receive a #GtkWidget::grab-notify signal, or a
|
||||
But one important aspect of grabs is that they may potentially
|
||||
happen at any point somewhere else, even while the pointer/touch
|
||||
device is already grabbed. This makes it necessary for widgets to
|
||||
handle the cancellation of any ongoing interaction. Depending on
|
||||
whether a GTK or GDK grab is causing this, the widget will
|
||||
respectively receive a #GtkWidget::grab-notify signal, or a
|
||||
#GdkEventGrabBroken event.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On gestures, these signals are handled automatically, causing the gesture
|
||||
to cancel all tracked pointer/touch events, and signal the end of recognition.
|
||||
On gestures, these signals are handled automatically, causing the
|
||||
gesture to cancel all tracked pointer/touch events, and signal
|
||||
the end of recognition.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Keyboard input</title>
|
||||
|
||||
<!-- focus, tab, directional navigation -->
|
||||
<para>
|
||||
Every #GtkWindow maintains a single focus location (in
|
||||
the ::focus-widget property). The focus widget is the
|
||||
target widget for key events sent to the window. Only
|
||||
widgets which have ::can-focus set to %TRUE can become
|
||||
the focus. Typically these are input controls such as
|
||||
entries or text fields, but e.g. buttons can take the
|
||||
focus too.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Input widgets can be given the focus by clicking on them,
|
||||
but focus can also be moved around with certain key
|
||||
events (this is known as “keyboard navigation”). GTK
|
||||
reserves the Tab key to move the focus to the next location,
|
||||
and Shift-Tab to move it back to the previous one. In addition
|
||||
many containers allow “directional navigation” with the
|
||||
arrow keys.
|
||||
</para>
|
||||
|
||||
<!-- mnemonics, accelerators, bindings -->
|
||||
</refsect2>
|
||||
|
||||
@@ -255,37 +254,43 @@
|
||||
<title>Event controllers and gestures</title>
|
||||
|
||||
<para>
|
||||
Event controllers are standalone objects that can perform specific actions
|
||||
upon received #GdkEvents. These are tied to a #GtkWidget, and can be told of
|
||||
the event propagation phase at which they will manage the events.
|
||||
Event controllers are standalone objects that can perform
|
||||
specific actions upon received #GdkEvents. These are tied
|
||||
to a #GtkWidget, and can be told of the event propagation
|
||||
phase at which they will manage the events.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Gestures are a set of specific controllers that are prepared to handle pointer
|
||||
and/or touch events, each gestures implementation attempts to recognize specific
|
||||
actions out the received events, notifying of the state/progress accordingly to
|
||||
let the widget react to those. On multi-touch gestures, every interacting touch
|
||||
sequence will be tracked independently.
|
||||
Gestures are a set of specific controllers that are prepared
|
||||
to handle pointer and/or touch events, each gesture
|
||||
implementation attempts to recognize specific actions out the
|
||||
received events, notifying of the state/progress accordingly to
|
||||
let the widget react to those. On multi-touch gestures, every
|
||||
interacting touch sequence will be tracked independently.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Being gestures “simple” units, it is not uncommon to tie several together to
|
||||
perform higher level actions, grouped gestures handle the same event sequences
|
||||
simultaneously, and those sequences share a same state across all grouped
|
||||
Since gestures are “simple” units, it is not uncommon to tie
|
||||
several together to perform higher level actions, grouped
|
||||
gestures handle the same event sequences simultaneously, and
|
||||
those sequences share a same state across all grouped
|
||||
gestures. Some examples of grouping may be:
|
||||
|
||||
<simplelist>
|
||||
<member>
|
||||
A “drag” and a “swipe” gestures may want grouping. The former will report
|
||||
events as the dragging happens, the latter will tell the swipe X/Y velocities
|
||||
only after gesture has finished.
|
||||
A “drag” and a “swipe” gestures may want grouping.
|
||||
The former will report events as the dragging happens,
|
||||
the latter will tell the swipe X/Y velocities only after
|
||||
recognition has finished.
|
||||
</member>
|
||||
<member>
|
||||
Grouping a “drag” gesture with a “pan” gesture will only effectively allow
|
||||
dragging in the panning orientation, as both gestures share state.
|
||||
Grouping a “drag” gesture with a “pan” gesture will only
|
||||
effectively allow dragging in the panning orientation, as
|
||||
both gestures share state.
|
||||
</member>
|
||||
<member>
|
||||
If “press” and “long press” are wanted simultaneously, those would need grouping.
|
||||
If “press” and “long press” are wanted simultaneously,
|
||||
those would need grouping.
|
||||
</member>
|
||||
</simplelist>
|
||||
</para>
|
||||
@@ -294,34 +299,39 @@
|
||||
<refsect2>
|
||||
<title>Gesture states</title>
|
||||
<para>
|
||||
Gestures have a notion of “state” for each individual touch sequence. When events
|
||||
from a touch sequence are first received, the touch sequence will have “none” state,
|
||||
this means the touch sequence is being handled by the gesture to possibly trigger
|
||||
Gestures have a notion of “state” for each individual touch
|
||||
sequence. When events from a touch sequence are first received,
|
||||
the touch sequence will have “none” state, this means the touch
|
||||
sequence is being handled by the gesture to possibly trigger
|
||||
actions, but the event propagation will not be stopped.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When the gesture enters recognition, or at a later point in time, the widget may
|
||||
choose to claim the touch sequences (individually or as a group), hence stopping
|
||||
event propagation after the event is run through every gesture in that widget and
|
||||
propagation phase. Anytime this happens, the touch sequences are cancelled downwards
|
||||
the propagation chain, to let these know that no further events will be sent.
|
||||
When the gesture enters recognition, or at a later point in time,
|
||||
the widget may choose to claim the touch sequences (individually
|
||||
or as a group), hence stopping event propagation after the event
|
||||
is run through every gesture in that widget and propagation phase.
|
||||
Anytime this happens, the touch sequences are cancelled downwards
|
||||
the propagation chain, to let these know that no further events
|
||||
will be sent.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Alternatively, or at a later point in time, the widget may choose to deny the touch
|
||||
sequences, thus letting those go through again in event propagation. When this happens
|
||||
in the capture phase, and if there are no other claiming gestures in the widget,
|
||||
Alternatively, or at a later point in time, the widget may choose
|
||||
to deny the touch sequences, thus letting those go through again
|
||||
in event propagation. When this happens in the capture phase, and
|
||||
if there are no other claiming gestures in the widget,
|
||||
a %GDK_TOUCH_BEGIN/%GDK_BUTTON_PRESS event will be emulated and
|
||||
propagated downwards, in order to preserve consistency.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Grouped gestures always share the same state for a given touch sequence, so setting
|
||||
the state on one does transfer the state to the others. They also are mutually exclusive,
|
||||
within a widget there may be only one gesture group claiming a given sequence. If
|
||||
another gesture group claims later that same sequence, the first group will deny the
|
||||
sequence.
|
||||
Grouped gestures always share the same state for a given touch
|
||||
sequence, so setting the state on one does transfer the state to
|
||||
the others. They also are mutually exclusive, within a widget
|
||||
there may be only one gesture group claiming a given sequence.
|
||||
If another gesture group claims later that same sequence, the
|
||||
first group will deny the sequence.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
|
||||
@@ -333,6 +333,7 @@ images = [
|
||||
]
|
||||
|
||||
content_files = [
|
||||
'actions.xml',
|
||||
'broadway.xml',
|
||||
'building.sgml',
|
||||
'compiling.sgml',
|
||||
@@ -368,6 +369,7 @@ content_files = [
|
||||
]
|
||||
|
||||
expand_content_files = [
|
||||
'actions.xml',
|
||||
'compiling.sgml',
|
||||
'drawing-model.xml',
|
||||
'glossary.xml',
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
compared to GTK 3.x. Thankfully, most of the changes are not hard
|
||||
to adapt to and there are a number of steps that you can take to
|
||||
prepare your GTK 3.x application for the switch to GTK 4. After
|
||||
that, there's a small number of adjustments that you may have to do
|
||||
that, there's a number of adjustments that you may have to do
|
||||
when you actually switch your application to build against GTK 4.
|
||||
</para>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
The steps outlined in the following sections assume that your
|
||||
application is working with GTK 3.24, which is the final stable
|
||||
release of GTK 3.x. It includes all the necessary APIs and tools
|
||||
to help you port your application to GTK 4. If you are still using
|
||||
to help you port your application to GTK 4. If you are using
|
||||
an older version of GTK 3.x, you should first get your application
|
||||
to build and work with the latest minor release in the 3.24 series.
|
||||
</para>
|
||||
@@ -84,9 +84,9 @@
|
||||
</para>
|
||||
<para>
|
||||
GTK 4 also removes the GDK_WA_VISUAL flag, and always uses
|
||||
an RGBA visual for windows. To prepare your code for this,
|
||||
use gdk_window_set_visual (gdk_screen_get_rgba_visual ()) after
|
||||
creating your window.
|
||||
an RGBA visual for windows. To prepare your code for this, use
|
||||
<literal>gdk_window_set_visual (gdk_screen_get_rgba_visual ())</literal>
|
||||
after creating your window.
|
||||
</para>
|
||||
<para>
|
||||
GTK 4 also removes the GDK_WA_WMCLASS flag. If you need this
|
||||
@@ -110,7 +110,7 @@
|
||||
<section>
|
||||
<title>Stop using GtkBox:padding, GtkBox:fill and GtkBox:expand</title>
|
||||
<para>
|
||||
GTK4 removes these #GtkBox child properties, so you should not use them.
|
||||
GTK 4 removes these #GtkBox child properties, so you should not use them.
|
||||
You can replace GtkBox:padding using the #GtkWidget:margin properties
|
||||
on your #GtkBox child widgets.
|
||||
</para>
|
||||
@@ -172,35 +172,30 @@
|
||||
<section>
|
||||
<title>Stop using GtkWidget event signals</title>
|
||||
<para>
|
||||
Event controllers and #GtkGestures replace event signals in GTK 4. They
|
||||
have been backported to GTK 3.x so you can prepare for this change.
|
||||
Event controllers and #GtkGestures replace event signals in GTK 4.
|
||||
They have been backported to GTK 3.x so you can prepare for this change.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Set a proper app_id</title>
|
||||
<title>Set a proper application ID</title>
|
||||
<para>
|
||||
In GTK4 we want the application's #GApplication
|
||||
In GTK 4 we want the application's #GApplication
|
||||
'application-id' (and therefore the D-Bus name), the desktop
|
||||
file basename and Wayland's xdg-shell app_id to match. In
|
||||
order to achieve this with GTK3 call g_set_prgname() with the same
|
||||
application id you passed to #GtkApplication. Rename your
|
||||
desktop files to match the application id if needed.
|
||||
order to achieve this with GTK 3.x call g_set_prgname() with the same
|
||||
application ID you passed to #GtkApplication. Rename your
|
||||
desktop files to match the application ID if needed.
|
||||
</para>
|
||||
<para>
|
||||
The call to g_set_prgname() can be removed once you fully migrated
|
||||
to GTK4.
|
||||
to GTK 4.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using GtkBox's pack-type child property</title>
|
||||
<para>
|
||||
In order to improve performance and simplify the widget, GtkBox lost its
|
||||
'pack-type' child property. In GTK4, every GtkBox instance has a simple
|
||||
list of child widgets that it allocates from start to end.
|
||||
The old behavior of pack-type=END can be emulated by simply making the
|
||||
box child in the center hexpand and right-align the ones at the end.
|
||||
You should be aware that changing the application ID makes your
|
||||
application appear as a new, different app to application installers.
|
||||
You should consult the appstream documentation for best practices
|
||||
around renaming applications.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -216,6 +211,17 @@
|
||||
have been either impossible or impractical.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Convert your ui files</title>
|
||||
|
||||
<para>
|
||||
A number of the changes outlined below affect .ui files. The
|
||||
gtk4-builder-tool simplify command can perform many of the
|
||||
necessary changes automatically, when called with the --3to4
|
||||
option. You should always review the resulting changes.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using GdkScreen</title>
|
||||
<para>
|
||||
@@ -301,9 +307,9 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to coordinate api changes</title>
|
||||
<title>Adapt to coordinate API changes</title>
|
||||
<para>
|
||||
A number of coordinate apis in GTK 3 had _double variants:
|
||||
A number of coordinate APIs in GTK 3 had _double variants:
|
||||
gdk_device_get_position(), gdk_device_get_surface_at_position(),
|
||||
gdk_surface_get_device_position(). These have been changed to use
|
||||
doubles, and the _double variants have been removed. Update your
|
||||
@@ -395,6 +401,10 @@
|
||||
their #GError argument. If you want to handle CSS loading errors,
|
||||
use the #GtkCssProvider::parsing-error signal instead.
|
||||
</para>
|
||||
<para>
|
||||
gtk_css_provider_get_named() has been replaced by
|
||||
gtk_css_provider_load_named().
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -411,7 +421,7 @@
|
||||
<para>
|
||||
GTK 3 used five different virtual functions in GtkWidget to
|
||||
implement size requisition, namely the gtk_widget_get_preferred_width()
|
||||
family of functions. To simplify widget implementations, GTK4 uses
|
||||
family of functions. To simplify widget implementations, GTK 4 uses
|
||||
only one virtual function, GtkWidgetClass::measure() that widgets
|
||||
have to implement.
|
||||
</para>
|
||||
@@ -640,7 +650,7 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to changes in the API of GtkEntry, GtkSearchEntry adn GtkSpinButton</title>
|
||||
<title>Adapt to changes in the API of GtkEntry, GtkSearchEntry and GtkSpinButton</title>
|
||||
<para>
|
||||
The GtkEditable has been made more useful, and the core functionality of
|
||||
GtkEntry has been broken out as a GtkText widget. GtkEntry, GtkSearchEntry,
|
||||
@@ -675,6 +685,77 @@
|
||||
of the existing GtkFixed container widget.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to search entry changes</title>
|
||||
<para>
|
||||
The way search entries are connected to global events has changed;
|
||||
gtk_search_entry_handle_event() has been dropped and replaced by
|
||||
gtk_search_entry_set_key_capture_widget() and
|
||||
gtk_event_controller_key_forward().
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using child properties</title>
|
||||
<para>
|
||||
GtkContainer no longer provides facilities for defining and using
|
||||
child properties. If you have custom widgets using child properties,
|
||||
they will have to be converted either to layout properties provided
|
||||
by a layout manager (if they are layout-related), or handled in
|
||||
some other way. One possibility is to use child meta objects,
|
||||
as seen with GtkAssistantPage, GtkStackPage and the like.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using tabular menus</title>
|
||||
<para>
|
||||
Tabular menus were rarely used and complicated the menu code,
|
||||
so they have been removed. If you need complex layout in menu-like
|
||||
popups, consider using a #GtkPopover instead.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using gtk_menu_set_display()</title>
|
||||
<para>
|
||||
This function has been removed. Menus should always be
|
||||
attached to a widget and get their display that way.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using gtk_window_activate_default()</title>
|
||||
<para>
|
||||
The handling of default widgets has been changed, and activating
|
||||
the default now works by calling gtk_widget_activate_default()
|
||||
on the widget that caused the activation.
|
||||
</para>
|
||||
<para>
|
||||
If you have a custom widget that wants to override the default
|
||||
handling, you can provide an implementation of the default.activate
|
||||
action in your widgets' action groups.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop setting ::has-default and ::has-focus in .ui files</title>
|
||||
<para>
|
||||
The special handling for the ::has-default and ::has-focus properties
|
||||
has been removed. If you want to define the initial focus or the
|
||||
the default widget in a .ui file, set the ::default-widget or
|
||||
::focus-widget properties of the toplevel window.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using the GtkWidget::display-changed signal</title>
|
||||
<para>
|
||||
To track the current display, use the GtkWidget::root property
|
||||
instead.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -79,12 +79,30 @@ Use a GdkPixbuf in combination with GtkImage to display images.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>graphene</term>
|
||||
<listitem><para>
|
||||
This is a small library which provides vector and matrix datatypes
|
||||
and operations. graphene provides optimized implementations using
|
||||
various SIMD instruction sets such as SSE.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>GDK</term>
|
||||
<listitem><para>
|
||||
GDK is the abstraction layer that allows GTK to support multiple
|
||||
windowing systems. GDK provides window system facilities on X11, Windows,
|
||||
and OS X.
|
||||
windowing systems. GDK provides window system facilities on Wayland,
|
||||
X11, Windows, and OS X.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>GSK</term>
|
||||
<listitem><para>
|
||||
GSK is a library for creating a scene graph from render nodes,
|
||||
and rendering it using different rendering APIs. GSK provides renderers
|
||||
for OpenGL, Vulkan and cairo.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
+36
-3
@@ -146,15 +146,48 @@ gdk_event_class_init (GdkEventClass *klass)
|
||||
g_object_class_install_properties (object_class, N_PROPS, event_props);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_event_emit (GdkEvent *event)
|
||||
gboolean
|
||||
check_event_sanity (GdkEvent *event)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkSurface *surface;
|
||||
GdkDevice *device;
|
||||
|
||||
display = gdk_event_get_display (event);
|
||||
surface = gdk_event_get_surface (event);
|
||||
device = gdk_event_get_device (event);
|
||||
|
||||
if (gdk_event_get_event_type (event) == GDK_NOTHING)
|
||||
{
|
||||
g_warning ("Ignoring GDK_NOTHING events; they're good for nothing");
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (surface && display != gdk_surface_get_display (surface))
|
||||
{
|
||||
char *type = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event->any.type);
|
||||
g_warning ("Event of type %s with mismatched surface display", type);
|
||||
g_free (type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (device && display != gdk_device_get_display (device))
|
||||
{
|
||||
char *type = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event->any.type);
|
||||
g_warning ("Event of type %s with mismatched device display", type);
|
||||
g_free (type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_event_emit (GdkEvent *event)
|
||||
{
|
||||
if (!check_event_sanity (event))
|
||||
return;
|
||||
|
||||
if (gdk_drag_handle_source_event (event))
|
||||
return;
|
||||
|
||||
|
||||
@@ -645,5 +645,7 @@ void gdk_event_set_related_target (GdkEvent *event,
|
||||
GObject *user_data);
|
||||
GObject * gdk_event_get_related_target (const GdkEvent *event);
|
||||
|
||||
gboolean check_event_sanity (GdkEvent *event);
|
||||
|
||||
|
||||
#endif /* __GDK_EVENTS_PRIVATE_H__ */
|
||||
|
||||
@@ -293,6 +293,7 @@ gdk_seat_grab (GdkSeat *seat,
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SEAT (seat), GDK_GRAB_FAILED);
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), GDK_GRAB_FAILED);
|
||||
g_return_val_if_fail (gdk_surface_get_display (surface) == gdk_seat_get_display (seat), GDK_GRAB_FAILED);
|
||||
|
||||
capabilities &= GDK_SEAT_CAPABILITY_ALL;
|
||||
g_return_val_if_fail (capabilities != GDK_SEAT_CAPABILITY_NONE, GDK_GRAB_FAILED);
|
||||
|
||||
@@ -107,6 +107,7 @@ enum {
|
||||
PROP_0,
|
||||
PROP_CURSOR,
|
||||
PROP_DISPLAY,
|
||||
PROP_FRAME_CLOCK,
|
||||
PROP_STATE,
|
||||
PROP_MAPPED,
|
||||
LAST_PROP
|
||||
@@ -268,6 +269,13 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_FRAME_CLOCK] =
|
||||
g_param_spec_object ("frame-clock",
|
||||
P_("Frame Clock"),
|
||||
P_("Frame Clock"),
|
||||
GDK_TYPE_FRAME_CLOCK,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_STATE] =
|
||||
g_param_spec_flags ("state",
|
||||
P_("State"),
|
||||
@@ -462,6 +470,10 @@ gdk_surface_set_property (GObject *object,
|
||||
g_assert (surface->display != NULL);
|
||||
break;
|
||||
|
||||
case PROP_FRAME_CLOCK:
|
||||
gdk_surface_set_frame_clock (surface, GDK_FRAME_CLOCK (g_value_get_object (value)));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -486,6 +498,10 @@ gdk_surface_get_property (GObject *object,
|
||||
g_value_set_object (value, surface->display);
|
||||
break;
|
||||
|
||||
case PROP_FRAME_CLOCK:
|
||||
g_value_set_object (value, surface->frame_clock);
|
||||
break;
|
||||
|
||||
case PROP_STATE:
|
||||
g_value_set_flags (value, surface->state);
|
||||
break;
|
||||
|
||||
@@ -5028,31 +5028,29 @@ _gdk_wayland_device_get_implicit_grab_serial (GdkWaylandDevice *device,
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_WAYLAND_SEAT (seat)->pointer_info.press_serial;
|
||||
return GDK_WAYLAND_SEAT (seat)->pointer_info.press_serial;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
_gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *seat,
|
||||
_gdk_wayland_seat_get_last_implicit_grab_serial (GdkWaylandSeat *seat,
|
||||
GdkEventSequence **sequence)
|
||||
{
|
||||
GdkWaylandSeat *wayland_seat;
|
||||
GdkWaylandTouchData *touch;
|
||||
GHashTableIter iter;
|
||||
GList *l;
|
||||
uint32_t serial;
|
||||
|
||||
wayland_seat = GDK_WAYLAND_SEAT (seat);
|
||||
g_hash_table_iter_init (&iter, wayland_seat->touches);
|
||||
g_hash_table_iter_init (&iter, seat->touches);
|
||||
|
||||
if (sequence)
|
||||
*sequence = NULL;
|
||||
|
||||
serial = wayland_seat->keyboard_key_serial;
|
||||
serial = seat->keyboard_key_serial;
|
||||
|
||||
if (wayland_seat->pointer_info.press_serial > serial)
|
||||
serial = wayland_seat->pointer_info.press_serial;
|
||||
if (seat->pointer_info.press_serial > serial)
|
||||
serial = seat->pointer_info.press_serial;
|
||||
|
||||
for (l = wayland_seat->tablets; l; l = l->next)
|
||||
for (l = seat->tablets; l; l = l->next)
|
||||
{
|
||||
GdkWaylandTabletData *tablet = l->data;
|
||||
|
||||
|
||||
@@ -396,6 +396,8 @@ static void gdk_wayland_display_add_output (GdkWaylandDisplay *display_wa
|
||||
guint32 version);
|
||||
static void gdk_wayland_display_remove_output (GdkWaylandDisplay *display_wayland,
|
||||
guint32 id);
|
||||
static void gdk_wayland_display_init_xdg_output (GdkWaylandDisplay *display_wayland);
|
||||
static void gdk_wayland_display_get_xdg_output (GdkWaylandMonitor *monitor);
|
||||
|
||||
static void
|
||||
gdk_registry_handle_global (void *data,
|
||||
@@ -527,6 +529,13 @@ gdk_registry_handle_global (void *data,
|
||||
&server_decoration_listener,
|
||||
display_wayland);
|
||||
}
|
||||
else if (strcmp(interface, "zxdg_output_manager_v1") == 0)
|
||||
{
|
||||
display_wayland->xdg_output_manager =
|
||||
wl_registry_bind (registry, id, &zxdg_output_manager_v1_interface, 1);
|
||||
gdk_wayland_display_init_xdg_output (display_wayland);
|
||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||
}
|
||||
|
||||
g_hash_table_insert (display_wayland->known_globals,
|
||||
GUINT_TO_POINTER (id), g_strdup (interface));
|
||||
@@ -2170,6 +2179,123 @@ update_scale (GdkDisplay *display)
|
||||
g_list_free (seats);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_display_init_xdg_output (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
int i;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("init xdg-output support, %d monitor(s) already present",
|
||||
display_wayland->monitors->len));
|
||||
|
||||
for (i = 0; i < display_wayland->monitors->len; i++)
|
||||
gdk_wayland_display_get_xdg_output (display_wayland->monitors->pdata[i]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
display_has_xdg_output_support (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
return (display_wayland->xdg_output_manager != NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
monitor_has_xdg_output (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
return (monitor->xdg_output != NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_update_monitor (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
return (GDK_MONITOR (monitor)->geometry.width != 0 &&
|
||||
monitor->version < OUTPUT_VERSION_WITH_DONE);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("monitor %d changed position %d %d, size %d %d",
|
||||
monitor->id,
|
||||
monitor->x, monitor->y,
|
||||
monitor->width, monitor->height));
|
||||
|
||||
gdk_monitor_set_position (GDK_MONITOR (monitor), monitor->x, monitor->y);
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), monitor->width, monitor->height);
|
||||
monitor->wl_output_done = FALSE;
|
||||
monitor->xdg_output_done = FALSE;
|
||||
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_position (void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
int32_t x,
|
||||
int32_t y)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle logical position xdg-output %d, position %d %d",
|
||||
monitor->id, x, y));
|
||||
monitor->x = x;
|
||||
monitor->y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_size (void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle logical size xdg-output %d, size %d %d",
|
||||
monitor->id, width, height));
|
||||
monitor->width = width;
|
||||
monitor->height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_done (void *data,
|
||||
struct zxdg_output_v1 *xdg_output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle done xdg-output %d", monitor->id));
|
||||
|
||||
monitor->xdg_output_done = TRUE;
|
||||
if (monitor->wl_output_done)
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
xdg_output_handle_logical_position,
|
||||
xdg_output_handle_logical_size,
|
||||
xdg_output_handle_done,
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_wayland_display_get_xdg_output (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
GdkDisplay *display = GDK_MONITOR (monitor)->display;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("get xdg-output for monitor %d", monitor->id));
|
||||
|
||||
monitor->xdg_output =
|
||||
zxdg_output_manager_v1_get_xdg_output (display_wayland->xdg_output_manager,
|
||||
monitor->output);
|
||||
|
||||
zxdg_output_v1_add_listener (monitor->xdg_output,
|
||||
&xdg_output_listener,
|
||||
monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_geometry (void *data,
|
||||
struct wl_output *wl_output,
|
||||
@@ -2188,13 +2314,17 @@ output_handle_geometry (void *data,
|
||||
g_message ("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s",
|
||||
monitor->id, x, y, physical_width, physical_height, subpixel_to_string (subpixel), make, model, transform_to_string (transform)));
|
||||
|
||||
gdk_monitor_set_position (GDK_MONITOR (monitor), x, y);
|
||||
monitor->x = x;
|
||||
monitor->y = y;
|
||||
gdk_monitor_set_physical_size (GDK_MONITOR (monitor), physical_width, physical_height);
|
||||
gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor), subpixel);
|
||||
gdk_monitor_set_manufacturer (GDK_MONITOR (monitor), make);
|
||||
gdk_monitor_set_model (GDK_MONITOR (monitor), model);
|
||||
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
|
||||
apply_monitor_change (monitor);
|
||||
|
||||
if (should_update_monitor (monitor))
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
}
|
||||
|
||||
@@ -2203,19 +2333,14 @@ output_handle_done (void *data,
|
||||
struct wl_output *wl_output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
GdkDisplay *display = gdk_monitor_get_display (GDK_MONITOR (monitor));
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle done output %d", monitor->id));
|
||||
|
||||
if (!monitor->added)
|
||||
{
|
||||
monitor->added = TRUE;
|
||||
g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
|
||||
gdk_display_monitor_added (display, GDK_MONITOR (monitor));
|
||||
}
|
||||
monitor->wl_output_done = TRUE;
|
||||
|
||||
update_scale (display);
|
||||
if (!monitor_has_xdg_output (monitor) || monitor->xdg_output_done)
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2232,6 +2357,9 @@ output_handle_scale (void *data,
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle scale output %d, scale %d", monitor->id, scale));
|
||||
|
||||
if (monitor_has_xdg_output (monitor))
|
||||
return;
|
||||
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (monitor), &previous_geometry);
|
||||
previous_scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
|
||||
@@ -2239,10 +2367,11 @@ output_handle_scale (void *data,
|
||||
height = previous_geometry.height * previous_scale;
|
||||
|
||||
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
|
||||
monitor->width = width / scale;
|
||||
monitor->height = height / scale;
|
||||
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
if (should_update_monitor (monitor))
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2264,11 +2393,12 @@ output_handle_mode (void *data,
|
||||
return;
|
||||
|
||||
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
|
||||
monitor->width = width / scale;
|
||||
monitor->height = height / scale;
|
||||
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
|
||||
|
||||
if (width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener =
|
||||
@@ -2295,13 +2425,17 @@ gdk_wayland_display_add_output (GdkWaylandDisplay *display_wayland,
|
||||
monitor->output = output;
|
||||
monitor->version = version;
|
||||
|
||||
if (monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
g_ptr_array_add (display_wayland->monitors, monitor);
|
||||
gdk_display_monitor_added (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
|
||||
}
|
||||
g_ptr_array_add (display_wayland->monitors, monitor);
|
||||
gdk_display_monitor_added (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
|
||||
|
||||
wl_output_add_listener (output, &output_listener, monitor);
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("xdg_output_manager %p",
|
||||
display_wayland->xdg_output_manager));
|
||||
|
||||
if (display_has_xdg_output_support (display_wayland))
|
||||
gdk_wayland_display_get_xdg_output (monitor);
|
||||
}
|
||||
|
||||
struct wl_output *
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <gdk/wayland/xdg-foreign-unstable-v1-client-protocol.h>
|
||||
#include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h>
|
||||
#include <gdk/wayland/server-decoration-client-protocol.h>
|
||||
#include <gdk/wayland/xdg-output-unstable-v1-client-protocol.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkkeys.h>
|
||||
@@ -109,6 +110,7 @@ struct _GdkWaylandDisplay
|
||||
struct zxdg_importer_v1 *xdg_importer;
|
||||
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
|
||||
struct org_kde_kwin_server_decoration_manager *server_decoration_manager;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
|
||||
GList *async_roundtrips;
|
||||
|
||||
|
||||
@@ -151,6 +151,9 @@ _gdk_wayland_display_deliver_event (GdkDisplay *display,
|
||||
{
|
||||
GList *node;
|
||||
|
||||
if (!check_event_sanity (event))
|
||||
g_warning ("Snap! delivering insane events\n");
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event,
|
||||
_gdk_display_get_next_serial (display));
|
||||
|
||||
@@ -30,6 +30,15 @@ struct _GdkWaylandMonitor {
|
||||
guint32 version;
|
||||
struct wl_output *output;
|
||||
gboolean added;
|
||||
|
||||
struct zxdg_output_v1 *xdg_output;
|
||||
/* Size and position, can be either from wl_output or xdg_output */
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
gboolean wl_output_done;
|
||||
gboolean xdg_output_done;
|
||||
};
|
||||
|
||||
struct _GdkWaylandMonitorClass {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <gdk/gdkcursor.h>
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#include <gdk/wayland/gdkdisplay-wayland.h>
|
||||
#include <gdk/wayland/gdkseat-wayland.h>
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
@@ -138,7 +139,7 @@ void _gdk_wayland_display_remove_seat (GdkWaylandDisplay *displa
|
||||
GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device);
|
||||
uint32_t _gdk_wayland_device_get_implicit_grab_serial(GdkWaylandDevice *device,
|
||||
const GdkEvent *event);
|
||||
uint32_t _gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *seat,
|
||||
uint32_t _gdk_wayland_seat_get_last_implicit_grab_serial (GdkWaylandSeat *seat,
|
||||
GdkEventSequence **seqence);
|
||||
struct wl_data_device * gdk_wayland_device_get_data_device (GdkDevice *gdk_device);
|
||||
void gdk_wayland_device_set_selection (GdkDevice *gdk_device,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkmonitor-wayland.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -861,7 +862,7 @@ gdk_wayland_surface_update_dialogs (GdkSurface *surface)
|
||||
GdkSurface *w = l->data;
|
||||
GdkSurfaceImplWayland *impl;
|
||||
|
||||
if (!GDK_IS_SURFACE_IMPL_WAYLAND(w->impl))
|
||||
if (!GDK_IS_SURFACE_IMPL_WAYLAND (w->impl))
|
||||
continue;
|
||||
|
||||
impl = GDK_SURFACE_IMPL_WAYLAND (w->impl);
|
||||
@@ -2185,14 +2186,12 @@ create_simple_positioner (GdkSurface *surface,
|
||||
static void
|
||||
gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
GdkSurface *parent,
|
||||
struct wl_seat *seat)
|
||||
GdkWaylandSeat *grab_input_seat)
|
||||
{
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
|
||||
GdkSurfaceImplWayland *parent_impl = GDK_SURFACE_IMPL_WAYLAND (parent->impl);
|
||||
gpointer positioner;
|
||||
GdkSeat *gdk_seat;
|
||||
guint32 serial;
|
||||
|
||||
if (!impl->display_server.wl_surface)
|
||||
return;
|
||||
@@ -2210,10 +2209,11 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
g_warning ("Can't map popup, already mapped");
|
||||
return;
|
||||
}
|
||||
if ((display->current_popups &&
|
||||
g_list_last (display->current_popups)->data != parent) ||
|
||||
(!display->current_popups &&
|
||||
!is_realized_toplevel (parent)))
|
||||
if (grab_input_seat &&
|
||||
((display->current_popups &&
|
||||
g_list_last (display->current_popups)->data != parent) ||
|
||||
(!display->current_popups &&
|
||||
!is_realized_toplevel (parent))))
|
||||
{
|
||||
g_warning ("Tried to map a popup with a non-top most parent");
|
||||
return;
|
||||
@@ -2264,10 +2264,13 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (seat)
|
||||
if (grab_input_seat)
|
||||
{
|
||||
gdk_seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_seat, NULL);
|
||||
struct wl_seat *seat;
|
||||
guint32 serial;
|
||||
|
||||
seat = gdk_wayland_seat_get_wl_seat (GDK_SEAT (grab_input_seat));
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (grab_input_seat, NULL);
|
||||
|
||||
switch (display->shell_variant)
|
||||
{
|
||||
@@ -2288,7 +2291,7 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
display->current_popups = g_list_append (display->current_popups, surface);
|
||||
}
|
||||
|
||||
static struct wl_seat *
|
||||
static GdkWaylandSeat *
|
||||
find_grab_input_seat (GdkSurface *surface,
|
||||
GdkSurface *transient_for)
|
||||
{
|
||||
@@ -2301,7 +2304,7 @@ find_grab_input_seat (GdkSurface *surface,
|
||||
* grab before showing the popup surface.
|
||||
*/
|
||||
if (impl->grab_input_seat)
|
||||
return gdk_wayland_seat_get_wl_seat (impl->grab_input_seat);
|
||||
return GDK_WAYLAND_SEAT (impl->grab_input_seat);
|
||||
|
||||
/* HACK: GtkMenu grabs a special surface known as the "grab transfer surface"
|
||||
* and then transfers the grab over to the correct surface later. Look for
|
||||
@@ -2314,7 +2317,7 @@ find_grab_input_seat (GdkSurface *surface,
|
||||
{
|
||||
tmp_impl = GDK_SURFACE_IMPL_WAYLAND (attached_grab_surface->impl);
|
||||
if (tmp_impl->grab_input_seat)
|
||||
return gdk_wayland_seat_get_wl_seat (tmp_impl->grab_input_seat);
|
||||
return GDK_WAYLAND_SEAT (tmp_impl->grab_input_seat);
|
||||
}
|
||||
|
||||
while (transient_for)
|
||||
@@ -2322,7 +2325,7 @@ find_grab_input_seat (GdkSurface *surface,
|
||||
tmp_impl = GDK_SURFACE_IMPL_WAYLAND (transient_for->impl);
|
||||
|
||||
if (tmp_impl->grab_input_seat)
|
||||
return gdk_wayland_seat_get_wl_seat (tmp_impl->grab_input_seat);
|
||||
return GDK_WAYLAND_SEAT (tmp_impl->grab_input_seat);
|
||||
|
||||
transient_for = tmp_impl->transient_for;
|
||||
}
|
||||
@@ -2418,7 +2421,7 @@ gdk_wayland_surface_map (GdkSurface *surface)
|
||||
if (should_map_as_popup (surface))
|
||||
{
|
||||
gboolean create_fallback = FALSE;
|
||||
struct wl_seat *grab_input_seat;
|
||||
GdkWaylandSeat *grab_input_seat;
|
||||
|
||||
/* Popup menus can appear without a transient parent, which means they
|
||||
* cannot be positioned properly on Wayland. This attempts to guess the
|
||||
@@ -2492,8 +2495,8 @@ gdk_wayland_surface_map (GdkSurface *surface)
|
||||
if (!create_fallback)
|
||||
{
|
||||
gdk_wayland_surface_create_xdg_popup (surface,
|
||||
transient_for,
|
||||
grab_input_seat);
|
||||
transient_for,
|
||||
grab_input_seat);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3581,7 +3584,7 @@ gdk_wayland_surface_begin_resize_drag (GdkSurface *surface,
|
||||
if (!is_realized_toplevel (surface))
|
||||
return;
|
||||
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_device_get_seat (device),
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (gdk_device_get_seat (device)),
|
||||
&sequence);
|
||||
|
||||
switch (display_wayland->shell_variant)
|
||||
@@ -3632,7 +3635,7 @@ gdk_wayland_surface_begin_move_drag (GdkSurface *surface,
|
||||
if (!is_realized_toplevel (surface))
|
||||
return;
|
||||
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_device_get_seat (device),
|
||||
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (gdk_device_get_seat (device)),
|
||||
&sequence);
|
||||
switch (display_wayland->shell_variant)
|
||||
{
|
||||
|
||||
@@ -58,6 +58,7 @@ proto_sources = [
|
||||
['tablet', 'unstable', 'v2', ],
|
||||
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
|
||||
['server-decoration', 'private' ],
|
||||
['xdg-output', 'unstable', 'v1', ],
|
||||
]
|
||||
|
||||
gdk_wayland_gen_headers = []
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32CairoContext, gdk_win32_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
|
||||
|
||||
static void
|
||||
void
|
||||
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||
gint scale,
|
||||
RECT *return_window_rect)
|
||||
@@ -53,7 +53,7 @@ gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||
*return_window_rect = window_rect;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
|
||||
RECT window_rect)
|
||||
{
|
||||
|
||||
@@ -166,6 +166,27 @@ gdk_win32_gl_context_begin_frame (GdkDrawContext *draw_context,
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkSurface *surface;
|
||||
GdkSurfaceImplWin32 *impl;
|
||||
RECT queued_window_rect;
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
impl = GDK_SURFACE_IMPL_WIN32 (surface->impl);
|
||||
|
||||
gdk_win32_surface_get_queued_window_rect (surface,
|
||||
gdk_surface_get_scale_factor (surface),
|
||||
&queued_window_rect);
|
||||
|
||||
/* Apply queued resizes GL windows before painting them
|
||||
* (we paint on the window DC directly, it must have the right size).
|
||||
* Due to some poorly-understood issue delayed
|
||||
* resizing of double-buffered windows can produce weird
|
||||
* artefacts, so these are also resized before we paint.
|
||||
*/
|
||||
if (impl->drag_move_resize_context.native_move_resize_pending)
|
||||
{
|
||||
impl->drag_move_resize_context.native_move_resize_pending = FALSE;
|
||||
gdk_win32_surface_apply_queued_move_resize (surface, queued_window_rect);
|
||||
}
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_parent_class)->begin_frame (draw_context, update_area);
|
||||
if (gdk_gl_context_get_shared_context (context))
|
||||
@@ -176,7 +197,6 @@ gdk_win32_gl_context_begin_frame (GdkDrawContext *draw_context,
|
||||
|
||||
/* If nothing else is known, repaint everything so that the back
|
||||
buffer is fully up-to-date for the swapbuffer */
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
cairo_region_union_rectangle (update_area, &(GdkRectangle) {
|
||||
0, 0,
|
||||
gdk_surface_get_width (surface),
|
||||
|
||||
@@ -384,6 +384,15 @@ void _gdk_win32_update_layered_window_from_cache (GdkSurface *window,
|
||||
gboolean do_paint);
|
||||
|
||||
|
||||
void
|
||||
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
|
||||
gint scale,
|
||||
RECT *return_window_rect);
|
||||
|
||||
void
|
||||
gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
|
||||
RECT window_rect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_SURFACE_WIN32_H__ */
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
|
||||
|
||||
#define APPEARS_FOCUSED(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_focus_window || (toplevel)->has_pointer_focus)
|
||||
#define HAS_FOCUS(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
|
||||
|
||||
static void gdk_x11_device_manager_core_finalize (GObject *object);
|
||||
static void gdk_x11_device_manager_core_constructed (GObject *object);
|
||||
@@ -752,7 +752,7 @@ _gdk_device_manager_core_handle_focus (GdkSurface *surface,
|
||||
if (toplevel->focus_window == original)
|
||||
return;
|
||||
|
||||
had_focus = APPEARS_FOCUSED (toplevel);
|
||||
had_focus = HAS_FOCUS (toplevel);
|
||||
x11_screen = GDK_X11_SCREEN (GDK_SURFACE_SCREEN (surface));
|
||||
|
||||
switch (detail)
|
||||
@@ -814,7 +814,7 @@ _gdk_device_manager_core_handle_focus (GdkSurface *surface,
|
||||
break;
|
||||
}
|
||||
|
||||
if (APPEARS_FOCUSED (toplevel) != had_focus)
|
||||
if (HAS_FOCUS (toplevel) != had_focus)
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ static void gdk_event_source_finalize (GSource *source);
|
||||
|
||||
static GQuark quark_needs_enter = 0;
|
||||
|
||||
#define APPEARS_FOCUSED(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_focus_window || (toplevel)->has_pointer_focus)
|
||||
#define HAS_FOCUS(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
|
||||
|
||||
struct _GdkEventSource
|
||||
{
|
||||
@@ -108,10 +108,10 @@ handle_focus_change (GdkEventCrossing *event)
|
||||
if (!event->focus || toplevel->has_focus_window)
|
||||
return;
|
||||
|
||||
had_focus = APPEARS_FOCUSED (toplevel);
|
||||
had_focus = HAS_FOCUS (toplevel);
|
||||
toplevel->has_pointer_focus = focus_in;
|
||||
|
||||
if (APPEARS_FOCUSED (toplevel) != had_focus)
|
||||
if (HAS_FOCUS (toplevel) != had_focus)
|
||||
{
|
||||
GdkEvent *focus_event;
|
||||
|
||||
|
||||
@@ -1867,6 +1867,14 @@ gdk_x11_surface_set_modal_hint (GdkSurface *surface,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_surface_set_skip_taskbar_hint:
|
||||
* @surface: (type GdkX11Surface): a native #GdkSurface
|
||||
* @skips_taskbar: %TRUE to skip taskbars
|
||||
*
|
||||
* Sets a hint on @surface that taskbars should not
|
||||
* display it. See the EWMH for details.
|
||||
*/
|
||||
void
|
||||
gdk_x11_surface_set_skip_taskbar_hint (GdkSurface *surface,
|
||||
gboolean skips_taskbar)
|
||||
@@ -1888,6 +1896,14 @@ gdk_x11_surface_set_skip_taskbar_hint (GdkSurface *surface,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_surface_set_skip_pager_hint:
|
||||
* @surface: (type GdkX11Surface): a #GdkSurface
|
||||
* @skips_pager: %TRUE to skip pagers
|
||||
*
|
||||
* Sets a hint on @surface that pagers should not
|
||||
* display it. See the EWMH for details.
|
||||
*/
|
||||
void
|
||||
gdk_x11_surface_set_skip_pager_hint (GdkSurface *surface,
|
||||
gboolean skips_pager)
|
||||
@@ -1909,6 +1925,14 @@ gdk_x11_surface_set_skip_pager_hint (GdkSurface *surface,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_surface_set_urgency_hint:
|
||||
* @surface: (type GdkX11Surface): a native #GdkSurface
|
||||
* @urgent: %TRUE to indicate urgenct attention needed
|
||||
*
|
||||
* Sets a hint on @surface that it needs user attention.
|
||||
* See the ICCCM for details.
|
||||
*/
|
||||
void
|
||||
gdk_x11_surface_set_urgency_hint (GdkSurface *surface,
|
||||
gboolean urgent)
|
||||
@@ -3377,6 +3401,14 @@ gdk_x11_surface_get_group (GdkSurface *surface)
|
||||
return toplevel->group_leader;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_surface_set_group:
|
||||
* @surface: (type GdkX11Surface): a native #GdkSurface
|
||||
* @leader: a #GdkSurface
|
||||
*
|
||||
* Sets the group leader of @surface to be @leader.
|
||||
* See the ICCCM for details.
|
||||
*/
|
||||
void
|
||||
gdk_x11_surface_set_group (GdkSurface *surface,
|
||||
GdkSurface *leader)
|
||||
|
||||
+41
-8
@@ -42,7 +42,6 @@
|
||||
|
||||
#include "gskdebugprivate.h"
|
||||
#include "gskrendererprivate.h"
|
||||
#include "gskrendernodeparserprivate.h"
|
||||
|
||||
#include <graphene-gobject.h>
|
||||
|
||||
@@ -329,11 +328,19 @@ gsk_render_node_diff (GskRenderNode *node1,
|
||||
GBytes *
|
||||
gsk_render_node_serialize (GskRenderNode *node)
|
||||
{
|
||||
GVariant *node_variant, *variant;
|
||||
GBytes *result;
|
||||
char *str;
|
||||
|
||||
str = gsk_render_node_serialize_to_string (node);
|
||||
result = g_bytes_new_take (str, strlen (str));
|
||||
node_variant = gsk_render_node_serialize_node (node);
|
||||
|
||||
variant = g_variant_new ("(suuv)",
|
||||
GSK_RENDER_NODE_SERIALIZATION_ID,
|
||||
(guint32) GSK_RENDER_NODE_SERIALIZATION_VERSION,
|
||||
(guint32) gsk_render_node_get_node_type (node),
|
||||
node_variant);
|
||||
|
||||
result = g_variant_get_data_as_bytes (variant);
|
||||
g_variant_unref (variant);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -387,13 +394,39 @@ gsk_render_node_write_to_file (GskRenderNode *node,
|
||||
* error.
|
||||
**/
|
||||
GskRenderNode *
|
||||
gsk_render_node_deserialize (GBytes *bytes,
|
||||
GskParseErrorFunc error_func,
|
||||
gpointer user_data)
|
||||
gsk_render_node_deserialize (GBytes *bytes,
|
||||
GError **error)
|
||||
{
|
||||
char *id_string;
|
||||
guint32 version, node_type;
|
||||
GVariant *variant, *node_variant;
|
||||
GskRenderNode *node = NULL;
|
||||
|
||||
node = gsk_render_node_deserialize_from_bytes (bytes, error_func, user_data);
|
||||
variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("(suuv)"), bytes, FALSE);
|
||||
|
||||
g_variant_get (variant, "(suuv)", &id_string, &version, &node_type, &node_variant);
|
||||
|
||||
if (!g_str_equal (id_string, GSK_RENDER_NODE_SERIALIZATION_ID))
|
||||
{
|
||||
g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_FORMAT,
|
||||
"Data not in GskRenderNode serialization format.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (version != GSK_RENDER_NODE_SERIALIZATION_VERSION)
|
||||
{
|
||||
g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_VERSION,
|
||||
"Format version %u not supported.", version);
|
||||
goto out;
|
||||
}
|
||||
|
||||
node = gsk_render_node_deserialize_node (node_type, node_variant, error);
|
||||
|
||||
out:
|
||||
g_free (id_string);
|
||||
g_variant_unref (node_variant);
|
||||
g_variant_unref (variant);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
+2
-8
@@ -25,7 +25,6 @@
|
||||
|
||||
#include <gsk/gskroundedrect.h>
|
||||
#include <gsk/gsktypes.h>
|
||||
#include <gtk/css/gtkcss.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -53,10 +52,6 @@ struct _GskShadow
|
||||
float radius;
|
||||
};
|
||||
|
||||
typedef void (* GskParseErrorFunc) (const GtkCssSection *section,
|
||||
const GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gsk_render_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
@@ -86,9 +81,8 @@ gboolean gsk_render_node_write_to_file (GskRenderNode *
|
||||
const char *filename,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_render_node_deserialize (GBytes *bytes,
|
||||
GskParseErrorFunc error_func,
|
||||
gpointer user_data);
|
||||
GskRenderNode * gsk_render_node_deserialize (GBytes *bytes,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_debug_node_new (GskRenderNode *child,
|
||||
|
||||
+1337
-9
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
|
||||
#ifndef __GSK_RENDER_NODE_PARSER_PRIVATE_H__
|
||||
#define __GSK_RENDER_NODE_PARSER_PRIVATE_H__
|
||||
|
||||
#include "gskrendernode.h"
|
||||
|
||||
GskRenderNode * gsk_render_node_deserialize_from_bytes (GBytes *bytes,
|
||||
GskParseErrorFunc error_func,
|
||||
gpointer user_data);
|
||||
char * gsk_render_node_serialize_to_string (GskRenderNode *root);
|
||||
|
||||
#endif
|
||||
@@ -33,6 +33,9 @@ struct _GskRenderNodeClass
|
||||
void (* diff) (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
GVariant * (* serialize) (GskRenderNode *node);
|
||||
GskRenderNode * (* deserialize) (GVariant *variant,
|
||||
GError **error);
|
||||
};
|
||||
|
||||
GskRenderNode * gsk_render_node_new (const GskRenderNodeClass *node_class,
|
||||
@@ -47,6 +50,11 @@ void gsk_render_node_diff_impossible (GskRenderNode *nod
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
|
||||
GVariant * gsk_render_node_serialize_node (GskRenderNode *node);
|
||||
GskRenderNode * gsk_render_node_deserialize_node (GskRenderNodeType type,
|
||||
GVariant *variant,
|
||||
GError **error);
|
||||
|
||||
GskRenderNode * gsk_cairo_node_new_for_surface (const graphene_rect_t *bounds,
|
||||
cairo_surface_t *surface);
|
||||
|
||||
|
||||
+13
-7
@@ -197,9 +197,10 @@ gsk_rounded_rect_offset (GskRoundedRect *self,
|
||||
}
|
||||
|
||||
static void
|
||||
border_radius_shrink (graphene_size_t *corner,
|
||||
double width,
|
||||
double height)
|
||||
border_radius_shrink (graphene_size_t *corner,
|
||||
double width,
|
||||
double height,
|
||||
const graphene_size_t *max)
|
||||
{
|
||||
if (corner->width > 0)
|
||||
corner->width -= width;
|
||||
@@ -211,6 +212,11 @@ border_radius_shrink (graphene_size_t *corner,
|
||||
corner->width = 0;
|
||||
corner->height = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
corner->width = MIN (corner->width, max->width);
|
||||
corner->height = MIN (corner->height, max->height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,10 +266,10 @@ gsk_rounded_rect_shrink (GskRoundedRect *self,
|
||||
self->bounds.size.height -= top + bottom;
|
||||
}
|
||||
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_TOP_LEFT], left, top);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_TOP_RIGHT], right, top);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_BOTTOM_RIGHT], right, bottom);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_BOTTOM_LEFT], left, bottom);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_TOP_LEFT], left, top, &self->bounds.size);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_TOP_RIGHT], right, top, &self->bounds.size);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_BOTTOM_RIGHT], right, bottom, &self->bounds.size);
|
||||
border_radius_shrink (&self->corner[GSK_CORNER_BOTTOM_LEFT], left, bottom, &self->bounds.size);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+24
-31
@@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:gsktransform
|
||||
* SECTION:GskTransform
|
||||
* @Title: GskTransform
|
||||
* @Short_description: A description for transform operations
|
||||
*
|
||||
@@ -42,8 +42,7 @@ typedef struct _GskTransformClass GskTransformClass;
|
||||
struct _GskTransform
|
||||
{
|
||||
const GskTransformClass *transform_class;
|
||||
|
||||
volatile int ref_count;
|
||||
|
||||
GskTransformCategory category;
|
||||
GskTransform *next;
|
||||
};
|
||||
@@ -113,10 +112,9 @@ gsk_transform_alloc (const GskTransformClass *transform_class,
|
||||
|
||||
g_return_val_if_fail (transform_class != NULL, NULL);
|
||||
|
||||
self = g_malloc0 (transform_class->struct_size);
|
||||
self = g_atomic_rc_box_alloc0 (transform_class->struct_size);
|
||||
|
||||
self->transform_class = transform_class;
|
||||
self->ref_count = 1;
|
||||
self->category = next ? MIN (category, next->category) : category;
|
||||
self->next = gsk_transform_is_identity (next) ? NULL : next;
|
||||
|
||||
@@ -312,15 +310,15 @@ gsk_matrix_transform_apply_affine (GskTransform *transform,
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_value (&self->matrix, 3, 0);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_value (&self->matrix, 3, 1);
|
||||
*out_scale_x *= graphene_matrix_get_value (&self->matrix, 0, 0);
|
||||
*out_scale_y *= graphene_matrix_get_value (&self->matrix, 1, 1);
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_x_translation (&self->matrix);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_y_translation (&self->matrix);
|
||||
*out_scale_x *= graphene_matrix_get_x_scale (&self->matrix);
|
||||
*out_scale_y *= graphene_matrix_get_y_scale (&self->matrix);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_value (&self->matrix, 3, 0);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_value (&self->matrix, 3, 1);
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_x_translation (&self->matrix);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_y_translation (&self->matrix);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
@@ -347,8 +345,8 @@ gsk_matrix_transform_apply_translate (GskTransform *transform,
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
*out_dx += graphene_matrix_get_value (&self->matrix, 3, 0);
|
||||
*out_dy += graphene_matrix_get_value (&self->matrix, 3, 1);
|
||||
*out_dx += graphene_matrix_get_x_translation (&self->matrix);
|
||||
*out_dy += graphene_matrix_get_y_translation (&self->matrix);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
@@ -421,8 +419,10 @@ gsk_matrix_transform_equal (GskTransform *first_transform,
|
||||
GskMatrixTransform *first = (GskMatrixTransform *) first_transform;
|
||||
GskMatrixTransform *second = (GskMatrixTransform *) second_transform;
|
||||
|
||||
/* Crude, but better than just returning FALSE */
|
||||
return memcmp (&first->matrix, &second->matrix, sizeof (graphene_matrix_t)) == 0;
|
||||
if (graphene_matrix_equal_fast (&first->matrix, &second->matrix))
|
||||
return TRUE;
|
||||
|
||||
return graphene_matrix_equal (&first->matrix, &second->matrix);
|
||||
}
|
||||
|
||||
static const GskTransformClass GSK_TRANSFORM_TRANSFORM_CLASS =
|
||||
@@ -735,7 +735,7 @@ gsk_rotate_transform_equal (GskTransform *first_transform,
|
||||
GskRotateTransform *first = (GskRotateTransform *) first_transform;
|
||||
GskRotateTransform *second = (GskRotateTransform *) second_transform;
|
||||
|
||||
return first->angle == second->angle;
|
||||
return G_APPROX_VALUE (first->angle, second->angle, 0.01f);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -837,8 +837,8 @@ gsk_rotate3d_transform_equal (GskTransform *first_transform,
|
||||
GskRotate3dTransform *first = (GskRotate3dTransform *) first_transform;
|
||||
GskRotate3dTransform *second = (GskRotate3dTransform *) second_transform;
|
||||
|
||||
return first->angle == second->angle
|
||||
&& graphene_vec3_equal (&first->axis, &second->axis);
|
||||
return G_APPROX_VALUE (first->angle, second->angle, 0.01f) &&
|
||||
graphene_vec3_equal (&first->axis, &second->axis);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -996,9 +996,9 @@ gsk_scale_transform_equal (GskTransform *first_transform,
|
||||
GskScaleTransform *first = (GskScaleTransform *) first_transform;
|
||||
GskScaleTransform *second = (GskScaleTransform *) second_transform;
|
||||
|
||||
return first->factor_x == second->factor_x
|
||||
&& first->factor_y == second->factor_y
|
||||
&& first->factor_z == second->factor_z;
|
||||
return G_APPROX_VALUE (first->factor_x, second->factor_x, 0.01f) &&
|
||||
G_APPROX_VALUE (first->factor_y, second->factor_y, 0.01f) &&
|
||||
G_APPROX_VALUE (first->factor_z, second->factor_z, 0.01f);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1150,7 +1150,7 @@ gsk_perspective_transform_equal (GskTransform *first_transform,
|
||||
GskPerspectiveTransform *first = (GskPerspectiveTransform *) first_transform;
|
||||
GskPerspectiveTransform *second = (GskPerspectiveTransform *) second_transform;
|
||||
|
||||
return first->depth == second->depth;
|
||||
return G_APPROX_VALUE (first->depth, second->depth, 0.001f);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1217,8 +1217,6 @@ gsk_transform_finalize (GskTransform *self)
|
||||
self->transform_class->finalize (self);
|
||||
|
||||
gsk_transform_unref (self->next);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1235,9 +1233,7 @@ gsk_transform_ref (GskTransform *self)
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
|
||||
g_atomic_int_inc (&self->ref_count);
|
||||
|
||||
return self;
|
||||
return g_atomic_rc_box_acquire (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1255,8 +1251,7 @@ gsk_transform_unref (GskTransform *self)
|
||||
if (self == NULL)
|
||||
return;
|
||||
|
||||
if (g_atomic_int_dec_and_test (&self->ref_count))
|
||||
gsk_transform_finalize (self);
|
||||
g_atomic_rc_box_release_full (self, (GDestroyNotify) gsk_transform_finalize);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1695,7 +1690,6 @@ gsk_transform_parser_parse (GtkCssParser *parser,
|
||||
if (gtk_css_token_is_ident (token, "none"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
|
||||
*out_transform = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1903,7 +1897,6 @@ gsk_transform_parse (const char *string,
|
||||
result = FALSE;
|
||||
}
|
||||
gtk_css_parser_unref (parser);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -35,7 +35,6 @@ gsk_private_sources = files([
|
||||
'gskdebug.c',
|
||||
'gskprivate.c',
|
||||
'gskprofiler.c',
|
||||
'gskrendernodeparser.c',
|
||||
'gl/gskshaderbuilder.c',
|
||||
'gl/gskglprofiler.c',
|
||||
'gl/gskglrenderer.c',
|
||||
|
||||
@@ -42,6 +42,13 @@ gtk_cell_accessible_parent_get_type (void)
|
||||
return g_define_type_id__volatile;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_accessible_parent_get_cell_extents:
|
||||
* @x: (out):
|
||||
* @y: (out):
|
||||
* @width: (out):
|
||||
* @height: (out):
|
||||
*/
|
||||
void
|
||||
gtk_cell_accessible_parent_get_cell_extents (GtkCellAccessibleParent *parent,
|
||||
GtkCellAccessible *cell,
|
||||
@@ -61,6 +68,10 @@ gtk_cell_accessible_parent_get_cell_extents (GtkCellAccessibleParent *parent,
|
||||
(iface->get_cell_extents) (parent, cell, x, y, width, height, coord_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_accessible_parent_get_cell_area:
|
||||
* @cell_rect: (out):
|
||||
*/
|
||||
void
|
||||
gtk_cell_accessible_parent_get_cell_area (GtkCellAccessibleParent *parent,
|
||||
GtkCellAccessible *cell,
|
||||
@@ -188,6 +199,11 @@ gtk_cell_accessible_parent_update_relationset (GtkCellAccessibleParent *parent,
|
||||
(iface->update_relationset) (parent, cell, relationset);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_cell_accessible_parent_get_cell_position:
|
||||
* @row: (out):
|
||||
* @column: (out):
|
||||
*/
|
||||
void
|
||||
gtk_cell_accessible_parent_get_cell_position (GtkCellAccessibleParent *parent,
|
||||
GtkCellAccessible *cell,
|
||||
|
||||
@@ -614,7 +614,6 @@ static gboolean
|
||||
gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
|
||||
{
|
||||
GtkIconViewItemAccessible *item;
|
||||
GtkWidget *toplevel;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component), FALSE);
|
||||
|
||||
@@ -624,13 +623,6 @@ gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
|
||||
|
||||
gtk_widget_grab_focus (item->widget);
|
||||
_gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item, NULL);
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
|
||||
if (gtk_widget_is_toplevel (toplevel))
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gtk_window_present (GTK_WINDOW (toplevel));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+6
-6
@@ -432,7 +432,7 @@ add_action_widgets (GtkAssistant *assistant)
|
||||
|
||||
if (has_default)
|
||||
{
|
||||
gtk_widget_grab_default (child);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (assistant), child);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (child), GTK_STYLE_CLASS_SUGGESTED_ACTION);
|
||||
}
|
||||
}
|
||||
@@ -807,7 +807,7 @@ update_buttons_state (GtkAssistant *assistant)
|
||||
case GTK_ASSISTANT_PAGE_INTRO:
|
||||
gtk_widget_set_sensitive (priv->cancel, TRUE);
|
||||
gtk_widget_set_sensitive (priv->forward, priv->current_page->complete);
|
||||
gtk_widget_grab_default (priv->forward);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (assistant), priv->forward);
|
||||
gtk_widget_show (priv->forward);
|
||||
gtk_widget_hide (priv->back);
|
||||
gtk_widget_hide (priv->apply);
|
||||
@@ -818,7 +818,7 @@ update_buttons_state (GtkAssistant *assistant)
|
||||
gtk_widget_set_sensitive (priv->cancel, TRUE);
|
||||
gtk_widget_set_sensitive (priv->back, TRUE);
|
||||
gtk_widget_set_sensitive (priv->apply, priv->current_page->complete);
|
||||
gtk_widget_grab_default (priv->apply);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (assistant), priv->apply);
|
||||
gtk_widget_show (priv->back);
|
||||
gtk_widget_show (priv->apply);
|
||||
gtk_widget_hide (priv->forward);
|
||||
@@ -829,7 +829,7 @@ update_buttons_state (GtkAssistant *assistant)
|
||||
gtk_widget_set_sensitive (priv->cancel, TRUE);
|
||||
gtk_widget_set_sensitive (priv->back, TRUE);
|
||||
gtk_widget_set_sensitive (priv->forward, priv->current_page->complete);
|
||||
gtk_widget_grab_default (priv->forward);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (assistant), priv->forward);
|
||||
gtk_widget_show (priv->back);
|
||||
gtk_widget_show (priv->forward);
|
||||
gtk_widget_hide (priv->apply);
|
||||
@@ -838,7 +838,7 @@ update_buttons_state (GtkAssistant *assistant)
|
||||
break;
|
||||
case GTK_ASSISTANT_PAGE_SUMMARY:
|
||||
gtk_widget_set_sensitive (priv->close, priv->current_page->complete);
|
||||
gtk_widget_grab_default (priv->close);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (assistant), priv->close);
|
||||
gtk_widget_show (priv->close);
|
||||
gtk_widget_hide (priv->back);
|
||||
gtk_widget_hide (priv->forward);
|
||||
@@ -849,7 +849,7 @@ update_buttons_state (GtkAssistant *assistant)
|
||||
gtk_widget_set_sensitive (priv->cancel, priv->current_page->complete);
|
||||
gtk_widget_set_sensitive (priv->back, priv->current_page->complete);
|
||||
gtk_widget_set_sensitive (priv->forward, priv->current_page->complete);
|
||||
gtk_widget_grab_default (priv->forward);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (assistant), priv->forward);
|
||||
gtk_widget_show (priv->back);
|
||||
gtk_widget_hide (priv->apply);
|
||||
gtk_widget_hide (priv->close);
|
||||
|
||||
@@ -766,6 +766,14 @@ gtk_box_layout_init (GtkBoxLayout *self)
|
||||
self->baseline_position = GTK_BASELINE_POSITION_CENTER;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_layout_new:
|
||||
* @orientation: the orientation for the new layout
|
||||
*
|
||||
* Creates a new box layout.
|
||||
*
|
||||
* Returns: a new box layout
|
||||
*/
|
||||
GtkLayoutManager *
|
||||
gtk_box_layout_new (GtkOrientation orientation)
|
||||
{
|
||||
@@ -774,6 +782,14 @@ gtk_box_layout_new (GtkOrientation orientation)
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_layout_set_homogeneous:
|
||||
* @box_layout: a #GtkBoxLayout
|
||||
* @homogeneous: %TRUE to set the box layout as homogeneous
|
||||
*
|
||||
* Sets whether the box layout will allocate the same
|
||||
* size to all children.
|
||||
*/
|
||||
void
|
||||
gtk_box_layout_set_homogeneous (GtkBoxLayout *box_layout,
|
||||
gboolean homogeneous)
|
||||
@@ -790,6 +806,14 @@ gtk_box_layout_set_homogeneous (GtkBoxLayout *box_layout,
|
||||
g_object_notify_by_pspec (G_OBJECT (box_layout), box_layout_props[PROP_HOMOGENEOUS]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_layout_get_homogeneous:
|
||||
* @box_layout: a #GtkBoxLayout
|
||||
*
|
||||
* Returns whether the layout is set to be homogeneous.
|
||||
*
|
||||
* Return: %TRUE if the layout is homogeneous
|
||||
*/
|
||||
gboolean
|
||||
gtk_box_layout_get_homogeneous (GtkBoxLayout *box_layout)
|
||||
{
|
||||
@@ -798,6 +822,13 @@ gtk_box_layout_get_homogeneous (GtkBoxLayout *box_layout)
|
||||
return box_layout->homogeneous;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_layout_set_spacing:
|
||||
* @box_layout: a #GtkBoxLayout
|
||||
* @spacing: the spacing to apply between children
|
||||
*
|
||||
* Sets how much spacing to put between children.
|
||||
*/
|
||||
void
|
||||
gtk_box_layout_set_spacing (GtkBoxLayout *box_layout,
|
||||
guint spacing)
|
||||
@@ -813,6 +844,14 @@ gtk_box_layout_set_spacing (GtkBoxLayout *box_layout,
|
||||
g_object_notify_by_pspec (G_OBJECT (box_layout), box_layout_props[PROP_SPACING]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_layout_get_spacing:
|
||||
* @box_layout: a #GtkBoxLayout
|
||||
*
|
||||
* Returns the space that @box_layout puts between children.
|
||||
*
|
||||
* Returns: the spacing of the layout
|
||||
*/
|
||||
guint
|
||||
gtk_box_layout_get_spacing (GtkBoxLayout *box_layout)
|
||||
{
|
||||
|
||||
+7
-7
@@ -1094,7 +1094,7 @@ gtk_builder_add_from_file (GtkBuilder *builder,
|
||||
priv->resource_prefix = NULL;
|
||||
|
||||
_gtk_builder_parser_parse_buffer (builder, filename,
|
||||
buffer, length,
|
||||
buffer, (gssize)length,
|
||||
NULL,
|
||||
&tmp_error);
|
||||
|
||||
@@ -1160,7 +1160,7 @@ gtk_builder_add_objects_from_file (GtkBuilder *builder,
|
||||
priv->resource_prefix = NULL;
|
||||
|
||||
_gtk_builder_parser_parse_buffer (builder, filename,
|
||||
buffer, length,
|
||||
buffer, (gssize)length,
|
||||
object_ids,
|
||||
&tmp_error);
|
||||
|
||||
@@ -1198,7 +1198,7 @@ gtk_builder_extend_with_template (GtkBuilder *builder,
|
||||
GtkWidget *widget,
|
||||
GType template_type,
|
||||
const gchar *buffer,
|
||||
gsize length,
|
||||
gssize length,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
@@ -1394,7 +1394,7 @@ gtk_builder_add_objects_from_resource (GtkBuilder *builder,
|
||||
*
|
||||
* Most users will probably want to use gtk_builder_new_from_string().
|
||||
*
|
||||
* Upon errors 0 will be returned and @error will be assigned a
|
||||
* Upon errors %FALSE will be returned and @error will be assigned a
|
||||
* #GError from the #GTK_BUILDER_ERROR, #G_MARKUP_ERROR or
|
||||
* #G_VARIANT_PARSE_ERROR domain.
|
||||
*
|
||||
@@ -1407,7 +1407,7 @@ gtk_builder_add_objects_from_resource (GtkBuilder *builder,
|
||||
gboolean
|
||||
gtk_builder_add_from_string (GtkBuilder *builder,
|
||||
const gchar *buffer,
|
||||
gsize length,
|
||||
gssize length,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
@@ -1449,7 +1449,7 @@ gtk_builder_add_from_string (GtkBuilder *builder,
|
||||
* building only the requested objects and merges
|
||||
* them with the current contents of @builder.
|
||||
*
|
||||
* Upon errors 0 will be returned and @error will be assigned a
|
||||
* Upon errors %FALSE will be returned and @error will be assigned a
|
||||
* #GError from the #GTK_BUILDER_ERROR or #G_MARKUP_ERROR domain.
|
||||
*
|
||||
* If you are adding an object that depends on an object that is not
|
||||
@@ -1461,7 +1461,7 @@ gtk_builder_add_from_string (GtkBuilder *builder,
|
||||
gboolean
|
||||
gtk_builder_add_objects_from_string (GtkBuilder *builder,
|
||||
const gchar *buffer,
|
||||
gsize length,
|
||||
gssize length,
|
||||
gchar **object_ids,
|
||||
GError **error)
|
||||
{
|
||||
|
||||
+3
-3
@@ -128,7 +128,7 @@ gboolean gtk_builder_add_from_resource (GtkBuilder *builder,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_builder_add_from_string (GtkBuilder *builder,
|
||||
const gchar *buffer,
|
||||
gsize length,
|
||||
gssize length,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_builder_add_objects_from_file (GtkBuilder *builder,
|
||||
@@ -143,7 +143,7 @@ gboolean gtk_builder_add_objects_from_resource(GtkBuilder *builder,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_builder_add_objects_from_string (GtkBuilder *builder,
|
||||
const gchar *buffer,
|
||||
gsize length,
|
||||
gssize length,
|
||||
gchar **object_ids,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
@@ -228,7 +228,7 @@ gboolean gtk_builder_extend_with_template (GtkBuilder *builder,
|
||||
GtkWidget *widget,
|
||||
GType template_type,
|
||||
const gchar *buffer,
|
||||
gsize length,
|
||||
gssize length,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -1230,7 +1230,7 @@ void
|
||||
_gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
const gchar *filename,
|
||||
const gchar *buffer,
|
||||
gsize length,
|
||||
gssize length,
|
||||
gchar **requested_objs,
|
||||
GError **error)
|
||||
{
|
||||
|
||||
@@ -135,7 +135,7 @@ typedef GType (*GTypeGetFunc) (void);
|
||||
void _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
const gchar *filename,
|
||||
const gchar *buffer,
|
||||
gsize length,
|
||||
gssize length,
|
||||
gchar **requested_objs,
|
||||
GError **error);
|
||||
GObject * _gtk_builder_construct (GtkBuilder *builder,
|
||||
|
||||
@@ -129,8 +129,6 @@ static void gtk_button_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_button_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display);
|
||||
static void gtk_button_unrealize (GtkWidget * widget);
|
||||
static void gtk_real_button_clicked (GtkButton * button);
|
||||
static void gtk_real_button_activate (GtkButton *button);
|
||||
@@ -204,7 +202,6 @@ gtk_button_class_init (GtkButtonClass *klass)
|
||||
gobject_class->set_property = gtk_button_set_property;
|
||||
gobject_class->get_property = gtk_button_get_property;
|
||||
|
||||
widget_class->display_changed = gtk_button_display_changed;
|
||||
widget_class->unrealize = gtk_button_unrealize;
|
||||
widget_class->state_flags_changed = gtk_button_state_flags_changed;
|
||||
widget_class->grab_notify = gtk_button_grab_notify;
|
||||
@@ -923,18 +920,6 @@ gtk_button_get_use_underline (GtkButton *button)
|
||||
return priv->use_underline;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (widget);
|
||||
GtkButtonPrivate *priv = gtk_button_get_instance_private (button);
|
||||
|
||||
/* If the button is being pressed while the display changes the
|
||||
release might never occur, so we reset the state. */
|
||||
priv->button_down = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state)
|
||||
|
||||
@@ -153,16 +153,6 @@ gtk_color_button_measure (GtkWidget *widget,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_button_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkColorButton *button = GTK_COLOR_BUTTON (widget);
|
||||
GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (button);
|
||||
|
||||
gtk_widget_snapshot_child (widget, priv->button, snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_button_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
@@ -193,7 +183,6 @@ gtk_color_button_class_init (GtkColorButtonClass *klass)
|
||||
gobject_class->set_property = gtk_color_button_set_property;
|
||||
gobject_class->finalize = gtk_color_button_finalize;
|
||||
|
||||
widget_class->snapshot = gtk_color_button_snapshot;
|
||||
widget_class->measure = gtk_color_button_measure;
|
||||
widget_class->size_allocate = gtk_color_button_size_allocate;
|
||||
klass->color_set = NULL;
|
||||
|
||||
@@ -30,29 +30,6 @@ G_BEGIN_DECLS
|
||||
#define GTK_IS_CSS_PROVIDER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GTK_TYPE_CSS_PROVIDER))
|
||||
#define GTK_CSS_PROVIDER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_CSS_PROVIDER, GtkCssProviderClass))
|
||||
|
||||
/**
|
||||
* GtkCssProviderError:
|
||||
* @GTK_CSS_PROVIDER_ERROR_FAILED: Failed.
|
||||
* @GTK_CSS_PROVIDER_ERROR_SYNTAX: Syntax error.
|
||||
* @GTK_CSS_PROVIDER_ERROR_IMPORT: Import error.
|
||||
* @GTK_CSS_PROVIDER_ERROR_NAME: Name error.
|
||||
* @GTK_CSS_PROVIDER_ERROR_DEPRECATED: Deprecation error.
|
||||
* @GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE: Unknown value.
|
||||
* @GTK_CSS_PROVIDER_WARN_GENERAL: A general warning.
|
||||
*
|
||||
* Error codes for %GTK_CSS_PROVIDER_ERROR.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_CSS_PROVIDER_ERROR_FAILED,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
GTK_CSS_PROVIDER_ERROR_IMPORT,
|
||||
GTK_CSS_PROVIDER_ERROR_NAME,
|
||||
GTK_CSS_PROVIDER_ERROR_DEPRECATED,
|
||||
GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE,
|
||||
GTK_CSS_PROVIDER_WARN_GENERAL,
|
||||
} GtkCssProviderError;
|
||||
|
||||
typedef struct _GtkCssProvider GtkCssProvider;
|
||||
typedef struct _GtkCssProviderClass GtkCssProviderClass;
|
||||
typedef struct _GtkCssProviderPrivate GtkCssProviderPrivate;
|
||||
|
||||
@@ -1143,8 +1143,18 @@ pack_font_description (GtkCssShorthandProperty *shorthand,
|
||||
v = (* query_func) (GTK_CSS_PROPERTY_FONT_FAMILY, query_data);
|
||||
if (v)
|
||||
{
|
||||
/* xxx: Can we set all the families here somehow? */
|
||||
pango_font_description_set_family (description, _gtk_css_string_value_get (_gtk_css_array_value_get_nth (v, 0)));
|
||||
int i;
|
||||
GString *s = g_string_new ("");
|
||||
|
||||
for (i = 0; i < _gtk_css_array_value_get_n_values (v); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append (s, ",");
|
||||
g_string_append (s, _gtk_css_string_value_get (_gtk_css_array_value_get_nth (v, i)));
|
||||
}
|
||||
|
||||
pango_font_description_set_family (description, s->str);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
v = (* query_func) (GTK_CSS_PROPERTY_FONT_SIZE, query_data);
|
||||
|
||||
+4
-7
@@ -156,7 +156,6 @@
|
||||
* </child>
|
||||
* <child type="action">
|
||||
* <object class="GtkButton" id="button_ok">
|
||||
* <property name="can-default">True</property>
|
||||
* </object>
|
||||
* </child>
|
||||
* <action-widgets>
|
||||
@@ -456,7 +455,7 @@ gtk_dialog_constructed (GObject *object)
|
||||
g_object_unref (child);
|
||||
|
||||
if (has_default)
|
||||
gtk_widget_grab_default (child);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (dialog), child);
|
||||
}
|
||||
g_list_free (children);
|
||||
|
||||
@@ -865,7 +864,7 @@ gtk_dialog_add_action_widget (GtkDialog *dialog,
|
||||
|
||||
if (gtk_widget_has_default (child))
|
||||
{
|
||||
gtk_widget_grab_default (child);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (dialog), child);
|
||||
update_suggested_action (dialog);
|
||||
}
|
||||
}
|
||||
@@ -900,8 +899,6 @@ gtk_dialog_add_button (GtkDialog *dialog,
|
||||
button = gtk_button_new_with_label (button_text);
|
||||
gtk_button_set_use_underline (GTK_BUTTON (button), TRUE);
|
||||
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
|
||||
gtk_widget_show (button);
|
||||
|
||||
gtk_dialog_add_action_widget (dialog, button, response_id);
|
||||
@@ -1028,7 +1025,7 @@ gtk_dialog_set_default_response (GtkDialog *dialog,
|
||||
ResponseData *rd = get_response_data (widget, FALSE);
|
||||
|
||||
if (rd && rd->response_id == response_id)
|
||||
gtk_widget_grab_default (widget);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (dialog), widget);
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
@@ -1528,7 +1525,7 @@ gtk_dialog_buildable_custom_finished (GtkBuildable *buildable,
|
||||
}
|
||||
|
||||
if (item->is_default)
|
||||
gtk_widget_grab_default (GTK_WIDGET (object));
|
||||
gtk_window_set_default_widget (GTK_WINDOW (dialog), GTK_WIDGET (object));
|
||||
}
|
||||
|
||||
g_slist_free_full (data->items, free_action_widget_info);
|
||||
|
||||
+48
-23
@@ -70,6 +70,9 @@ struct _GtkEmojiChooser
|
||||
EmojiSection flags;
|
||||
|
||||
GVariant *data;
|
||||
GtkWidget *box;
|
||||
GVariantIter *iter;
|
||||
guint populate_idle;
|
||||
|
||||
GSettings *settings;
|
||||
};
|
||||
@@ -92,6 +95,9 @@ gtk_emoji_chooser_finalize (GObject *object)
|
||||
{
|
||||
GtkEmojiChooser *chooser = GTK_EMOJI_CHOOSER (object);
|
||||
|
||||
if (chooser->populate_idle)
|
||||
g_source_remove (chooser->populate_idle);
|
||||
|
||||
g_variant_unref (chooser->data);
|
||||
g_object_unref (chooser->settings);
|
||||
|
||||
@@ -399,47 +405,68 @@ add_emoji (GtkWidget *box,
|
||||
gtk_flow_box_insert (GTK_FLOW_BOX (box), child, prepend ? 0 : -1);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_emoji_chooser (GtkEmojiChooser *chooser)
|
||||
static gboolean
|
||||
populate_emoji_chooser (gpointer data)
|
||||
{
|
||||
GBytes *bytes = NULL;
|
||||
GVariantIter iter;
|
||||
GtkEmojiChooser *chooser = data;
|
||||
GVariant *item;
|
||||
GtkWidget *box;
|
||||
guint64 start, now;
|
||||
|
||||
bytes = g_resources_lookup_data ("/org/gtk/libgtk/emoji/emoji.data", 0, NULL);
|
||||
chooser->data = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(auss)"), bytes, TRUE));
|
||||
start = g_get_monotonic_time ();
|
||||
|
||||
g_variant_iter_init (&iter, chooser->data);
|
||||
box = chooser->people.box;
|
||||
while ((item = g_variant_iter_next_value (&iter)))
|
||||
if (!chooser->data)
|
||||
{
|
||||
GBytes *bytes = g_resources_lookup_data ("/org/gtk/libgtk/emoji/emoji.data", 0, NULL);
|
||||
chooser->data = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(auss)"), bytes, TRUE));
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
if (!chooser->iter)
|
||||
{
|
||||
chooser->iter = g_variant_iter_new (chooser->data);
|
||||
chooser->box = chooser->people.box;
|
||||
}
|
||||
|
||||
while ((item = g_variant_iter_next_value (chooser->iter)))
|
||||
{
|
||||
const char *name;
|
||||
|
||||
g_variant_get_child (item, 1, "&s", &name);
|
||||
|
||||
if (strcmp (name, chooser->body.first) == 0)
|
||||
box = chooser->body.box;
|
||||
chooser->box = chooser->body.box;
|
||||
else if (strcmp (name, chooser->nature.first) == 0)
|
||||
box = chooser->nature.box;
|
||||
chooser->box = chooser->nature.box;
|
||||
else if (strcmp (name, chooser->food.first) == 0)
|
||||
box = chooser->food.box;
|
||||
chooser->box = chooser->food.box;
|
||||
else if (strcmp (name, chooser->travel.first) == 0)
|
||||
box = chooser->travel.box;
|
||||
chooser->box = chooser->travel.box;
|
||||
else if (strcmp (name, chooser->activities.first) == 0)
|
||||
box = chooser->activities.box;
|
||||
chooser->box = chooser->activities.box;
|
||||
else if (strcmp (name, chooser->objects.first) == 0)
|
||||
box = chooser->objects.box;
|
||||
chooser->box = chooser->objects.box;
|
||||
else if (strcmp (name, chooser->symbols.first) == 0)
|
||||
box = chooser->symbols.box;
|
||||
chooser->box = chooser->symbols.box;
|
||||
else if (strcmp (name, chooser->flags.first) == 0)
|
||||
box = chooser->flags.box;
|
||||
chooser->box = chooser->flags.box;
|
||||
|
||||
add_emoji (box, FALSE, item, 0, chooser);
|
||||
add_emoji (chooser->box, FALSE, item, 0, chooser);
|
||||
g_variant_unref (item);
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
if (now > start + 8000)
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
/* We scroll to the top on show, so check the right button for the 1st time */
|
||||
gtk_widget_set_state_flags (chooser->recent.button, GTK_STATE_FLAG_CHECKED, FALSE);
|
||||
|
||||
g_variant_iter_free (chooser->iter);
|
||||
chooser->iter = NULL;
|
||||
chooser->box = NULL;
|
||||
chooser->populate_idle = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -651,11 +678,9 @@ gtk_emoji_chooser_init (GtkEmojiChooser *chooser)
|
||||
setup_section (chooser, &chooser->symbols, "ATM sign", "emoji-symbols-symbolic");
|
||||
setup_section (chooser, &chooser->flags, "chequered flag", "emoji-flags-symbolic");
|
||||
|
||||
populate_emoji_chooser (chooser);
|
||||
populate_recent_section (chooser);
|
||||
|
||||
/* We scroll to the top on show, so check the right button for the 1st time */
|
||||
gtk_widget_set_state_flags (chooser->recent.button, GTK_STATE_FLAG_CHECKED, FALSE);
|
||||
chooser->populate_idle = g_idle_add (populate_emoji_chooser, chooser);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+10
-8
@@ -1234,10 +1234,13 @@ notify_cb (GObject *object,
|
||||
gpointer data)
|
||||
{
|
||||
gpointer iface;
|
||||
gpointer class;
|
||||
|
||||
/* The editable interface properties are already forwarded by the editable delegate setup */
|
||||
iface = g_type_interface_peek (g_type_class_peek (G_OBJECT_TYPE (object)), gtk_editable_get_type ());
|
||||
if (!g_object_interface_find_property (iface, pspec->name))
|
||||
class = g_type_class_peek (GTK_TYPE_ENTRY);
|
||||
if (!g_object_interface_find_property (iface, pspec->name) &&
|
||||
g_object_class_find_property (class, pspec->name))
|
||||
g_object_notify (data, pspec->name);
|
||||
}
|
||||
|
||||
@@ -1547,6 +1550,7 @@ gtk_entry_size_allocate (GtkWidget *widget,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
const gboolean is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
|
||||
gint i;
|
||||
@@ -1572,8 +1576,8 @@ gtk_entry_size_allocate (GtkWidget *widget,
|
||||
NULL, &icon_width,
|
||||
NULL, NULL);
|
||||
|
||||
if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL && i == GTK_ENTRY_ICON_PRIMARY) ||
|
||||
(gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR && i == GTK_ENTRY_ICON_SECONDARY))
|
||||
if ((is_rtl && i == GTK_ENTRY_ICON_PRIMARY) ||
|
||||
(!is_rtl && i == GTK_ENTRY_ICON_SECONDARY))
|
||||
icon_alloc.x = width - icon_width;
|
||||
else
|
||||
icon_alloc.x = 0;
|
||||
@@ -1584,7 +1588,9 @@ gtk_entry_size_allocate (GtkWidget *widget,
|
||||
gtk_widget_size_allocate (icon_info->widget, &icon_alloc, baseline);
|
||||
|
||||
text_alloc.width -= icon_width;
|
||||
if (i == 0)
|
||||
|
||||
if ((!is_rtl && i == GTK_ENTRY_ICON_PRIMARY) ||
|
||||
(is_rtl && i == GTK_ENTRY_ICON_SECONDARY))
|
||||
text_alloc.x += icon_width;
|
||||
}
|
||||
|
||||
@@ -2117,10 +2123,6 @@ gtk_entry_get_text_length (GtkEntry *entry)
|
||||
* widget for the window containing the entry. This usually means that
|
||||
* the dialog box containing the entry will be closed, since the default
|
||||
* widget is usually one of the dialog buttons.
|
||||
*
|
||||
* (For experts: if @setting is %TRUE, the entry calls
|
||||
* gtk_window_activate_default() on the window containing the entry, in
|
||||
* the default handler for the #GtkEntry::activate signal.)
|
||||
**/
|
||||
void
|
||||
gtk_entry_set_activates_default (GtkEntry *entry,
|
||||
|
||||
+1
-2
@@ -82,8 +82,7 @@ struct _GtkEntry
|
||||
* non-%NULL, this will be called to add additional entries to the context
|
||||
* menu when it is displayed.
|
||||
* @activate: Class handler for the #GtkEntry::activate signal. The default
|
||||
* implementation calls gtk_window_activate_default() on the entry’s top-level
|
||||
* window.
|
||||
* implementation activates the gtk.activate-default action.
|
||||
* @move_cursor: Class handler for the #GtkEntry::move-cursor signal. The
|
||||
* default implementation specifies the standard #GtkEntry cursor movement
|
||||
* behavior.
|
||||
|
||||
@@ -73,6 +73,18 @@ gtk_event_controller_unset_widget (GtkEventController *self)
|
||||
priv->widget = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_event_controller_filter_event_default (GtkEventController *self,
|
||||
const GdkEvent *event)
|
||||
{
|
||||
GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
|
||||
|
||||
if (priv->widget)
|
||||
return !gtk_widget_is_sensitive (priv->widget);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_event_controller_handle_event_default (GtkEventController *self,
|
||||
const GdkEvent *event)
|
||||
@@ -128,7 +140,7 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
|
||||
|
||||
klass->set_widget = gtk_event_controller_set_widget;
|
||||
klass->unset_widget = gtk_event_controller_unset_widget;
|
||||
klass->filter_event = gtk_event_controller_handle_event_default;
|
||||
klass->filter_event = gtk_event_controller_filter_event_default;
|
||||
klass->handle_event = gtk_event_controller_handle_event_default;
|
||||
|
||||
object_class->set_property = gtk_event_controller_set_property;
|
||||
|
||||
+22
-87
@@ -49,6 +49,7 @@
|
||||
#include "gtkfilechooserprivate.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkbinlayout.h"
|
||||
|
||||
#include "gtkfilechooserbutton.h"
|
||||
|
||||
@@ -256,12 +257,11 @@ static void gtk_file_chooser_button_drag_data_received (GtkWidget *wi
|
||||
GtkSelectionData *data);
|
||||
static void gtk_file_chooser_button_show (GtkWidget *widget);
|
||||
static void gtk_file_chooser_button_hide (GtkWidget *widget);
|
||||
static void gtk_file_chooser_button_root (GtkWidget *widget);
|
||||
static void gtk_file_chooser_button_map (GtkWidget *widget);
|
||||
static gboolean gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget,
|
||||
gboolean group_cycling);
|
||||
static void gtk_file_chooser_button_style_updated (GtkWidget *widget);
|
||||
static void gtk_file_chooser_button_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *old_display);
|
||||
static void gtk_file_chooser_button_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state);
|
||||
|
||||
@@ -340,41 +340,6 @@ G_DEFINE_TYPE_WITH_CODE (GtkFileChooserButton, gtk_file_chooser_button, GTK_TYPE
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER,
|
||||
gtk_file_chooser_button_file_chooser_iface_init))
|
||||
|
||||
|
||||
|
||||
static void
|
||||
gtk_file_chooser_button_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
|
||||
GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
|
||||
|
||||
gtk_widget_measure (priv->child, orientation, for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_button_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
|
||||
GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
|
||||
|
||||
gtk_widget_size_allocate (priv->child,
|
||||
&(GtkAllocation) {
|
||||
0, 0,
|
||||
width, height
|
||||
}, baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class)
|
||||
{
|
||||
@@ -395,11 +360,9 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class)
|
||||
widget_class->hide = gtk_file_chooser_button_hide;
|
||||
widget_class->map = gtk_file_chooser_button_map;
|
||||
widget_class->style_updated = gtk_file_chooser_button_style_updated;
|
||||
widget_class->display_changed = gtk_file_chooser_button_display_changed;
|
||||
widget_class->root = gtk_file_chooser_button_root;
|
||||
widget_class->mnemonic_activate = gtk_file_chooser_button_mnemonic_activate;
|
||||
widget_class->state_flags_changed = gtk_file_chooser_button_state_flags_changed;
|
||||
widget_class->measure = gtk_file_chooser_button_measure;
|
||||
widget_class->size_allocate = gtk_file_chooser_button_size_allocate;
|
||||
|
||||
/**
|
||||
* GtkFileChooserButton::file-set:
|
||||
@@ -534,6 +497,8 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
|
||||
target_list,
|
||||
GDK_ACTION_COPY);
|
||||
gdk_content_formats_unref (target_list);
|
||||
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (button), gtk_bin_layout_new ());
|
||||
}
|
||||
|
||||
|
||||
@@ -1023,17 +988,8 @@ gtk_file_chooser_button_finalize (GObject *object)
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
|
||||
GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
|
||||
|
||||
if (priv->selection_while_inactive)
|
||||
g_object_unref (priv->selection_while_inactive);
|
||||
|
||||
if (priv->current_folder_while_inactive)
|
||||
g_object_unref (priv->current_folder_while_inactive);
|
||||
|
||||
if (priv->model)
|
||||
{
|
||||
model_remove_rows (button, 0, gtk_tree_model_iter_n_children (priv->model, NULL));
|
||||
g_object_unref (priv->model);
|
||||
}
|
||||
g_clear_object (&priv->selection_while_inactive);
|
||||
g_clear_object (&priv->current_folder_while_inactive);
|
||||
|
||||
gtk_widget_unparent (priv->button);
|
||||
gtk_widget_unparent (priv->combo_box);
|
||||
@@ -1067,31 +1023,22 @@ gtk_file_chooser_button_destroy (GtkWidget *widget)
|
||||
GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
|
||||
GSList *l;
|
||||
|
||||
if (priv->dialog != NULL)
|
||||
if (priv->model)
|
||||
{
|
||||
gtk_widget_destroy (priv->dialog);
|
||||
priv->dialog = NULL;
|
||||
model_remove_rows (button, 0, gtk_tree_model_iter_n_children (priv->model, NULL));
|
||||
g_clear_object (&priv->model);
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->dialog, gtk_widget_destroy);
|
||||
|
||||
if (priv->native)
|
||||
{
|
||||
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (priv->native));
|
||||
g_clear_object (&priv->native);
|
||||
}
|
||||
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (priv->native));
|
||||
|
||||
priv->chooser = NULL;
|
||||
g_clear_object (&priv->native);
|
||||
priv->chooser = NULL; /* Was either priv->dialog or priv->native! */
|
||||
|
||||
if (priv->dnd_select_folder_cancellable)
|
||||
{
|
||||
g_cancellable_cancel (priv->dnd_select_folder_cancellable);
|
||||
priv->dnd_select_folder_cancellable = NULL;
|
||||
}
|
||||
|
||||
if (priv->update_button_cancellable)
|
||||
{
|
||||
g_cancellable_cancel (priv->update_button_cancellable);
|
||||
priv->update_button_cancellable = NULL;
|
||||
}
|
||||
g_clear_pointer (&priv->dnd_select_folder_cancellable, g_cancellable_cancel);
|
||||
g_clear_pointer (&priv->update_button_cancellable, g_cancellable_cancel);
|
||||
|
||||
if (priv->change_icon_theme_cancellables)
|
||||
{
|
||||
@@ -1104,24 +1051,15 @@ gtk_file_chooser_button_destroy (GtkWidget *widget)
|
||||
priv->change_icon_theme_cancellables = NULL;
|
||||
}
|
||||
|
||||
if (priv->filter_model)
|
||||
{
|
||||
g_object_unref (priv->filter_model);
|
||||
priv->filter_model = NULL;
|
||||
}
|
||||
g_clear_object (&priv->filter_model);
|
||||
|
||||
if (priv->fs)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->fs, priv->fs_volumes_changed_id);
|
||||
g_object_unref (priv->fs);
|
||||
priv->fs = NULL;
|
||||
g_clear_object (&priv->fs);
|
||||
}
|
||||
|
||||
if (priv->bookmarks_manager)
|
||||
{
|
||||
_gtk_bookmarks_manager_free (priv->bookmarks_manager);
|
||||
priv->bookmarks_manager = NULL;
|
||||
}
|
||||
g_clear_pointer (&priv->bookmarks_manager, _gtk_bookmarks_manager_free);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->destroy (widget);
|
||||
}
|
||||
@@ -1494,16 +1432,13 @@ gtk_file_chooser_button_style_updated (GtkWidget *widget)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_button_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *old_display)
|
||||
gtk_file_chooser_button_root (GtkWidget *widget)
|
||||
{
|
||||
if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->display_changed)
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->display_changed (widget, old_display);
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->root (widget);
|
||||
|
||||
change_icon_theme (GTK_FILE_CHOOSER_BUTTON (widget));
|
||||
}
|
||||
|
||||
|
||||
/* ******************* *
|
||||
* Utility Functions *
|
||||
* ******************* */
|
||||
|
||||
@@ -341,17 +341,7 @@ static void
|
||||
file_chooser_widget_file_activated (GtkFileChooser *chooser,
|
||||
GtkFileChooserDialog *dialog)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
if (gtk_window_activate_default (GTK_WINDOW (dialog)))
|
||||
return;
|
||||
|
||||
/* There probably isn't a default widget, so make things easier for the
|
||||
* programmer by looking for a reasonable button on our own.
|
||||
*/
|
||||
widget = get_accept_action_widget (GTK_DIALOG (dialog), TRUE);
|
||||
if (widget)
|
||||
gtk_widget_activate (widget);
|
||||
gtk_widget_activate_default (GTK_WIDGET (chooser));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -409,12 +399,6 @@ file_chooser_widget_response_requested (GtkWidget *widget,
|
||||
|
||||
dialog->priv->response_requested = TRUE;
|
||||
|
||||
if (gtk_window_activate_default (GTK_WINDOW (dialog)))
|
||||
return;
|
||||
|
||||
/* There probably isn't a default widget, so make things easier for the
|
||||
* programmer by looking for a reasonable button on our own.
|
||||
*/
|
||||
button = get_accept_action_widget (GTK_DIALOG (dialog), TRUE);
|
||||
if (button)
|
||||
{
|
||||
@@ -563,7 +547,7 @@ ensure_default_response (GtkFileChooserDialog *dialog)
|
||||
|
||||
widget = get_accept_action_widget (GTK_DIALOG (dialog), TRUE);
|
||||
if (widget)
|
||||
gtk_widget_grab_default (widget);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (dialog), widget);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+112
-221
@@ -83,6 +83,7 @@
|
||||
#include "gtkfilechoosererrorstackprivate.h"
|
||||
#include "gtkentryprivate.h"
|
||||
#include "gtkroot.h"
|
||||
#include "gtkbinlayout.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
@@ -347,6 +348,8 @@ struct _GtkFileChooserWidgetPrivate {
|
||||
gint sort_column;
|
||||
GtkSortType sort_order;
|
||||
|
||||
ClockFormat clock_format;
|
||||
|
||||
/* Flags */
|
||||
|
||||
guint local_only : 1;
|
||||
@@ -363,6 +366,7 @@ struct _GtkFileChooserWidgetPrivate {
|
||||
guint show_size_column : 1;
|
||||
guint create_folders : 1;
|
||||
guint auto_selecting_first_row : 1;
|
||||
guint starting_search : 1;
|
||||
};
|
||||
|
||||
#define MAX_LOADING_TIME 500
|
||||
@@ -457,8 +461,6 @@ static void gtk_file_chooser_widget_unmap (GtkWidget *w
|
||||
static void gtk_file_chooser_widget_root (GtkWidget *widget);
|
||||
static void gtk_file_chooser_widget_unroot (GtkWidget *widget);
|
||||
static void gtk_file_chooser_widget_style_updated (GtkWidget *widget);
|
||||
static void gtk_file_chooser_widget_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display);
|
||||
|
||||
static gboolean gtk_file_chooser_widget_set_current_folder (GtkFileChooser *chooser,
|
||||
GFile *folder,
|
||||
@@ -532,6 +534,7 @@ static void search_shortcut_handler (GtkFileChooserWidget *impl);
|
||||
static void recent_shortcut_handler (GtkFileChooserWidget *impl);
|
||||
static void places_shortcut_handler (GtkFileChooserWidget *impl);
|
||||
static void update_appearance (GtkFileChooserWidget *impl);
|
||||
static void check_icon_theme (GtkFileChooserWidget *impl);
|
||||
|
||||
static void operation_mode_set (GtkFileChooserWidget *impl, OperationMode mode);
|
||||
static void location_mode_set (GtkFileChooserWidget *impl, LocationMode new_mode);
|
||||
@@ -555,8 +558,6 @@ static void list_row_activated (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *column,
|
||||
GtkFileChooserWidget *impl);
|
||||
static void list_cursor_changed (GtkTreeView *treeview,
|
||||
GtkFileChooserWidget *impl);
|
||||
|
||||
static void path_bar_clicked (GtkPathBar *path_bar,
|
||||
GFile *file,
|
||||
@@ -672,8 +673,7 @@ gtk_file_chooser_widget_finalize (GObject *object)
|
||||
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (object);
|
||||
GtkFileChooserWidgetPrivate *priv = impl->priv;
|
||||
|
||||
if (priv->choices)
|
||||
g_hash_table_unref (priv->choices);
|
||||
g_clear_pointer (&priv->choices, g_hash_table_unref);
|
||||
|
||||
if (priv->location_changed_id > 0)
|
||||
g_source_remove (priv->location_changed_id);
|
||||
@@ -683,21 +683,10 @@ gtk_file_chooser_widget_finalize (GObject *object)
|
||||
g_free (priv->browse_files_last_selected_name);
|
||||
|
||||
g_slist_free_full (priv->filters, g_object_unref);
|
||||
|
||||
if (priv->current_filter)
|
||||
g_object_unref (priv->current_filter);
|
||||
|
||||
if (priv->current_volume_file)
|
||||
g_object_unref (priv->current_volume_file);
|
||||
|
||||
if (priv->current_folder)
|
||||
g_object_unref (priv->current_folder);
|
||||
|
||||
if (priv->preview_file)
|
||||
g_object_unref (priv->preview_file);
|
||||
|
||||
if (priv->browse_path_bar_size_group)
|
||||
g_object_unref (priv->browse_path_bar_size_group);
|
||||
g_clear_object (&priv->current_filter);
|
||||
g_clear_object (&priv->current_volume_file);
|
||||
g_clear_object (&priv->current_folder);
|
||||
g_clear_object (&priv->browse_path_bar_size_group);
|
||||
|
||||
/* Free all the Models we have */
|
||||
stop_loading_and_clear_list_model (impl, FALSE);
|
||||
@@ -715,31 +704,6 @@ gtk_file_chooser_widget_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (gtk_file_chooser_widget_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/* Shows an error dialog set as transient for the specified window */
|
||||
static void
|
||||
error_message_with_parent (GtkWindow *parent,
|
||||
const char *msg,
|
||||
const char *detail)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
"%s",
|
||||
msg);
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%s", detail);
|
||||
|
||||
if (parent && gtk_window_has_group (parent))
|
||||
gtk_window_group_add_window (gtk_window_get_group (parent),
|
||||
GTK_WINDOW (dialog));
|
||||
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
/* Returns a toplevel GtkWindow, or NULL if none */
|
||||
static GtkWindow *
|
||||
get_toplevel (GtkWidget *widget)
|
||||
@@ -759,7 +723,25 @@ error_message (GtkFileChooserWidget *impl,
|
||||
const char *msg,
|
||||
const char *detail)
|
||||
{
|
||||
error_message_with_parent (get_toplevel (GTK_WIDGET (impl)), msg, detail);
|
||||
GtkWindow *parent = get_toplevel (GTK_WIDGET (impl));
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
"%s",
|
||||
msg);
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%s", detail);
|
||||
|
||||
if (parent && gtk_window_has_group (parent))
|
||||
gtk_window_group_add_window (gtk_window_get_group (parent),
|
||||
GTK_WINDOW (dialog));
|
||||
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
}
|
||||
|
||||
/* Shows a simple error dialog relative to a path. Frees the GError as well. */
|
||||
@@ -920,7 +902,6 @@ update_preview_widget_visibility (GtkFileChooserWidget *impl)
|
||||
priv->preview_label = gtk_label_new (priv->preview_display_name);
|
||||
gtk_box_insert_child_after (GTK_BOX (priv->preview_box), priv->preview_label, NULL);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (priv->preview_label), PANGO_ELLIPSIZE_MIDDLE);
|
||||
gtk_widget_show (priv->preview_label);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1259,13 +1240,10 @@ places_sidebar_show_error_message_cb (GtkPlacesSidebar *sidebar,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
key_is_left_or_right (const GdkEvent *event)
|
||||
key_is_left_or_right (guint keyval,
|
||||
guint state)
|
||||
{
|
||||
guint modifiers, keyval, state;
|
||||
|
||||
if (!gdk_event_get_keyval (event, &keyval) ||
|
||||
!gdk_event_get_state (event, &state))
|
||||
return FALSE;
|
||||
guint modifiers;
|
||||
|
||||
modifiers = gtk_accelerator_get_default_mod_mask ();
|
||||
|
||||
@@ -1326,11 +1304,8 @@ key_press_cb (GtkEventControllerKey *controller,
|
||||
{
|
||||
GtkFileChooserWidget *impl = (GtkFileChooserWidget *) data;
|
||||
GtkFileChooserWidgetPrivate *priv = impl->priv;
|
||||
const GdkEvent *event;
|
||||
const char *string;
|
||||
|
||||
event = gtk_get_current_event ();
|
||||
|
||||
if (should_trigger_location_entry (impl, keyval, state, &string) &&
|
||||
(priv->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
|
||||
priv->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER))
|
||||
@@ -1339,7 +1314,7 @@ key_press_cb (GtkEventControllerKey *controller,
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
|
||||
if (key_is_left_or_right (event))
|
||||
if (key_is_left_or_right (keyval, state))
|
||||
{
|
||||
if (gtk_widget_child_focus (priv->places_sidebar, GTK_DIR_LEFT))
|
||||
return GDK_EVENT_STOP;
|
||||
@@ -1354,25 +1329,8 @@ key_press_cb (GtkEventControllerKey *controller,
|
||||
&& !(priv->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
|
||||
priv->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (impl);
|
||||
GtkWindow *window;
|
||||
|
||||
window = get_toplevel (widget);
|
||||
if (window)
|
||||
{
|
||||
GtkWidget *default_widget, *focus_widget;
|
||||
|
||||
default_widget = gtk_window_get_default_widget (window);
|
||||
focus_widget = gtk_root_get_focus (GTK_ROOT (window));
|
||||
|
||||
if (widget != default_widget &&
|
||||
!(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
|
||||
{
|
||||
gtk_window_activate_default (window);
|
||||
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
}
|
||||
gtk_widget_activate_default (GTK_WIDGET (impl));
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
|
||||
if (keyval == GDK_KEY_Escape &&
|
||||
@@ -1395,11 +1353,8 @@ widget_key_press_cb (GtkEventControllerKey *controller,
|
||||
GtkFileChooserWidget *impl = (GtkFileChooserWidget *) data;
|
||||
GtkFileChooserWidgetPrivate *priv = impl->priv;
|
||||
gboolean handled = FALSE;
|
||||
GdkEvent *event;
|
||||
const char *string;
|
||||
|
||||
event = gtk_get_current_event ();
|
||||
|
||||
if (should_trigger_location_entry (impl, keyval, state, &string))
|
||||
{
|
||||
if (priv->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
|
||||
@@ -1411,16 +1366,17 @@ widget_key_press_cb (GtkEventControllerKey *controller,
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_event_controller_key_forward (controller, priv->search_entry);
|
||||
priv->starting_search = TRUE;
|
||||
if (gtk_event_controller_key_forward (controller, priv->search_entry))
|
||||
{
|
||||
if (priv->operation_mode != OPERATION_MODE_SEARCH &&
|
||||
priv->starting_search)
|
||||
operation_mode_set (impl, OPERATION_MODE_SEARCH);
|
||||
|
||||
if (priv->operation_mode != OPERATION_MODE_SEARCH)
|
||||
operation_mode_set (impl, OPERATION_MODE_SEARCH);
|
||||
|
||||
handled = TRUE;
|
||||
handled = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (event);
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
@@ -1709,7 +1665,6 @@ visit_file_cb (GSimpleAction *action,
|
||||
g_slist_free_full (files, g_object_unref);
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
/* Callback used when the "Open this folder" menu item is activated */
|
||||
static void
|
||||
open_folder_cb (GSimpleAction *action,
|
||||
@@ -1735,7 +1690,6 @@ open_folder_cb (GSimpleAction *action,
|
||||
|
||||
g_slist_free_full (files, g_object_unref);
|
||||
}
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
/* callback used when the "Show Hidden Files" menu item is toggled */
|
||||
static void
|
||||
@@ -2197,7 +2151,6 @@ file_list_build_popover (GtkFileChooserWidget *impl)
|
||||
priv->browse_files_popover = gtk_popover_new (priv->browse_files_tree_view);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (box, "margin", 10, NULL);
|
||||
gtk_widget_show (box);
|
||||
gtk_container_add (GTK_CONTAINER (priv->browse_files_popover), box);
|
||||
|
||||
priv->visit_file_item = add_button (box, _("_Visit File"), "item.visit");
|
||||
@@ -2267,7 +2220,12 @@ file_list_show_popover (GtkFileChooserWidget *impl,
|
||||
GtkTreeModel *model;
|
||||
GList *list;
|
||||
GtkTreePath *path;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
if (!gtk_widget_compute_bounds (priv->browse_files_tree_view,
|
||||
priv->browse_files_tree_view,
|
||||
&bounds))
|
||||
return;
|
||||
|
||||
file_list_update_popover (impl);
|
||||
|
||||
@@ -2280,7 +2238,7 @@ file_list_show_popover (GtkFileChooserWidget *impl,
|
||||
gtk_tree_view_convert_bin_window_to_widget_coords (GTK_TREE_VIEW (priv->browse_files_tree_view),
|
||||
rect.x, rect.y, &rect.x, &rect.y);
|
||||
|
||||
rect.x = CLAMP (x - 20, 0, gtk_widget_get_allocated_width (priv->browse_files_tree_view) - 40);
|
||||
rect.x = CLAMP (x - 20, 0, bounds.size.width - 40);
|
||||
rect.width = 40;
|
||||
|
||||
g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
|
||||
@@ -2303,11 +2261,17 @@ list_popup_menu_cb (GtkWidget *widget,
|
||||
GtkFileChooserWidget *impl)
|
||||
{
|
||||
GtkFileChooserWidgetPrivate *priv = impl->priv;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
file_list_show_popover (impl,
|
||||
0.5 * gtk_widget_get_allocated_width (GTK_WIDGET (priv->browse_files_tree_view)),
|
||||
0.5 * gtk_widget_get_allocated_height (GTK_WIDGET (priv->browse_files_tree_view)));
|
||||
return TRUE;
|
||||
if (gtk_widget_compute_bounds (priv->browse_files_tree_view,
|
||||
priv->browse_files_tree_view,
|
||||
&bounds))
|
||||
{
|
||||
file_list_show_popover (impl, 0.5 * bounds.size.width, 0.5 * bounds.size.height);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Callback used when a button is pressed on the file list. We trap button 3 to
|
||||
@@ -2491,6 +2455,7 @@ static void
|
||||
location_entry_close_clicked (GtkFileChooserWidget *impl)
|
||||
{
|
||||
location_mode_set (impl, LOCATION_MODE_PATH_BAR);
|
||||
gtk_widget_grab_focus (GTK_WIDGET (impl));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2608,7 +2573,6 @@ save_widgets_create (GtkFileChooserWidget *impl)
|
||||
|
||||
priv->save_widgets = vbox;
|
||||
gtk_box_insert_child_after (GTK_BOX (priv->box), priv->save_widgets, NULL);
|
||||
gtk_widget_show (priv->save_widgets);
|
||||
}
|
||||
|
||||
/* Destroys the widgets specific to Save mode */
|
||||
@@ -3468,29 +3432,10 @@ cancel_all_operations (GtkFileChooserWidget *impl)
|
||||
|
||||
pending_select_files_free (impl);
|
||||
|
||||
if (priv->file_list_drag_data_received_cancellable)
|
||||
{
|
||||
g_cancellable_cancel (priv->file_list_drag_data_received_cancellable);
|
||||
priv->file_list_drag_data_received_cancellable = NULL;
|
||||
}
|
||||
|
||||
if (priv->update_current_folder_cancellable)
|
||||
{
|
||||
g_cancellable_cancel (priv->update_current_folder_cancellable);
|
||||
priv->update_current_folder_cancellable = NULL;
|
||||
}
|
||||
|
||||
if (priv->should_respond_get_info_cancellable)
|
||||
{
|
||||
g_cancellable_cancel (priv->should_respond_get_info_cancellable);
|
||||
priv->should_respond_get_info_cancellable = NULL;
|
||||
}
|
||||
|
||||
if (priv->file_exists_get_info_cancellable)
|
||||
{
|
||||
g_cancellable_cancel (priv->file_exists_get_info_cancellable);
|
||||
priv->file_exists_get_info_cancellable = NULL;
|
||||
}
|
||||
g_clear_pointer (&priv->file_list_drag_data_received_cancellable, g_cancellable_cancel);
|
||||
g_clear_pointer (&priv->update_current_folder_cancellable, g_cancellable_cancel);
|
||||
g_clear_pointer (&priv->should_respond_get_info_cancellable, g_cancellable_cancel);
|
||||
g_clear_pointer (&priv->file_exists_get_info_cancellable, g_cancellable_cancel);
|
||||
|
||||
search_stop_searching (impl, TRUE);
|
||||
recent_stop_loading (impl);
|
||||
@@ -3525,25 +3470,10 @@ gtk_file_chooser_widget_dispose (GObject *object)
|
||||
if (priv->rename_file_popover)
|
||||
gtk_popover_set_relative_to (GTK_POPOVER (priv->rename_file_popover), NULL);
|
||||
|
||||
if (priv->browse_files_popover)
|
||||
{
|
||||
gtk_widget_destroy (priv->browse_files_popover);
|
||||
priv->browse_files_popover = NULL;
|
||||
}
|
||||
|
||||
if (priv->extra_widget)
|
||||
{
|
||||
g_object_unref (priv->extra_widget);
|
||||
priv->extra_widget = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->browse_files_popover, gtk_widget_destroy);
|
||||
g_clear_object (&priv->extra_widget);
|
||||
remove_settings_signal (impl, gtk_widget_get_display (GTK_WIDGET (impl)));
|
||||
|
||||
if (priv->bookmarks_manager)
|
||||
{
|
||||
_gtk_bookmarks_manager_free (priv->bookmarks_manager);
|
||||
priv->bookmarks_manager = NULL;
|
||||
}
|
||||
g_clear_pointer (&priv->bookmarks_manager, _gtk_bookmarks_manager_free);
|
||||
|
||||
if (priv->external_entry && priv->location_entry == priv->external_entry)
|
||||
{
|
||||
@@ -3551,11 +3481,7 @@ gtk_file_chooser_widget_dispose (GObject *object)
|
||||
priv->external_entry = NULL;
|
||||
}
|
||||
|
||||
if (priv->box)
|
||||
{
|
||||
gtk_widget_unparent (priv->box);
|
||||
priv->box = NULL;
|
||||
}
|
||||
g_clear_pointer (&priv->box, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (gtk_file_chooser_widget_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -3611,6 +3537,10 @@ gtk_file_chooser_widget_unroot (GtkWidget *widget)
|
||||
priv->toplevel_current_focus_widget = NULL;
|
||||
}
|
||||
|
||||
remove_settings_signal (impl, gtk_widget_get_display (widget));
|
||||
check_icon_theme (impl);
|
||||
emit_default_size_changed (impl);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_widget_parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
@@ -3695,27 +3625,6 @@ gtk_file_chooser_widget_style_updated (GtkWidget *widget)
|
||||
profile_end ("end", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_widget_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display)
|
||||
{
|
||||
GtkFileChooserWidget *impl;
|
||||
|
||||
profile_start ("start", NULL);
|
||||
|
||||
impl = GTK_FILE_CHOOSER_WIDGET (widget);
|
||||
|
||||
if (GTK_WIDGET_CLASS (gtk_file_chooser_widget_parent_class)->display_changed)
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_widget_parent_class)->display_changed (widget, previous_display);
|
||||
|
||||
remove_settings_signal (impl, previous_display);
|
||||
check_icon_theme (impl);
|
||||
|
||||
emit_default_size_changed (impl);
|
||||
|
||||
profile_end ("end", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
set_sort_column (GtkFileChooserWidget *impl)
|
||||
{
|
||||
@@ -3768,6 +3677,7 @@ settings_load (GtkFileChooserWidget *impl)
|
||||
priv->startup_mode = startup_mode;
|
||||
priv->sort_directories_first = sort_directories_first;
|
||||
priv->show_time = date_format == DATE_FORMAT_WITH_TIME;
|
||||
priv->clock_format = g_settings_get_enum (settings, "clock-format");
|
||||
|
||||
/* We don't call set_sort_column() here as the models may not have been
|
||||
* created yet. The individual functions that create and set the models will
|
||||
@@ -3775,6 +3685,14 @@ settings_load (GtkFileChooserWidget *impl)
|
||||
*/
|
||||
|
||||
update_time_renderer_visible (impl);
|
||||
if (sidebar_width < 0)
|
||||
{
|
||||
GtkWidget *sidebar = gtk_paned_get_child1 (GTK_PANED (priv->browse_widgets_hpaned));
|
||||
|
||||
gtk_widget_measure (sidebar, GTK_ORIENTATION_HORIZONTAL, -1,
|
||||
NULL, &sidebar_width, NULL, NULL);
|
||||
}
|
||||
|
||||
gtk_paned_set_position (GTK_PANED (priv->browse_widgets_hpaned), sidebar_width);
|
||||
}
|
||||
|
||||
@@ -4636,13 +4554,11 @@ static char *
|
||||
my_g_format_date_for_display (GtkFileChooserWidget *impl,
|
||||
glong secs)
|
||||
{
|
||||
GtkFileChooserWidgetPrivate *priv = impl->priv;
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
GDateTime *now, *time;
|
||||
GDateTime *now_date, *date;
|
||||
ClockFormat clock_format;
|
||||
const gchar *format;
|
||||
gchar *date_str;
|
||||
GSettings *settings;
|
||||
gint days_ago;
|
||||
|
||||
time = g_date_time_new_from_unix_local (secs);
|
||||
@@ -4651,9 +4567,6 @@ my_g_format_date_for_display (GtkFileChooserWidget *impl,
|
||||
g_date_time_get_day_of_month (time),
|
||||
0, 0, 0);
|
||||
|
||||
settings = _gtk_file_chooser_get_settings_for_widget (GTK_WIDGET (impl));
|
||||
clock_format = g_settings_get_enum (settings, "clock-format");
|
||||
|
||||
now = g_date_time_new_now_local ();
|
||||
now_date = g_date_time_new_local (g_date_time_get_year (now),
|
||||
g_date_time_get_month (now),
|
||||
@@ -4665,7 +4578,7 @@ my_g_format_date_for_display (GtkFileChooserWidget *impl,
|
||||
{
|
||||
if (priv->show_time)
|
||||
format = "";
|
||||
else if (clock_format == CLOCK_FORMAT_24)
|
||||
else if (priv->clock_format == CLOCK_FORMAT_24)
|
||||
/* Translators: see g_date_time_format() for details on the format */
|
||||
format = _("%H:%M");
|
||||
else
|
||||
@@ -4703,18 +4616,14 @@ static char *
|
||||
my_g_format_time_for_display (GtkFileChooserWidget *impl,
|
||||
glong secs)
|
||||
{
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
GDateTime *time;
|
||||
ClockFormat clock_format;
|
||||
const gchar *format;
|
||||
gchar *date_str;
|
||||
GSettings *settings;
|
||||
|
||||
time = g_date_time_new_from_unix_local (secs);
|
||||
|
||||
settings = _gtk_file_chooser_get_settings_for_widget (GTK_WIDGET (impl));
|
||||
clock_format = g_settings_get_enum (settings, "clock-format");
|
||||
|
||||
if (clock_format == CLOCK_FORMAT_24)
|
||||
if (priv->clock_format == CLOCK_FORMAT_24)
|
||||
format = _("%H:%M");
|
||||
else
|
||||
format = _("%l:%M %p");
|
||||
@@ -6200,7 +6109,6 @@ add_custom_button_to_dialog (GtkDialog *dialog,
|
||||
GtkWidget *button;
|
||||
|
||||
button = gtk_button_new_with_mnemonic (mnemonic_label);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, response_id);
|
||||
}
|
||||
@@ -7001,10 +6909,6 @@ search_engine_hits_added_cb (GtkSearchEngine *engine,
|
||||
{
|
||||
GList *l, *files, *files_with_info, *infos;
|
||||
GFile *file;
|
||||
gboolean select = FALSE;
|
||||
|
||||
if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (impl->priv->search_model), NULL) == 0)
|
||||
select = TRUE;
|
||||
|
||||
files = NULL;
|
||||
files_with_info = NULL;
|
||||
@@ -7032,8 +6936,6 @@ search_engine_hits_added_cb (GtkSearchEngine *engine,
|
||||
g_list_free_full (infos, g_object_unref);
|
||||
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (impl->priv->browse_files_stack), "list");
|
||||
if (select)
|
||||
gtk_widget_grab_focus (impl->priv->browse_files_tree_view);
|
||||
}
|
||||
|
||||
/* Callback used from GtkSearchEngine when the query is done running */
|
||||
@@ -7182,8 +7084,6 @@ search_start_query (GtkFileChooserWidget *impl,
|
||||
set_busy_cursor (impl, TRUE);
|
||||
priv->show_progress_timeout = g_timeout_add (1500, show_spinner, impl);
|
||||
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_files_stack), "list");
|
||||
|
||||
if (priv->search_engine == NULL)
|
||||
priv->search_engine = _gtk_search_engine_new ();
|
||||
|
||||
@@ -7217,6 +7117,10 @@ search_start_query (GtkFileChooserWidget *impl,
|
||||
if (gtk_query_get_location (priv->search_query) &&
|
||||
_gtk_file_consider_as_remote (gtk_query_get_location (priv->search_query)))
|
||||
gtk_widget_show (priv->remote_warning_bar);
|
||||
|
||||
/* We're not showing the file list here already and instead rely on the
|
||||
* GtkSearchEntry timout and the ::hits-added signal from above to
|
||||
* switch. */
|
||||
}
|
||||
|
||||
/* Callback used when the user presses Enter while typing on the search
|
||||
@@ -7251,6 +7155,8 @@ search_entry_stop_cb (GtkFileChooserWidget *impl)
|
||||
search_stop_searching (impl, FALSE);
|
||||
else
|
||||
g_object_set (impl, "search-mode", FALSE, NULL);
|
||||
|
||||
impl->priv->starting_search = FALSE;
|
||||
}
|
||||
|
||||
/* Hides the path bar and creates the search entry */
|
||||
@@ -7691,6 +7597,24 @@ list_cursor_changed (GtkTreeView *list,
|
||||
check_preview_change (impl);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
browse_files_tree_view_keynav_failed_cb (GtkWidget *widget,
|
||||
GtkDirectionType direction,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileChooserWidget *self = user_data;
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (self);
|
||||
|
||||
if (direction == GTK_DIR_UP && priv->operation_mode == OPERATION_MODE_SEARCH)
|
||||
{
|
||||
gtk_widget_grab_focus (priv->search_entry);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Callback used when a row in the file list is activated */
|
||||
static void
|
||||
list_row_activated (GtkTreeView *tree_view,
|
||||
@@ -7954,39 +7878,6 @@ add_normal_and_shifted_binding (GtkBindingSet *binding_set,
|
||||
signal_name, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_widget_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkFileChooserWidget *self = GTK_FILE_CHOOSER_WIDGET (widget);
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (self);
|
||||
|
||||
gtk_widget_measure (priv->box, orientation, for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_widget_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkFileChooserWidget *self = GTK_FILE_CHOOSER_WIDGET (widget);
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (self);
|
||||
|
||||
gtk_widget_size_allocate (priv->box,
|
||||
&(GtkAllocation) {
|
||||
0, 0,
|
||||
width, height
|
||||
},-1);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
|
||||
{
|
||||
@@ -8010,9 +7901,6 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
|
||||
widget_class->root = gtk_file_chooser_widget_root;
|
||||
widget_class->unroot = gtk_file_chooser_widget_unroot;
|
||||
widget_class->style_updated = gtk_file_chooser_widget_style_updated;
|
||||
widget_class->display_changed = gtk_file_chooser_widget_display_changed;
|
||||
widget_class->measure = gtk_file_chooser_widget_measure;
|
||||
widget_class->size_allocate = gtk_file_chooser_widget_size_allocate;
|
||||
|
||||
/*
|
||||
* Signals
|
||||
@@ -8418,6 +8306,7 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_list_drag_end_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, list_selection_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, list_cursor_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, browse_files_tree_view_keynav_failed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, filter_combo_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, path_bar_clicked);
|
||||
gtk_widget_class_bind_template_callback (widget_class, places_sidebar_open_location_cb);
|
||||
@@ -8578,6 +8467,8 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
|
||||
*/
|
||||
post_process_ui (impl);
|
||||
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (impl), gtk_bin_layout_new ());
|
||||
|
||||
profile_end ("end", NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -334,6 +334,13 @@ gtk_fixed_layout_init (GtkFixedLayout *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_fixed_layout_new:
|
||||
*
|
||||
* Creates a new #GtkFixedLayout.
|
||||
*
|
||||
* Returns: the newly created #GtkFixedLayout
|
||||
*/
|
||||
GtkLayoutManager *
|
||||
gtk_fixed_layout_new (void)
|
||||
{
|
||||
|
||||
+80
-41
@@ -55,6 +55,7 @@
|
||||
#include "gtkcombobox.h"
|
||||
#include "gtkgesturemultipress.h"
|
||||
#include "gtkeventcontrollerscroll.h"
|
||||
#include "gtkroot.h"
|
||||
|
||||
#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
|
||||
#include <pango/pangofc-font.h>
|
||||
@@ -168,9 +169,6 @@ static void gtk_font_chooser_widget_get_property (GObject *objec
|
||||
GParamSpec *pspec);
|
||||
static void gtk_font_chooser_widget_finalize (GObject *object);
|
||||
|
||||
static void gtk_font_chooser_widget_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display);
|
||||
|
||||
static gboolean gtk_font_chooser_widget_find_font (GtkFontChooserWidget *fontchooser,
|
||||
const PangoFontDescription *font_desc,
|
||||
GtkTreeIter *iter);
|
||||
@@ -617,6 +615,35 @@ rows_changed_cb (GtkFontChooserWidget *fontchooser)
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (priv->list_stack), page);
|
||||
}
|
||||
|
||||
static void
|
||||
update_key_capture (GtkWidget *chooser)
|
||||
{
|
||||
GtkFontChooserWidgetPrivate *priv;
|
||||
GtkWidget *capture_widget;
|
||||
|
||||
priv = gtk_font_chooser_widget_get_instance_private (GTK_FONT_CHOOSER_WIDGET (chooser));
|
||||
|
||||
if (gtk_widget_get_mapped (chooser) &&
|
||||
g_str_equal (gtk_stack_get_visible_child_name (GTK_STACK (priv->stack)), "list"))
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *focus;
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (chooser);
|
||||
focus = gtk_root_get_focus (GTK_ROOT (toplevel));
|
||||
|
||||
if (GTK_IS_EDITABLE (focus) && focus != priv->search_entry)
|
||||
capture_widget = NULL;
|
||||
else
|
||||
capture_widget = chooser;
|
||||
}
|
||||
else
|
||||
capture_widget = NULL;
|
||||
|
||||
gtk_search_entry_set_key_capture_widget (GTK_SEARCH_ENTRY (priv->search_entry),
|
||||
capture_widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_chooser_widget_map (GtkWidget *widget)
|
||||
{
|
||||
@@ -628,6 +655,53 @@ gtk_font_chooser_widget_map (GtkWidget *widget)
|
||||
g_simple_action_set_state (G_SIMPLE_ACTION (priv->tweak_action), g_variant_new_boolean (FALSE));
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->map (widget);
|
||||
|
||||
update_key_capture (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_chooser_widget_unmap (GtkWidget *widget)
|
||||
{
|
||||
update_key_capture (widget);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->unmap (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
fontconfig_changed (GtkFontChooserWidget *fontchooser)
|
||||
{
|
||||
gtk_font_chooser_widget_load_fonts (fontchooser, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_chooser_widget_root (GtkWidget *widget)
|
||||
{
|
||||
GtkSettings *settings;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->root (widget);
|
||||
|
||||
g_signal_connect_swapped (gtk_widget_get_root (widget), "notify::focus-widget",
|
||||
G_CALLBACK (update_key_capture), widget);
|
||||
|
||||
settings = gtk_widget_get_settings (widget);
|
||||
g_signal_connect_object (settings, "notify::gtk-fontconfig-timestamp",
|
||||
G_CALLBACK (fontconfig_changed), widget, G_CONNECT_SWAPPED);
|
||||
|
||||
gtk_font_chooser_widget_load_fonts (GTK_FONT_CHOOSER_WIDGET (widget), FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_chooser_widget_unroot (GtkWidget *widget)
|
||||
{
|
||||
GtkSettings *settings;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (gtk_widget_get_root (widget),
|
||||
update_key_capture, widget);
|
||||
|
||||
settings = gtk_widget_get_settings (widget);
|
||||
g_signal_handlers_disconnect_by_func (settings, fontconfig_changed, widget);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -685,10 +759,12 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
|
||||
g_type_ensure (GTK_TYPE_DELAYED_FONT_DESCRIPTION);
|
||||
g_type_ensure (G_TYPE_THEMED_ICON);
|
||||
|
||||
widget_class->display_changed = gtk_font_chooser_widget_display_changed;
|
||||
widget_class->measure = gtk_font_chooser_widget_measure;
|
||||
widget_class->size_allocate = gtk_font_chooser_widget_size_allocate;
|
||||
widget_class->root = gtk_font_chooser_widget_root;
|
||||
widget_class->unroot = gtk_font_chooser_widget_unroot;
|
||||
widget_class->map = gtk_font_chooser_widget_map;
|
||||
widget_class->unmap = gtk_font_chooser_widget_unmap;
|
||||
|
||||
gobject_class->finalize = gtk_font_chooser_widget_finalize;
|
||||
gobject_class->dispose = gtk_font_chooser_widget_dispose;
|
||||
@@ -876,9 +952,6 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
|
||||
|
||||
gtk_font_chooser_widget_set_cell_size (fontchooser);
|
||||
gtk_font_chooser_widget_take_font_desc (fontchooser, NULL);
|
||||
|
||||
gtk_search_entry_set_key_capture_widget (GTK_SEARCH_ENTRY (priv->search_entry),
|
||||
GTK_WIDGET (fontchooser));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1250,40 +1323,6 @@ gtk_font_chooser_widget_find_font (GtkFontChooserWidget *fontchooser,
|
||||
return valid;
|
||||
}
|
||||
|
||||
static void
|
||||
fontconfig_changed (GtkFontChooserWidget *fontchooser)
|
||||
{
|
||||
gtk_font_chooser_widget_load_fonts (fontchooser, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_font_chooser_widget_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display)
|
||||
{
|
||||
GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (widget);
|
||||
GtkSettings *settings;
|
||||
|
||||
if (GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->display_changed)
|
||||
GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->display_changed (widget, previous_display);
|
||||
|
||||
if (previous_display)
|
||||
{
|
||||
settings = gtk_settings_get_for_display (previous_display);
|
||||
g_signal_handlers_disconnect_by_func (settings, fontconfig_changed, widget);
|
||||
}
|
||||
settings = gtk_widget_get_settings (widget);
|
||||
g_signal_connect_object (settings, "notify::gtk-fontconfig-timestamp",
|
||||
G_CALLBACK (fontconfig_changed), widget, G_CONNECT_SWAPPED);
|
||||
|
||||
if (previous_display == NULL)
|
||||
previous_display = gdk_display_get_default ();
|
||||
|
||||
if (previous_display == gtk_widget_get_display (widget))
|
||||
return;
|
||||
|
||||
gtk_font_chooser_widget_load_fonts (fontchooser, FALSE);
|
||||
}
|
||||
|
||||
static PangoFontFamily *
|
||||
gtk_font_chooser_widget_get_family (GtkFontChooser *chooser)
|
||||
{
|
||||
|
||||
+4
-1
@@ -628,7 +628,10 @@ gtk_gesture_filter_event (GtkEventController *controller,
|
||||
* subclasses which punch the holes in for the events
|
||||
* they can possibly handle.
|
||||
*/
|
||||
return EVENT_IS_TOUCHPAD_GESTURE (event);
|
||||
if (EVENT_IS_TOUCHPAD_GESTURE (event))
|
||||
return FALSE;
|
||||
|
||||
return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_parent_class)->filter_event (controller, event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -107,6 +107,7 @@ gtk_gizmo_new (const char *css_name,
|
||||
{
|
||||
GtkGizmo *gizmo = GTK_GIZMO (g_object_new (GTK_TYPE_GIZMO,
|
||||
"css-name", css_name,
|
||||
"name", css_name,
|
||||
NULL));
|
||||
|
||||
gizmo->measure_func = measure_func;
|
||||
|
||||
+1
-1
@@ -1726,7 +1726,7 @@ gtk_grid_layout_init (GtkGridLayout *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_grid_layou_new:
|
||||
* gtk_grid_layout_new:
|
||||
*
|
||||
* Creates a new #GtkGridLayout.
|
||||
*
|
||||
|
||||
+6
-3
@@ -576,8 +576,6 @@ gtk_info_bar_add_button (GtkInfoBar *info_bar,
|
||||
button = gtk_button_new_with_label (button_text);
|
||||
gtk_button_set_use_underline (GTK_BUTTON (button), TRUE);
|
||||
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
|
||||
gtk_widget_show (button);
|
||||
|
||||
gtk_info_bar_add_action_widget (info_bar, button, response_id);
|
||||
@@ -744,7 +742,12 @@ gtk_info_bar_set_default_response (GtkInfoBar *info_bar,
|
||||
ResponseData *rd = get_response_data (widget, FALSE);
|
||||
|
||||
if (rd && rd->response_id == response_id)
|
||||
gtk_widget_grab_default (widget);
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
window = gtk_widget_get_ancestor (GTK_WIDGET (info_bar), GTK_TYPE_WINDOW);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (window), widget);
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
+46
-78
@@ -456,8 +456,6 @@ static void gtk_label_set_markup_internal (GtkLabel *label,
|
||||
static void gtk_label_recalculate (GtkLabel *label);
|
||||
static void gtk_label_root (GtkWidget *widget);
|
||||
static void gtk_label_unroot (GtkWidget *widget);
|
||||
static void gtk_label_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *old_display);
|
||||
static gboolean gtk_label_popup_menu (GtkWidget *widget);
|
||||
|
||||
static void gtk_label_set_selectable_hint (GtkLabel *label);
|
||||
@@ -609,7 +607,6 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
widget_class->unmap = gtk_label_unmap;
|
||||
widget_class->root = gtk_label_root;
|
||||
widget_class->unroot = gtk_label_unroot;
|
||||
widget_class->display_changed = gtk_label_display_changed;
|
||||
widget_class->mnemonic_activate = gtk_label_mnemonic_activate;
|
||||
widget_class->drag_data_get = gtk_label_drag_data_get;
|
||||
widget_class->grab_focus = gtk_label_grab_focus;
|
||||
@@ -1803,28 +1800,6 @@ gtk_label_setup_mnemonic (GtkLabel *label,
|
||||
g_object_set_qdata (G_OBJECT (label), quark_mnemonic_menu, mnemonic_menu);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_root (GtkWidget *widget)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_label_parent_class)->root (widget);
|
||||
|
||||
gtk_label_setup_mnemonic (label, gtk_widget_get_toplevel (widget), priv->mnemonic_keyval);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_unroot (GtkWidget *widget)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
gtk_label_setup_mnemonic (label, NULL, priv->mnemonic_keyval);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_label_parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
label_shortcut_setting_apply (GtkLabel *label)
|
||||
{
|
||||
@@ -1861,6 +1836,50 @@ label_shortcut_setting_changed (GtkSettings *settings)
|
||||
g_list_free (list);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_root (GtkWidget *widget)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
GtkSettings *settings;
|
||||
gboolean shortcuts_connected;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_label_parent_class)->root (widget);
|
||||
|
||||
gtk_label_setup_mnemonic (label, gtk_widget_get_toplevel (widget), priv->mnemonic_keyval);
|
||||
|
||||
/* The PangoContext is replaced when the display changes, so clear the layouts */
|
||||
gtk_label_clear_layout (GTK_LABEL (widget));
|
||||
|
||||
settings = gtk_widget_get_settings (widget);
|
||||
|
||||
shortcuts_connected =
|
||||
GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (settings), quark_shortcuts_connected));
|
||||
|
||||
if (! shortcuts_connected)
|
||||
{
|
||||
g_signal_connect (settings, "notify::gtk-enable-accels",
|
||||
G_CALLBACK (label_shortcut_setting_changed),
|
||||
NULL);
|
||||
|
||||
g_object_set_qdata (G_OBJECT (settings), quark_shortcuts_connected,
|
||||
GINT_TO_POINTER (TRUE));
|
||||
}
|
||||
|
||||
label_shortcut_setting_apply (GTK_LABEL (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_unroot (GtkWidget *widget)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
gtk_label_setup_mnemonic (label, NULL, priv->mnemonic_keyval);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_label_parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
mnemonics_visible_apply (GtkWidget *widget,
|
||||
gboolean mnemonics_visible)
|
||||
@@ -1913,35 +1932,6 @@ label_mnemonics_visible_changed (GtkWindow *window,
|
||||
GINT_TO_POINTER (mnemonics_visible));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *old_display)
|
||||
{
|
||||
GtkSettings *settings;
|
||||
gboolean shortcuts_connected;
|
||||
|
||||
/* The PangoContext is replaced when the display changes, so clear the layouts */
|
||||
gtk_label_clear_layout (GTK_LABEL (widget));
|
||||
|
||||
settings = gtk_widget_get_settings (widget);
|
||||
|
||||
shortcuts_connected =
|
||||
GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (settings), quark_shortcuts_connected));
|
||||
|
||||
if (! shortcuts_connected)
|
||||
{
|
||||
g_signal_connect (settings, "notify::gtk-enable-accels",
|
||||
G_CALLBACK (label_shortcut_setting_changed),
|
||||
NULL);
|
||||
|
||||
g_object_set_qdata (G_OBJECT (settings), quark_shortcuts_connected,
|
||||
GINT_TO_POINTER (TRUE));
|
||||
}
|
||||
|
||||
label_shortcut_setting_apply (GTK_LABEL (widget));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
label_mnemonic_widget_weak_notify (gpointer data,
|
||||
GObject *where_the_object_was)
|
||||
@@ -6203,31 +6193,9 @@ gtk_label_activate_current_link (GtkLabel *label)
|
||||
link = gtk_label_get_focus_link (label);
|
||||
|
||||
if (link)
|
||||
{
|
||||
emit_activate_link (label, link);
|
||||
}
|
||||
emit_activate_link (label, link);
|
||||
else
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GtkWindow *window;
|
||||
GtkWidget *default_widget, *focus_widget;
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
{
|
||||
window = GTK_WINDOW (toplevel);
|
||||
|
||||
if (window)
|
||||
{
|
||||
default_widget = gtk_window_get_default_widget (window);
|
||||
focus_widget = gtk_root_get_focus (GTK_ROOT (window));
|
||||
|
||||
if (default_widget != widget &&
|
||||
!(widget == focus_widget && (!default_widget || !gtk_widget_is_sensitive (default_widget))))
|
||||
gtk_window_activate_default (window);
|
||||
}
|
||||
}
|
||||
}
|
||||
gtk_widget_activate_default (widget);
|
||||
}
|
||||
|
||||
static GtkLabelLink *
|
||||
|
||||
+18
-39
@@ -1046,12 +1046,12 @@ menu_change_display (GtkMenu *menu,
|
||||
}
|
||||
|
||||
static void
|
||||
attach_widget_display_changed (GtkWidget *attach_widget,
|
||||
GdkDisplay *previous_display,
|
||||
GtkMenu *menu)
|
||||
attach_widget_root_changed (GObject *attach_widget,
|
||||
GParamSpec *pspec,
|
||||
gpointer menu)
|
||||
{
|
||||
if (!g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-display"))
|
||||
menu_change_display (menu, gtk_widget_get_display (attach_widget));
|
||||
menu_change_display (menu, gtk_widget_get_display (GTK_WIDGET (attach_widget)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1107,9 +1107,9 @@ gtk_menu_attach_to_widget (GtkMenu *menu,
|
||||
data = g_slice_new (GtkMenuAttachData);
|
||||
data->attach_widget = attach_widget;
|
||||
|
||||
g_signal_connect (attach_widget, "display-changed",
|
||||
G_CALLBACK (attach_widget_display_changed), menu);
|
||||
attach_widget_display_changed (attach_widget, NULL, menu);
|
||||
g_signal_connect (attach_widget, "notify::root",
|
||||
G_CALLBACK (attach_widget_root_changed), menu);
|
||||
attach_widget_root_changed (G_OBJECT (attach_widget), NULL, menu);
|
||||
|
||||
data->detacher = detacher;
|
||||
g_object_set_data (G_OBJECT (menu), I_(attach_data_key), data);
|
||||
@@ -1189,7 +1189,7 @@ gtk_menu_detach (GtkMenu *menu)
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (data->attach_widget,
|
||||
(gpointer) attach_widget_display_changed,
|
||||
(gpointer) attach_widget_root_changed,
|
||||
menu);
|
||||
|
||||
if (data->detacher)
|
||||
@@ -1266,6 +1266,8 @@ popup_grab_on_surface (GdkSurface *surface,
|
||||
GdkGrabStatus status;
|
||||
GdkSeat *seat;
|
||||
|
||||
g_return_val_if_fail (gdk_surface_get_display (surface) == gdk_device_get_display (pointer), FALSE);
|
||||
|
||||
seat = gdk_device_get_seat (pointer);
|
||||
status = gdk_seat_grab (seat, surface,
|
||||
GDK_SEAT_CAPABILITY_ALL, TRUE,
|
||||
@@ -1321,7 +1323,11 @@ gtk_menu_popup_internal (GtkMenu *menu,
|
||||
device = NULL;
|
||||
|
||||
if (device == NULL)
|
||||
device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
|
||||
{
|
||||
device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
|
||||
g_return_if_fail (gdk_device_get_display (device) == display);
|
||||
}
|
||||
|
||||
|
||||
widget = GTK_WIDGET (menu);
|
||||
menu_shell = GTK_MENU_SHELL (menu);
|
||||
@@ -1331,6 +1337,8 @@ gtk_menu_popup_internal (GtkMenu *menu,
|
||||
else
|
||||
pointer = device;
|
||||
|
||||
g_return_if_fail (gdk_device_get_display (pointer) == display);
|
||||
|
||||
menu_shell->priv->parent_menu_shell = parent_menu_shell;
|
||||
|
||||
/* Find the last viewable ancestor, and make an X grab on it
|
||||
@@ -1437,7 +1445,7 @@ gtk_menu_popup_internal (GtkMenu *menu,
|
||||
parent_toplevel = NULL;
|
||||
if (parent_menu_shell)
|
||||
parent_toplevel = gtk_widget_get_toplevel (parent_menu_shell);
|
||||
else if (!g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-display"))
|
||||
else
|
||||
{
|
||||
GtkWidget *attach_widget = gtk_menu_get_attach_widget (menu);
|
||||
if (attach_widget)
|
||||
@@ -3604,35 +3612,6 @@ gtk_menu_select_item (GtkMenuShell *menu_shell,
|
||||
GTK_MENU_SHELL_CLASS (gtk_menu_parent_class)->select_item (menu_shell, menu_item);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_menu_set_display:
|
||||
* @menu: a #GtkMenu
|
||||
* @display: (allow-none): a #GdkDisplay, or %NULL if the display should be
|
||||
* determined by the widget the menu is attached to
|
||||
*
|
||||
* Sets the #GdkDisplay on which the menu will be displayed.
|
||||
*/
|
||||
void
|
||||
gtk_menu_set_display (GtkMenu *menu,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_MENU (menu));
|
||||
g_return_if_fail (display == NULL || GDK_IS_DISPLAY (display));
|
||||
|
||||
g_object_set_data (G_OBJECT (menu), I_("gtk-menu-explicit-display"), display);
|
||||
|
||||
if (display)
|
||||
{
|
||||
menu_change_display (menu, display);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkWidget *attach_widget = gtk_menu_get_attach_widget (menu);
|
||||
if (attach_widget)
|
||||
attach_widget_display_changed (attach_widget, NULL, menu);
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_menu_get_popup_delay (GtkMenuShell *menu_shell)
|
||||
{
|
||||
|
||||
@@ -172,10 +172,6 @@ void gtk_menu_reorder_child (GtkMenu *menu,
|
||||
GtkWidget *child,
|
||||
gint position);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_menu_set_display (GtkMenu *menu,
|
||||
GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_menu_set_monitor (GtkMenu *menu,
|
||||
gint monitor_num);
|
||||
|
||||
+5
-5
@@ -118,8 +118,7 @@ static gboolean gtk_menu_shell_key_press (GtkEventControllerKey *key,
|
||||
guint keycode,
|
||||
GdkModifierType modifiers,
|
||||
GtkWidget *widget);
|
||||
static void gtk_menu_shell_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display);
|
||||
static void gtk_menu_shell_root (GtkWidget *widget);
|
||||
static void multi_press_pressed (GtkGestureMultiPress *gesture,
|
||||
gint n_press,
|
||||
gdouble x,
|
||||
@@ -188,7 +187,7 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
|
||||
object_class->finalize = gtk_menu_shell_finalize;
|
||||
object_class->dispose = gtk_menu_shell_dispose;
|
||||
|
||||
widget_class->display_changed = gtk_menu_shell_display_changed;
|
||||
widget_class->root = gtk_menu_shell_root;
|
||||
|
||||
container_class->add = gtk_menu_shell_add;
|
||||
container_class->remove = gtk_menu_shell_remove;
|
||||
@@ -945,9 +944,10 @@ gtk_menu_shell_key_press (GtkEventControllerKey *key,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_menu_shell_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display)
|
||||
gtk_menu_shell_root (GtkWidget *widget)
|
||||
{
|
||||
GTK_WIDGET_CLASS (gtk_menu_shell_parent_class)->root (widget);
|
||||
|
||||
gtk_menu_shell_reset_key_hash (GTK_MENU_SHELL (widget));
|
||||
}
|
||||
|
||||
|
||||
@@ -455,7 +455,7 @@ pw_dialog_cycle_focus (GtkWidget *widget,
|
||||
if (next_widget)
|
||||
gtk_widget_grab_focus (next_widget);
|
||||
else if (pw_dialog_input_is_valid (operation))
|
||||
gtk_window_activate_default (GTK_WINDOW (priv->dialog));
|
||||
gtk_widget_activate_default (widget);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
|
||||
@@ -446,7 +446,7 @@ gtk_password_entry_new (void)
|
||||
/**
|
||||
* gtk_password_entry_set_show_peek_icon:
|
||||
* @entry: a #GtkPasswordEntry
|
||||
* show_peek_icon: whether to show the peek icon
|
||||
* @show_peek_icon: whether to show the peek icon
|
||||
*
|
||||
* Sets whether the entry should have a clickable icon
|
||||
* to show the contents of the entry in clear text.
|
||||
|
||||
+14
-11
@@ -151,8 +151,8 @@ static gboolean gtk_path_bar_slider_down_defocus (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
GtkPathBar *path_bar);
|
||||
static void gtk_path_bar_style_updated (GtkWidget *widget);
|
||||
static void gtk_path_bar_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display);
|
||||
static void gtk_path_bar_root (GtkWidget *widget);
|
||||
static void gtk_path_bar_unroot (GtkWidget *widget);
|
||||
static void gtk_path_bar_check_icon_theme (GtkPathBar *path_bar);
|
||||
static void gtk_path_bar_update_button_appearance (GtkPathBar *path_bar,
|
||||
ButtonData *button_data,
|
||||
@@ -273,7 +273,8 @@ gtk_path_bar_class_init (GtkPathBarClass *path_bar_class)
|
||||
widget_class->measure = gtk_path_bar_measure;
|
||||
widget_class->size_allocate = gtk_path_bar_size_allocate;
|
||||
widget_class->style_updated = gtk_path_bar_style_updated;
|
||||
widget_class->display_changed = gtk_path_bar_display_changed;
|
||||
widget_class->root = gtk_path_bar_root;
|
||||
widget_class->unroot = gtk_path_bar_unroot;
|
||||
|
||||
container_class->add = gtk_path_bar_add;
|
||||
container_class->forall = gtk_path_bar_forall;
|
||||
@@ -729,19 +730,21 @@ gtk_path_bar_style_updated (GtkWidget *widget)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_bar_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display)
|
||||
gtk_path_bar_root (GtkWidget *widget)
|
||||
{
|
||||
if (GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->display_changed)
|
||||
GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->display_changed (widget, previous_display);
|
||||
|
||||
/* We might nave a new settings, so we remove the old one */
|
||||
if (previous_display)
|
||||
remove_settings_signal (GTK_PATH_BAR (widget), previous_display);
|
||||
GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->root (widget);
|
||||
|
||||
gtk_path_bar_check_icon_theme (GTK_PATH_BAR (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_bar_unroot (GtkWidget *widget)
|
||||
{
|
||||
remove_settings_signal (GTK_PATH_BAR (widget), gtk_widget_get_display (widget));
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_path_bar_scroll_controller_scroll (GtkEventControllerScroll *scroll,
|
||||
gdouble dx,
|
||||
|
||||
@@ -2688,7 +2688,6 @@ create_rename_popover (GtkPlacesSidebar *sidebar)
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
|
||||
g_free (str);
|
||||
button = gtk_button_new_with_mnemonic (_("_Rename"));
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "suggested-action");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (do_rename), sidebar);
|
||||
error = gtk_label_new ("");
|
||||
|
||||
+56
-4
@@ -155,6 +155,7 @@ enum {
|
||||
PROP_POSITION,
|
||||
PROP_MODAL,
|
||||
PROP_CONSTRAIN_TO,
|
||||
PROP_DEFAULT_WIDGET,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
@@ -345,6 +346,40 @@ gesture_released (GtkGestureMultiPress *gesture,
|
||||
gtk_popover_popdown (popover);
|
||||
}
|
||||
|
||||
static void
|
||||
activate_default_cb (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPopover *popover = data;
|
||||
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
|
||||
GtkWidget *focus_widget;
|
||||
|
||||
focus_widget = gtk_window_get_focus (GTK_WINDOW (gtk_widget_get_root (priv->widget)));
|
||||
if (priv->default_widget && gtk_widget_is_sensitive (priv->default_widget) &&
|
||||
(!focus_widget || !gtk_widget_get_receives_default (focus_widget)))
|
||||
gtk_widget_activate (priv->default_widget);
|
||||
else if (focus_widget && gtk_widget_is_sensitive (focus_widget))
|
||||
gtk_widget_activate (focus_widget);
|
||||
}
|
||||
|
||||
static void
|
||||
add_actions (GtkPopover *popover)
|
||||
{
|
||||
GActionEntry entries[] = {
|
||||
{ "activate", activate_default_cb, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
GActionGroup *actions;
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
||||
entries, G_N_ELEMENTS (entries),
|
||||
popover);
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (popover), "default", actions);
|
||||
g_object_unref (actions);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_init (GtkPopover *popover)
|
||||
{
|
||||
@@ -389,6 +424,8 @@ gtk_popover_init (GtkPopover *popover)
|
||||
g_signal_connect (controller, "released",
|
||||
G_CALLBACK (gesture_released), popover);
|
||||
gtk_widget_add_controller (widget, controller);
|
||||
|
||||
add_actions (popover);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -419,6 +456,10 @@ gtk_popover_set_property (GObject *object,
|
||||
gtk_popover_set_constrain_to (GTK_POPOVER (object),
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_DEFAULT_WIDGET:
|
||||
gtk_popover_set_default_widget (GTK_POPOVER (object),
|
||||
g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -449,6 +490,9 @@ gtk_popover_get_property (GObject *object,
|
||||
case PROP_CONSTRAIN_TO:
|
||||
g_value_set_enum (value, priv->constraint);
|
||||
break;
|
||||
case PROP_DEFAULT_WIDGET:
|
||||
g_value_set_object (value, priv->default_widget);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -818,7 +862,7 @@ gtk_popover_map (GtkWidget *widget)
|
||||
gdk_surface_show (gtk_widget_get_surface (widget));
|
||||
gtk_popover_update_position (GTK_POPOVER (widget));
|
||||
|
||||
gtk_window_set_default (priv->window, priv->default_widget);
|
||||
gtk_window_set_default_widget (priv->window, priv->default_widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -832,7 +876,7 @@ gtk_popover_unmap (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (gtk_popover_parent_class)->unmap (widget);
|
||||
|
||||
if (gtk_window_get_default_widget (priv->window) == priv->default_widget)
|
||||
gtk_window_set_default (priv->window, priv->prev_default);
|
||||
gtk_window_set_default_widget (priv->window, priv->prev_default);
|
||||
g_clear_object (&priv->prev_default);
|
||||
}
|
||||
|
||||
@@ -1645,6 +1689,13 @@ gtk_popover_class_init (GtkPopoverClass *klass)
|
||||
GTK_TYPE_POPOVER_CONSTRAINT, GTK_POPOVER_CONSTRAINT_WINDOW,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
properties[PROP_DEFAULT_WIDGET] =
|
||||
g_param_spec_object ("default-widget",
|
||||
P_("Default widget"),
|
||||
P_("The default widget"),
|
||||
GTK_TYPE_WIDGET,
|
||||
GTK_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
|
||||
|
||||
/**
|
||||
@@ -2378,7 +2429,6 @@ gtk_popover_set_default_widget (GtkPopover *popover,
|
||||
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
|
||||
|
||||
g_return_if_fail (GTK_IS_POPOVER (popover));
|
||||
g_return_if_fail (widget == NULL || gtk_widget_get_can_default (widget));
|
||||
|
||||
if (priv->default_widget == widget)
|
||||
return;
|
||||
@@ -2392,7 +2442,9 @@ gtk_popover_set_default_widget (GtkPopover *popover,
|
||||
g_object_ref (priv->default_widget);
|
||||
|
||||
if (gtk_widget_get_mapped (GTK_WIDGET (popover)))
|
||||
gtk_window_set_default (priv->window, priv->default_widget);
|
||||
gtk_window_set_default_widget (priv->window, priv->default_widget);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (popover), properties[PROP_DEFAULT_WIDGET]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -611,6 +611,16 @@ gtk_snapshot_ensure_identity (GtkSnapshot *snapshot)
|
||||
gtk_snapshot_autopush_transform (snapshot);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_push_repeat:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @bounds: the bounds within which to repeat
|
||||
* @child_bounds: the bounds of the child
|
||||
*
|
||||
* Creates a node that repeats the child node.
|
||||
*
|
||||
* The child is recorded until the next call to gtk_snapshot_pop().
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_push_repeat (GtkSnapshot *snapshot,
|
||||
const graphene_rect_t *bounds,
|
||||
|
||||
@@ -809,6 +809,14 @@ button_released_cb (GtkGestureMultiPress *gesture,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
button_cancel_cb (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence,
|
||||
GtkSpinButton *spin_button)
|
||||
{
|
||||
gtk_spin_button_stop_spinning (spin_button);
|
||||
}
|
||||
|
||||
static void
|
||||
key_controller_key_released (GtkEventControllerKey *key,
|
||||
guint keyval,
|
||||
@@ -886,6 +894,7 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
|
||||
GTK_PHASE_CAPTURE);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (button_pressed_cb), spin_button);
|
||||
g_signal_connect (gesture, "released", G_CALLBACK (button_released_cb), spin_button);
|
||||
g_signal_connect (gesture, "cancel", G_CALLBACK (button_cancel_cb), spin_button);
|
||||
gtk_widget_add_controller (GTK_WIDGET (priv->down_button), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
priv->up_button = gtk_button_new ();
|
||||
@@ -902,6 +911,7 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
|
||||
GTK_PHASE_CAPTURE);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (button_pressed_cb), spin_button);
|
||||
g_signal_connect (gesture, "released", G_CALLBACK (button_released_cb), spin_button);
|
||||
g_signal_connect (gesture, "cancel", G_CALLBACK (button_cancel_cb), spin_button);
|
||||
gtk_widget_add_controller (GTK_WIDGET (priv->up_button), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
gtk_spin_button_set_adjustment (spin_button, NULL);
|
||||
|
||||
+26
-28
@@ -324,8 +324,7 @@ static void gtk_text_direction_changed (GtkWidget *widget,
|
||||
GtkTextDirection previous_dir);
|
||||
static void gtk_text_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state);
|
||||
static void gtk_text_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *old_display);
|
||||
static void gtk_text_root (GtkWidget *widget);
|
||||
|
||||
static gboolean gtk_text_drag_drop (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
@@ -679,7 +678,7 @@ gtk_text_class_init (GtkTextClass *class)
|
||||
widget_class->drag_end = gtk_text_drag_end;
|
||||
widget_class->direction_changed = gtk_text_direction_changed;
|
||||
widget_class->state_flags_changed = gtk_text_state_flags_changed;
|
||||
widget_class->display_changed = gtk_text_display_changed;
|
||||
widget_class->root = gtk_text_root;
|
||||
widget_class->mnemonic_activate = gtk_text_mnemonic_activate;
|
||||
widget_class->popup_menu = gtk_text_popup_menu;
|
||||
widget_class->drag_drop = gtk_text_drag_drop;
|
||||
@@ -3029,9 +3028,10 @@ gtk_text_state_flags_changed (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *old_display)
|
||||
gtk_text_root (GtkWidget *widget)
|
||||
{
|
||||
GTK_WIDGET_CLASS (gtk_text_parent_class)->root (widget);
|
||||
|
||||
gtk_text_recompute (GTK_TEXT (widget));
|
||||
}
|
||||
|
||||
@@ -3839,30 +3839,9 @@ static void
|
||||
gtk_text_real_activate (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GtkWindow *window;
|
||||
GtkWidget *default_widget, *focus_widget;
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = GTK_WIDGET (self);
|
||||
|
||||
if (priv->activates_default)
|
||||
{
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
if (GTK_IS_WINDOW (toplevel))
|
||||
{
|
||||
window = GTK_WINDOW (toplevel);
|
||||
|
||||
if (window)
|
||||
{
|
||||
default_widget = gtk_window_get_default_widget (window);
|
||||
focus_widget = gtk_root_get_focus (GTK_ROOT (window));
|
||||
if (widget != default_widget &&
|
||||
!(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
|
||||
gtk_window_activate_default (window);
|
||||
}
|
||||
}
|
||||
}
|
||||
gtk_widget_activate_default (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6617,9 +6596,25 @@ gtk_text_get_tabs (GtkText *self)
|
||||
return priv->tabs;
|
||||
}
|
||||
|
||||
static void
|
||||
emoji_picked (GtkEmojiChooser *chooser,
|
||||
const char *text,
|
||||
GtkText *self)
|
||||
{
|
||||
int current_pos;
|
||||
int selection_bound;
|
||||
|
||||
current_pos = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (chooser), "current-pos"));
|
||||
selection_bound = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (chooser), "selection-bound"));
|
||||
|
||||
gtk_text_set_positions (self, current_pos, selection_bound);
|
||||
gtk_text_enter_text (self, text);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_insert_emoji (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GtkWidget *chooser;
|
||||
|
||||
if (gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_EMOJI_CHOOSER) != NULL)
|
||||
@@ -6632,9 +6627,12 @@ gtk_text_insert_emoji (GtkText *self)
|
||||
g_object_set_data (G_OBJECT (self), "gtk-emoji-chooser", chooser);
|
||||
|
||||
gtk_popover_set_relative_to (GTK_POPOVER (chooser), GTK_WIDGET (self));
|
||||
g_signal_connect_swapped (chooser, "emoji-picked", G_CALLBACK (gtk_text_enter_text), self);
|
||||
g_signal_connect (chooser, "emoji-picked", G_CALLBACK (emoji_picked), self);
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (chooser), "current-pos", GINT_TO_POINTER (priv->current_pos));
|
||||
g_object_set_data (G_OBJECT (chooser), "selection-bound", GINT_TO_POINTER (priv->selection_bound));
|
||||
|
||||
gtk_popover_popup (GTK_POPOVER (chooser));
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,7 @@ typedef struct _GtkTextClass GtkTextClass;
|
||||
* non-%NULL, this will be called to add additional entries to the context
|
||||
* menu when it is displayed.
|
||||
* @activate: Class handler for the #GtkText::activate signal. The default
|
||||
* implementation calls gtk_window_activate_default() on the entry’s top-level
|
||||
* window.
|
||||
* implementation activates the gtk.activate-default action.
|
||||
* @move_cursor: Class handler for the #GtkText::move-cursor signal. The
|
||||
* default implementation specifies the standard #GtkText cursor movement
|
||||
* behavior.
|
||||
|
||||
+1
-1
@@ -201,7 +201,7 @@ limit_layout_lines (PangoLayout *layout)
|
||||
GdkPaintable *
|
||||
gtk_text_util_create_drag_icon (GtkWidget *widget,
|
||||
gchar *text,
|
||||
gsize len)
|
||||
gssize len)
|
||||
{
|
||||
GtkStyleContext *style_context;
|
||||
GtkSnapshot *snapshot;
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ void _gtk_text_util_append_special_char_menuitems (GtkMenuShell *me
|
||||
|
||||
GdkPaintable * gtk_text_util_create_drag_icon (GtkWidget *widget,
|
||||
gchar *text,
|
||||
gsize len);
|
||||
gssize len);
|
||||
GdkPaintable * gtk_text_util_create_rich_drag_icon (GtkWidget *widget,
|
||||
GtkTextBuffer *buffer,
|
||||
GtkTextIter *start,
|
||||
|
||||
+27
-27
@@ -186,8 +186,8 @@ static gboolean gtk_toolbar_focus (GtkWidget *widget,
|
||||
GtkDirectionType dir);
|
||||
static void gtk_toolbar_move_focus (GtkWidget *widget,
|
||||
GtkDirectionType dir);
|
||||
static void gtk_toolbar_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display);
|
||||
static void gtk_toolbar_root (GtkWidget *widget);
|
||||
static void gtk_toolbar_unroot (GtkWidget *widget);
|
||||
static void gtk_toolbar_finalize (GObject *object);
|
||||
static void gtk_toolbar_dispose (GObject *object);
|
||||
static void gtk_toolbar_add (GtkContainer *container,
|
||||
@@ -362,7 +362,8 @@ gtk_toolbar_class_init (GtkToolbarClass *klass)
|
||||
GTK_TYPE_TOOLBAR,
|
||||
G_CALLBACK (gtk_toolbar_move_focus));
|
||||
|
||||
widget_class->display_changed = gtk_toolbar_display_changed;
|
||||
widget_class->root = gtk_toolbar_root;
|
||||
widget_class->unroot = gtk_toolbar_unroot;
|
||||
widget_class->popup_menu = gtk_toolbar_popup_menu;
|
||||
|
||||
container_class->add = gtk_toolbar_add;
|
||||
@@ -1645,41 +1646,40 @@ settings_change_notify (GtkSettings *settings,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_toolbar_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display)
|
||||
gtk_toolbar_root (GtkWidget *widget)
|
||||
{
|
||||
GtkToolbar *toolbar = GTK_TOOLBAR (widget);
|
||||
GtkToolbarPrivate *priv = toolbar->priv;
|
||||
GtkSettings *old_settings = toolbar_get_settings (toolbar);
|
||||
GtkSettings *settings;
|
||||
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_toolbar_parent_class)->root (widget);
|
||||
|
||||
settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
|
||||
|
||||
if (settings == old_settings)
|
||||
return;
|
||||
|
||||
if (old_settings)
|
||||
{
|
||||
g_signal_handler_disconnect (old_settings, priv->settings_connection);
|
||||
priv->settings_connection = 0;
|
||||
g_object_unref (old_settings);
|
||||
}
|
||||
|
||||
if (settings)
|
||||
{
|
||||
priv->settings_connection =
|
||||
g_signal_connect (settings, "notify",
|
||||
G_CALLBACK (settings_change_notify),
|
||||
toolbar);
|
||||
priv->settings_connection =
|
||||
g_signal_connect (settings, "notify",
|
||||
G_CALLBACK (settings_change_notify),
|
||||
toolbar);
|
||||
|
||||
priv->settings = g_object_ref (settings);
|
||||
}
|
||||
else
|
||||
priv->settings = NULL;
|
||||
priv->settings = g_object_ref (settings);
|
||||
|
||||
animation_change_notify (toolbar);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_toolbar_unroot (GtkWidget *widget)
|
||||
{
|
||||
GtkToolbar *toolbar = GTK_TOOLBAR (widget);
|
||||
GtkToolbarPrivate *priv = toolbar->priv;
|
||||
|
||||
if (priv->settings_connection)
|
||||
g_signal_handler_disconnect (priv->settings, priv->settings_connection);
|
||||
priv->settings_connection = 0;
|
||||
g_clear_object (&priv->settings);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_toolbar_parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
static int
|
||||
find_drop_index (GtkToolbar *toolbar,
|
||||
gint x,
|
||||
|
||||
@@ -689,8 +689,6 @@ gtk_tooltip_show_tooltip (GdkDisplay *display)
|
||||
tooltip = g_object_get_qdata (G_OBJECT (display), quark_current_tooltip);
|
||||
|
||||
{
|
||||
gint tx, ty;
|
||||
|
||||
surface = tooltip->last_surface;
|
||||
|
||||
if (!GDK_IS_SURFACE (surface))
|
||||
@@ -702,7 +700,6 @@ gtk_tooltip_show_tooltip (GdkDisplay *display)
|
||||
x = round (px);
|
||||
y = round (py);
|
||||
|
||||
gdk_surface_get_root_coords (surface, x, y, &tx, &ty);
|
||||
tooltip_widget = _gtk_widget_find_at_coords (surface, x, y, &x, &y);
|
||||
}
|
||||
|
||||
|
||||
+3
-59
@@ -398,11 +398,6 @@ struct _GtkTreeViewPrivate
|
||||
gint drag_pos;
|
||||
gint x_drag;
|
||||
|
||||
/* Non-interactive Header Resizing, expand flag support */
|
||||
gint last_extra_space;
|
||||
gint last_extra_space_per_column;
|
||||
gint last_number_of_expand_columns;
|
||||
|
||||
/* Row drag-and-drop */
|
||||
GtkTreeRowReference *drag_dest_row;
|
||||
GtkTreeViewDropPosition drag_dest_pos;
|
||||
@@ -502,8 +497,6 @@ struct _GtkTreeViewPrivate
|
||||
|
||||
guint in_grab : 1;
|
||||
|
||||
guint post_validation_flag : 1;
|
||||
|
||||
/* Whether our key press handler is to avoid sending an unhandled binding to the search entry */
|
||||
guint search_entry_avoid_unhandled_binding : 1;
|
||||
|
||||
@@ -1704,8 +1697,6 @@ gtk_tree_view_init (GtkTreeView *tree_view)
|
||||
|
||||
priv->tooltip_column = -1;
|
||||
|
||||
priv->post_validation_flag = FALSE;
|
||||
|
||||
priv->event_last_x = -10000;
|
||||
priv->event_last_y = -10000;
|
||||
|
||||
@@ -2397,11 +2388,10 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget)
|
||||
GList *list, *first_column, *last_column;
|
||||
GtkTreeViewColumn *column;
|
||||
gint widget_width, width = 0;
|
||||
gint extra, extra_per_column, extra_for_last;
|
||||
gint extra, extra_per_column;
|
||||
gint full_requested_width = 0;
|
||||
gint number_of_expand_columns = 0;
|
||||
gboolean rtl;
|
||||
gboolean update_expand;
|
||||
|
||||
for (last_column = g_list_last (tree_view->priv->columns);
|
||||
last_column &&
|
||||
@@ -2436,41 +2426,14 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget)
|
||||
number_of_expand_columns++;
|
||||
}
|
||||
|
||||
/* Only update the expand value if the number of expand columns has changed,
|
||||
* or if there are no expand columns, or if we didn't have an size-allocation
|
||||
* yet after the last validated node.
|
||||
*/
|
||||
update_expand = number_of_expand_columns != tree_view->priv->last_number_of_expand_columns
|
||||
|| number_of_expand_columns == 0
|
||||
|| tree_view->priv->post_validation_flag == TRUE;
|
||||
|
||||
tree_view->priv->post_validation_flag = FALSE;
|
||||
|
||||
widget_width = gtk_widget_get_width (widget);
|
||||
if (!update_expand)
|
||||
{
|
||||
extra = tree_view->priv->last_extra_space;
|
||||
extra_for_last = MAX (widget_width - full_requested_width - extra, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
extra = MAX (widget_width - full_requested_width, 0);
|
||||
extra_for_last = 0;
|
||||
|
||||
tree_view->priv->last_extra_space = extra;
|
||||
}
|
||||
extra = MAX (widget_width - full_requested_width, 0);
|
||||
|
||||
if (number_of_expand_columns > 0)
|
||||
extra_per_column = extra/number_of_expand_columns;
|
||||
else
|
||||
extra_per_column = 0;
|
||||
|
||||
if (update_expand)
|
||||
{
|
||||
tree_view->priv->last_extra_space_per_column = extra_per_column;
|
||||
tree_view->priv->last_number_of_expand_columns = number_of_expand_columns;
|
||||
}
|
||||
|
||||
for (list = first_column;
|
||||
list != last_column->next;
|
||||
list = list->next)
|
||||
@@ -2507,12 +2470,6 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget)
|
||||
column_width += extra;
|
||||
}
|
||||
|
||||
/* In addition to expand, the last column can get even more
|
||||
* extra space so all available space is filled up.
|
||||
*/
|
||||
if (extra_for_last > 0 && list == last_column)
|
||||
column_width += extra_for_last;
|
||||
|
||||
if (rtl)
|
||||
_gtk_tree_view_column_allocate (column, widget_width - width - column_width + x_offset,
|
||||
column_width, tree_view->priv->header_height);
|
||||
@@ -2527,10 +2484,7 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget)
|
||||
* which changes the total width of the tree view. This is of
|
||||
* importance for getting the horizontal scroll bar right.
|
||||
*/
|
||||
if (tree_view->priv->width != width)
|
||||
{
|
||||
tree_view->priv->width = width;
|
||||
}
|
||||
tree_view->priv->width = width;
|
||||
}
|
||||
|
||||
/* GtkWidget::size_allocate helper */
|
||||
@@ -5686,7 +5640,6 @@ validate_row (GtkTreeView *tree_view,
|
||||
gtk_tree_rbtree_node_set_height (tree, node, height);
|
||||
}
|
||||
gtk_tree_rbtree_node_mark_valid (tree, node);
|
||||
tree_view->priv->post_validation_flag = TRUE;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -9441,16 +9394,12 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
|
||||
GtkTreeRBTree *new_cursor_tree = NULL;
|
||||
GtkTreeRBNode *new_cursor_node = NULL;
|
||||
GtkTreePath *cursor_path = NULL;
|
||||
gboolean grab_focus = TRUE;
|
||||
gboolean selectable;
|
||||
GtkDirectionType direction;
|
||||
GtkCellArea *cell_area = NULL;
|
||||
GtkCellRenderer *last_focus_cell = NULL;
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (! gtk_widget_has_focus (GTK_WIDGET (tree_view)))
|
||||
return;
|
||||
|
||||
if (tree_view->priv->cursor_node == NULL)
|
||||
return;
|
||||
|
||||
@@ -9576,8 +9525,6 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
|
||||
count < 0 ?
|
||||
GTK_DIR_TAB_BACKWARD :
|
||||
GTK_DIR_TAB_FORWARD);
|
||||
|
||||
grab_focus = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -9588,9 +9535,6 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
|
||||
if (cell_area)
|
||||
gtk_cell_area_set_focus_cell (cell_area, last_focus_cell);
|
||||
}
|
||||
|
||||
if (grab_focus)
|
||||
gtk_widget_grab_focus (GTK_WIDGET (tree_view));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+89
-267
@@ -548,7 +548,6 @@ enum {
|
||||
PROP_IS_FOCUS,
|
||||
PROP_CAN_TARGET,
|
||||
PROP_FOCUS_ON_CLICK,
|
||||
PROP_CAN_DEFAULT,
|
||||
PROP_HAS_DEFAULT,
|
||||
PROP_RECEIVES_DEFAULT,
|
||||
PROP_CURSOR,
|
||||
@@ -633,8 +632,6 @@ static void gtk_widget_real_move_focus (GtkWidget
|
||||
GtkDirectionType direction);
|
||||
static gboolean gtk_widget_real_keynav_failed (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
static void gtk_widget_root (GtkWidget *widget);
|
||||
static void gtk_widget_unroot (GtkWidget *widget);
|
||||
#ifdef G_ENABLE_CONSISTENCY_CHECKS
|
||||
static void gtk_widget_verify_invariants (GtkWidget *widget);
|
||||
static void gtk_widget_push_verify_invariants (GtkWidget *widget);
|
||||
@@ -676,10 +673,6 @@ static const gchar * gtk_widget_buildable_get_name (GtkBuildable
|
||||
static GObject * gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *childname);
|
||||
static void gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *name,
|
||||
const GValue *value);
|
||||
static gboolean gtk_widget_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
@@ -923,7 +916,6 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
klass->drag_motion = NULL;
|
||||
klass->drag_drop = NULL;
|
||||
klass->drag_data_received = NULL;
|
||||
klass->display_changed = NULL;
|
||||
klass->can_activate_accel = gtk_widget_real_can_activate_accel;
|
||||
klass->query_tooltip = gtk_widget_real_query_tooltip;
|
||||
klass->style_updated = gtk_widget_real_style_updated;
|
||||
@@ -1037,19 +1029,12 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
widget_props[PROP_CAN_DEFAULT] =
|
||||
g_param_spec_boolean ("can-default",
|
||||
P_("Can default"),
|
||||
P_("Whether the widget can be the default widget"),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
widget_props[PROP_HAS_DEFAULT] =
|
||||
g_param_spec_boolean ("has-default",
|
||||
P_("Has default"),
|
||||
P_("Whether the widget is the default widget"),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
GTK_PARAM_READABLE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
widget_props[PROP_RECEIVES_DEFAULT] =
|
||||
g_param_spec_boolean ("receives-default",
|
||||
@@ -2089,25 +2074,6 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GtkWidget::display-changed:
|
||||
* @widget: the object on which the signal is emitted
|
||||
* @previous_display: (allow-none): the previous screen, or %NULL if the
|
||||
* widget was not associated with a screen before
|
||||
*
|
||||
* The ::display-changed signal gets emitted when the
|
||||
* display of a widget has changed.
|
||||
*/
|
||||
widget_signals[DISPLAY_CHANGED] =
|
||||
g_signal_new (I_("display-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkWidgetClass, display_changed),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DISPLAY);
|
||||
|
||||
/**
|
||||
* GtkWidget::can-activate-accel:
|
||||
* @widget: the object which received the signal
|
||||
@@ -2194,13 +2160,6 @@ gtk_widget_set_property (GObject *object,
|
||||
case PROP_FOCUS_ON_CLICK:
|
||||
gtk_widget_set_focus_on_click (widget, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_CAN_DEFAULT:
|
||||
gtk_widget_set_can_default (widget, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_HAS_DEFAULT:
|
||||
if (g_value_get_boolean (value))
|
||||
gtk_widget_grab_default (widget);
|
||||
break;
|
||||
case PROP_RECEIVES_DEFAULT:
|
||||
gtk_widget_set_receives_default (widget, g_value_get_boolean (value));
|
||||
break;
|
||||
@@ -2375,9 +2334,6 @@ gtk_widget_get_property (GObject *object,
|
||||
case PROP_FOCUS_ON_CLICK:
|
||||
g_value_set_boolean (value, gtk_widget_get_focus_on_click (widget));
|
||||
break;
|
||||
case PROP_CAN_DEFAULT:
|
||||
g_value_set_boolean (value, gtk_widget_get_can_default (widget));
|
||||
break;
|
||||
case PROP_HAS_DEFAULT:
|
||||
g_value_set_boolean (value, gtk_widget_has_default (widget));
|
||||
break;
|
||||
@@ -2887,21 +2843,22 @@ gtk_widget_new (GType type,
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gtk_widget_root (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
/* roots are rooted by default */
|
||||
if (GTK_IS_ROOT (widget))
|
||||
return;
|
||||
|
||||
g_assert (priv->root == NULL);
|
||||
g_assert (!priv->realized);
|
||||
g_assert (priv->parent);
|
||||
g_assert (priv->parent->priv->root);
|
||||
|
||||
priv->root = priv->parent->priv->root;
|
||||
if (GTK_IS_ROOT (widget))
|
||||
{
|
||||
g_assert (priv->root == GTK_ROOT (widget));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (priv->root == NULL);
|
||||
priv->root = priv->parent->priv->root;
|
||||
}
|
||||
|
||||
if (priv->context)
|
||||
gtk_style_context_set_display (priv->context, gtk_root_get_display (priv->root));
|
||||
@@ -2911,19 +2868,16 @@ gtk_widget_root (GtkWidget *widget)
|
||||
|
||||
GTK_WIDGET_GET_CLASS (widget)->root (widget);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_ROOT]);
|
||||
if (!GTK_IS_ROOT (widget))
|
||||
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_ROOT]);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gtk_widget_unroot (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
GtkWidgetSurfaceTransformData *surface_transform_data;
|
||||
|
||||
/* roots are rooted by default and cannot be unrooted */
|
||||
if (GTK_IS_ROOT (widget))
|
||||
return;
|
||||
|
||||
g_assert (priv->root);
|
||||
g_assert (!priv->realized);
|
||||
|
||||
@@ -2937,9 +2891,16 @@ gtk_widget_unroot (GtkWidget *widget)
|
||||
if (priv->context)
|
||||
gtk_style_context_set_display (priv->context, gdk_display_get_default ());
|
||||
|
||||
priv->root = NULL;
|
||||
if (g_object_get_qdata (G_OBJECT (widget), quark_pango_context))
|
||||
g_object_set_qdata (G_OBJECT (widget), quark_pango_context, NULL);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_ROOT]);
|
||||
_gtk_tooltip_hide (widget);
|
||||
|
||||
if (!GTK_IS_ROOT (widget))
|
||||
{
|
||||
priv->root = NULL;
|
||||
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_ROOT]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5478,7 +5439,8 @@ static void
|
||||
gtk_widget_real_grab_focus (GtkWidget *focus_widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (focus_widget);
|
||||
gtk_root_set_focus (priv->root, focus_widget);
|
||||
if (priv->root)
|
||||
gtk_root_set_focus (priv->root, focus_widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -5818,58 +5780,12 @@ gtk_widget_get_focus_on_click (GtkWidget *widget)
|
||||
return priv->focus_on_click;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_widget_set_can_default:
|
||||
* @widget: a #GtkWidget
|
||||
* @can_default: whether or not @widget can be a default widget.
|
||||
*
|
||||
* Specifies whether @widget can be a default widget. See
|
||||
* gtk_widget_grab_default() for details about the meaning of
|
||||
* “default”.
|
||||
**/
|
||||
void
|
||||
gtk_widget_set_can_default (GtkWidget *widget,
|
||||
gboolean can_default)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
if (priv->can_default != can_default)
|
||||
{
|
||||
priv->can_default = can_default;
|
||||
|
||||
gtk_widget_queue_resize (widget);
|
||||
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_CAN_DEFAULT]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_can_default:
|
||||
* @widget: a #GtkWidget
|
||||
*
|
||||
* Determines whether @widget can be a default widget. See
|
||||
* gtk_widget_set_can_default().
|
||||
*
|
||||
* Returns: %TRUE if @widget can be a default widget, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
gtk_widget_get_can_default (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
||||
|
||||
return priv->can_default;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_has_default:
|
||||
* @widget: a #GtkWidget
|
||||
*
|
||||
* Determines whether @widget is the current default widget within its
|
||||
* toplevel. See gtk_widget_set_can_default().
|
||||
* toplevel.
|
||||
*
|
||||
* Returns: %TRUE if @widget is the current default widget within
|
||||
* its toplevel, %FALSE otherwise
|
||||
@@ -5901,47 +5817,14 @@ _gtk_widget_set_has_default (GtkWidget *widget,
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_grab_default:
|
||||
* @widget: a #GtkWidget
|
||||
*
|
||||
* Causes @widget to become the default widget. @widget must be able to be
|
||||
* a default widget; typically you would ensure this yourself
|
||||
* by calling gtk_widget_set_can_default() with a %TRUE value.
|
||||
* The default widget is activated when
|
||||
* the user presses Enter in a window. Default widgets must be
|
||||
* activatable, that is, gtk_widget_activate() should affect them. Note
|
||||
* that #GtkEntry widgets require the “activates-default” property
|
||||
* set to %TRUE before they activate the default widget when Enter
|
||||
* is pressed and the #GtkEntry is focused.
|
||||
**/
|
||||
void
|
||||
gtk_widget_grab_default (GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (gtk_widget_get_can_default (widget));
|
||||
|
||||
window = _gtk_widget_get_toplevel (widget);
|
||||
|
||||
if (window && _gtk_widget_is_toplevel (window))
|
||||
gtk_window_set_default (GTK_WINDOW (window), widget);
|
||||
else
|
||||
g_warning (G_STRLOC ": widget not within a GtkWindow");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_set_receives_default:
|
||||
* @widget: a #GtkWidget
|
||||
* @receives_default: whether or not @widget can be a default widget.
|
||||
*
|
||||
* Specifies whether @widget will be treated as the default widget
|
||||
* within its toplevel when it has the focus, even if another widget
|
||||
* is the default.
|
||||
*
|
||||
* See gtk_widget_grab_default() for details about the meaning of
|
||||
* “default”.
|
||||
* Specifies whether @widget will be treated as the default
|
||||
* widget within its toplevel when it has the focus, even if
|
||||
* another widget is the default.
|
||||
**/
|
||||
void
|
||||
gtk_widget_set_receives_default (GtkWidget *widget,
|
||||
@@ -6480,6 +6363,7 @@ gtk_widget_set_sensitive (GtkWidget *widget,
|
||||
gboolean sensitive)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
GList *l;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
@@ -6490,6 +6374,13 @@ gtk_widget_set_sensitive (GtkWidget *widget,
|
||||
|
||||
priv->sensitive = sensitive;
|
||||
|
||||
for (l = priv->event_controllers; l; l = l->next)
|
||||
{
|
||||
GtkEventController *controller = l->data;
|
||||
|
||||
gtk_event_controller_reset (controller);
|
||||
}
|
||||
|
||||
if (priv->parent == NULL
|
||||
|| gtk_widget_is_sensitive (priv->parent))
|
||||
{
|
||||
@@ -6791,84 +6682,6 @@ gtk_widget_real_direction_changed (GtkWidget *widget,
|
||||
gtk_widget_queue_resize (widget);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *previous_toplevel;
|
||||
GdkDisplay *previous_display;
|
||||
GdkDisplay *new_display;
|
||||
} HierarchyChangedInfo;
|
||||
|
||||
static void
|
||||
do_display_change (GtkWidget *widget,
|
||||
GdkDisplay *old_display,
|
||||
GdkDisplay *new_display)
|
||||
{
|
||||
if (old_display != new_display)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
if (old_display)
|
||||
{
|
||||
PangoContext *context = g_object_get_qdata (G_OBJECT (widget), quark_pango_context);
|
||||
if (context)
|
||||
g_object_set_qdata (G_OBJECT (widget), quark_pango_context, NULL);
|
||||
}
|
||||
|
||||
_gtk_tooltip_hide (widget);
|
||||
|
||||
if (new_display && priv->context)
|
||||
gtk_style_context_set_display (priv->context, new_display);
|
||||
|
||||
g_signal_emit (widget, widget_signals[DISPLAY_CHANGED], 0, old_display);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_propagate_display_changed_recurse (GtkWidget *widget,
|
||||
gpointer client_data)
|
||||
{
|
||||
HierarchyChangedInfo *info = client_data;
|
||||
GtkWidget *child;
|
||||
|
||||
g_object_ref (widget);
|
||||
|
||||
do_display_change (widget, info->previous_display, info->new_display);
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
gtk_widget_propagate_display_changed_recurse (child, client_data);
|
||||
}
|
||||
|
||||
g_object_unref (widget);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_widget_propagate_display_changed:
|
||||
* @widget: a #GtkWidget
|
||||
* @previous_display: Previous display
|
||||
*
|
||||
* Propagates changes in the display for a widget to all
|
||||
* children, emitting #GtkWidget::display-changed.
|
||||
**/
|
||||
void
|
||||
_gtk_widget_propagate_display_changed (GtkWidget *widget,
|
||||
GdkDisplay *previous_display)
|
||||
{
|
||||
HierarchyChangedInfo info;
|
||||
|
||||
info.previous_display = previous_display;
|
||||
info.new_display = gtk_widget_get_display (widget);
|
||||
|
||||
if (previous_display)
|
||||
g_object_ref (previous_display);
|
||||
|
||||
gtk_widget_propagate_display_changed_recurse (widget, &info);
|
||||
|
||||
if (previous_display)
|
||||
g_object_unref (previous_display);
|
||||
}
|
||||
|
||||
static void
|
||||
reset_style_recurse (GtkWidget *widget, gpointer user_data)
|
||||
{
|
||||
@@ -6926,17 +6739,17 @@ gtk_widget_verify_invariants (GtkWidget *widget)
|
||||
|
||||
if (!priv->realized)
|
||||
g_warning ("%s %p is mapped but not realized",
|
||||
G_OBJECT_TYPE_NAME (widget), widget);
|
||||
gtk_widget_get_name (widget), widget);
|
||||
|
||||
if (!priv->visible)
|
||||
g_warning ("%s %p is mapped but not visible",
|
||||
G_OBJECT_TYPE_NAME (widget), widget);
|
||||
gtk_widget_get_name (widget), widget);
|
||||
|
||||
if (!GTK_IS_ROOT (widget))
|
||||
{
|
||||
if (!priv->child_visible)
|
||||
g_warning ("%s %p is mapped but not child_visible",
|
||||
G_OBJECT_TYPE_NAME (widget), widget);
|
||||
gtk_widget_get_name (widget), widget);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -6986,8 +6799,8 @@ gtk_widget_verify_invariants (GtkWidget *widget)
|
||||
|
||||
if (priv->realized)
|
||||
g_warning ("%s %p is not realized but child %s %p is realized",
|
||||
parent ? G_OBJECT_TYPE_NAME (parent) : "no parent", parent,
|
||||
G_OBJECT_TYPE_NAME (widget), widget);
|
||||
parent ? gtk_widget_get_name (parent) : "no parent", parent,
|
||||
gtk_widget_get_name (widget), widget);
|
||||
}
|
||||
|
||||
if (parent &&
|
||||
@@ -6999,8 +6812,8 @@ gtk_widget_verify_invariants (GtkWidget *widget)
|
||||
|
||||
if (!priv->mapped)
|
||||
g_warning ("%s %p is mapped but visible child %s %p is not mapped",
|
||||
G_OBJECT_TYPE_NAME (parent), parent,
|
||||
G_OBJECT_TYPE_NAME (widget), widget);
|
||||
gtk_widget_get_name (parent), parent,
|
||||
gtk_widget_get_name (widget), widget);
|
||||
}
|
||||
else if (!GTK_IS_ROOT (widget))
|
||||
{
|
||||
@@ -7008,10 +6821,10 @@ gtk_widget_verify_invariants (GtkWidget *widget)
|
||||
|
||||
if (priv->mapped)
|
||||
g_warning ("%s %p is mapped but visible=%d child_visible=%d parent %s %p mapped=%d",
|
||||
G_OBJECT_TYPE_NAME (widget), widget,
|
||||
gtk_widget_get_name (widget), widget,
|
||||
priv->visible,
|
||||
priv->child_visible,
|
||||
parent ? G_OBJECT_TYPE_NAME (parent) : "no parent", parent,
|
||||
parent ? gtk_widget_get_name (parent) : "no parent", parent,
|
||||
parent ? parent->priv->mapped : FALSE);
|
||||
}
|
||||
}
|
||||
@@ -9589,8 +9402,6 @@ gtk_widget_set_vexpand_set (GtkWidget *widget,
|
||||
/*
|
||||
* GtkBuildable implementation
|
||||
*/
|
||||
static GQuark quark_builder_has_default = 0;
|
||||
static GQuark quark_builder_has_focus = 0;
|
||||
static GQuark quark_builder_atk_relations = 0;
|
||||
static GQuark quark_builder_set_name = 0;
|
||||
|
||||
@@ -9622,15 +9433,12 @@ gtk_widget_buildable_add_child (GtkBuildable *buildable,
|
||||
static void
|
||||
gtk_widget_buildable_interface_init (GtkBuildableIface *iface)
|
||||
{
|
||||
quark_builder_has_default = g_quark_from_static_string ("gtk-builder-has-default");
|
||||
quark_builder_has_focus = g_quark_from_static_string ("gtk-builder-has-focus");
|
||||
quark_builder_atk_relations = g_quark_from_static_string ("gtk-builder-atk-relations");
|
||||
quark_builder_set_name = g_quark_from_static_string ("gtk-builder-set-name");
|
||||
|
||||
iface->set_name = gtk_widget_buildable_set_name;
|
||||
iface->get_name = gtk_widget_buildable_get_name;
|
||||
iface->get_internal_child = gtk_widget_buildable_get_internal_child;
|
||||
iface->set_buildable_property = gtk_widget_buildable_set_buildable_property;
|
||||
iface->parser_finished = gtk_widget_buildable_parser_finished;
|
||||
iface->custom_tag_start = gtk_widget_buildable_custom_tag_start;
|
||||
iface->custom_tag_end = gtk_widget_buildable_custom_tag_end;
|
||||
@@ -9695,22 +9503,6 @@ gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *name,
|
||||
const GValue *value)
|
||||
{
|
||||
if (strcmp (name, "has-default") == 0 && g_value_get_boolean (value))
|
||||
g_object_set_qdata (G_OBJECT (buildable), quark_builder_has_default,
|
||||
GINT_TO_POINTER (TRUE));
|
||||
else if (strcmp (name, "has-focus") == 0 && g_value_get_boolean (value))
|
||||
g_object_set_qdata (G_OBJECT (buildable), quark_builder_has_focus,
|
||||
GINT_TO_POINTER (TRUE));
|
||||
else
|
||||
g_object_set_property (G_OBJECT (buildable), name, value);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *action_name;
|
||||
@@ -9749,18 +9541,6 @@ gtk_widget_buildable_parser_finished (GtkBuildable *buildable,
|
||||
{
|
||||
GSList *atk_relations;
|
||||
|
||||
if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_default))
|
||||
{
|
||||
gtk_widget_grab_default (GTK_WIDGET (buildable));
|
||||
g_object_steal_qdata (G_OBJECT (buildable), quark_builder_has_default);
|
||||
}
|
||||
|
||||
if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_focus))
|
||||
{
|
||||
gtk_widget_grab_focus (GTK_WIDGET (buildable));
|
||||
g_object_steal_qdata (G_OBJECT (buildable), quark_builder_has_focus);
|
||||
}
|
||||
|
||||
atk_relations = g_object_get_qdata (G_OBJECT (buildable),
|
||||
quark_builder_atk_relations);
|
||||
if (atk_relations)
|
||||
@@ -12900,6 +12680,48 @@ gtk_widget_get_action_group (GtkWidget *widget,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_activate_action:
|
||||
* @widget: a #GtkWidget
|
||||
* @name: a prefixed action name
|
||||
* @parameter: parameters that required by the action
|
||||
*
|
||||
* Looks up the action in the action groups associated
|
||||
* with @widget and its ancestors, and activates it.
|
||||
*
|
||||
* The action name is expected to be prefixed with the
|
||||
* prefix that was used when adding the action group
|
||||
* with gtk_widget_insert_action_group().
|
||||
*
|
||||
* The @parameter must match the actions expected parameter
|
||||
* type, as returned by g_action_get_parameter_type().
|
||||
*/
|
||||
void
|
||||
gtk_widget_activate_action (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, FALSE);
|
||||
if (muxer)
|
||||
g_action_group_activate_action (G_ACTION_GROUP (muxer),
|
||||
name,
|
||||
parameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_activate_default:
|
||||
* @widget: a #GtkWidget
|
||||
*
|
||||
* Activate the default.activate action from @widget.
|
||||
*/
|
||||
void
|
||||
gtk_widget_activate_default (GtkWidget *widget)
|
||||
{
|
||||
gtk_widget_activate_action (widget, "default.activate", NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_cancel_event_sequence (GtkWidget *widget,
|
||||
GtkGesture *gesture,
|
||||
@@ -13164,7 +12986,7 @@ gtk_widget_snapshot (GtkWidget *widget,
|
||||
|
||||
if (_gtk_widget_get_alloc_needed (widget))
|
||||
{
|
||||
g_warning ("Trying to snapshot %s %p without a current allocation", G_OBJECT_TYPE_NAME (widget), widget);
|
||||
g_warning ("Trying to snapshot %s %p without a current allocation", gtk_widget_get_name (widget), widget);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+8
-12
@@ -209,8 +209,6 @@ struct _GtkWidget
|
||||
* context menu.
|
||||
* @get_accessible: Returns the accessible object that describes the
|
||||
* widget to an assistive technology.
|
||||
* @display_changed: Signal emitted when the #GdkDisplay of a widget has
|
||||
* changed.
|
||||
* @can_activate_accel: Signal allows applications and derived widgets
|
||||
* to override the default GtkWidget handling for determining whether
|
||||
* an accelerator can be activated.
|
||||
@@ -314,8 +312,6 @@ struct _GtkWidgetClass
|
||||
*/
|
||||
AtkObject * (* get_accessible) (GtkWidget *widget);
|
||||
|
||||
void (* display_changed) (GtkWidget *widget,
|
||||
GdkDisplay *previous_display);
|
||||
gboolean (* can_activate_accel) (GtkWidget *widget,
|
||||
guint signal_id);
|
||||
|
||||
@@ -474,16 +470,8 @@ void gtk_widget_set_can_target (GtkWidget *widget,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_get_can_target (GtkWidget *widget);
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_set_can_default (GtkWidget *widget,
|
||||
gboolean can_default);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_get_can_default (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_has_default (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_grab_default (GtkWidget *widget);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_set_receives_default (GtkWidget *widget,
|
||||
@@ -1011,6 +999,14 @@ GActionGroup *gtk_widget_get_action_group (GtkWidget *
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const gchar ** gtk_widget_list_action_prefixes (GtkWidget *widget);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_activate_action (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_activate_default (GtkWidget *widget);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_set_font_map (GtkWidget *widget,
|
||||
PangoFontMap *font_map);
|
||||
|
||||
@@ -81,7 +81,6 @@ struct _GtkWidgetPrivate
|
||||
guint can_focus : 1;
|
||||
guint has_focus : 1;
|
||||
guint focus_on_click : 1;
|
||||
guint can_default : 1;
|
||||
guint has_default : 1;
|
||||
guint receives_default : 1;
|
||||
guint has_grab : 1;
|
||||
@@ -210,6 +209,8 @@ struct _GtkWidgetPrivate
|
||||
GdkCursor *cursor;
|
||||
};
|
||||
|
||||
void gtk_widget_root (GtkWidget *widget);
|
||||
void gtk_widget_unroot (GtkWidget *widget);
|
||||
GtkCssNode * gtk_widget_get_css_node (GtkWidget *widget);
|
||||
void _gtk_widget_set_visible_flag (GtkWidget *widget,
|
||||
gboolean visible);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user