Compare commits

..

25 Commits

Author SHA1 Message Date
Timm Bäder 2b5c49fb58 gl renderer: Add simple blend node implementation 2019-04-28 07:46:17 +02:00
Benjamin Otte c0791ca38e rendernode: Parse and print blend nodes properly 2019-04-28 07:05:08 +02:00
Timm Bäder 8ca1a46272 gl renderer: Move texture labeling below initialization
Apparently genTextures and friends only "reserves names", initializing
them will actually create them. Using glObjectLabel on textures before
initializing them will throw a GL_INVALID_VALUE error.
2019-04-27 10:35:03 +02:00
Timm Bäder 97b688702b gdkglcontext: Limit gl debug label length
There's a maximum length we have to adhere to, otherwise GL throws a
GL_INVALID_VALUE error.
2019-04-27 10:35:01 +02:00
Timm Bäder 31e503aa46 testsuite: Add nodeparser test case
An serialized frame from the widget factory!
2019-04-27 10:35:01 +02:00
Benjamin Otte 5d63bfd285 Add gtk4-node-editor
It's meant to be a little editor for render nodes so we can do testing
with it.
2019-04-27 10:35:01 +02:00
Timm Bäder 78859b9e2a ci: Don't disable the gsk suite 2019-04-27 10:35:01 +02:00
Timm Bäder d4dd43f93d testsuite: Update clipped_rounded_clip test case 2019-04-27 10:35:01 +02:00
Timm Bäder ed51dd58b5 Add error func to node deserialization 2019-04-27 10:35:01 +02:00
Timm Bäder f3742a37db testsuite: Remove another test case
That one's just drawing a 1px outset shadow with rounded corners on top,
which is bound to be slightly different between renderer, hardware
and drivers.
2019-04-27 10:35:01 +02:00
Timm Bäder f1ebc75f58 testsuite: Remove old cairo/vulkan tests
They are still in the old binary format and haven't worked for a while.
2019-04-27 10:35:01 +02:00
Timm Bäder 0ec6abcedb rendernode: Remove old GVariant (de)serialization code
We're doing the CSS thing now.
2019-04-27 10:35:01 +02:00
Timm Bäder cc1cc27037 testsuite: Add another gl renderer test 2019-04-27 10:35:01 +02:00
Timm Bäder b86fd0269e testsuite: Add cross-fade-in-opacity test
Making sure that an opacity node doesn't end up reviving a node that's
hidden because the cross-fade has progress 0 or 1.
2019-04-27 10:35:01 +02:00
Timm Bäder adb6d5f965 testsuite: Remove broken GL comparison tests
These only work on special hardware, which not even I have anymore.
We'll need to redo them in a way that works on different systems.
2019-04-27 10:35:01 +02:00
Timm Bäder 982524c860 testsuite: Print serialized nodes when parsing fails 2019-04-27 10:35:00 +02:00
Timm Bäder b56c102f8e testsuite: add shadow node parser test 2019-04-27 10:35:00 +02:00
Timm Bäder a3daaac009 testsuite: add another nodeparser crash test 2019-04-27 10:35:00 +02:00
Timm Bäder 77ace0a39f testsuite: Add serialize-deserialize tests
Check that we can successfully deserialize a node, then serialize it
again and serialize that result once more.
2019-04-27 10:35:00 +02:00
Timm Bäder 6c9011d181 build: don't use 'continue'
ffs
2019-04-27 10:35:00 +02:00
Benjamin Otte e6865e1c21 testsuite: Add a broken test
This also adds some build magic so all tests that contain "-3d" in them
won't be added to the Cairo renderer.

Of course, this new test is such a test.
2019-04-27 10:35:00 +02:00
Benjamin Otte cc20e07347 Move working tests to new directory
These are tests that are working on both GL and Cairo now.

Some tests got black boxes over the areas that aren't easy to compare.
2019-04-27 10:35:00 +02:00
Timm Bäder e37319193c testsuite: Port gl tests to text-based format 2019-04-27 10:35:00 +02:00
Benjamin Otte 107e462831 testsuite: Add tests for the new node parser
These are just a few crashes I encountered while developing it.
2019-04-27 10:35:00 +02:00
Timm Bäder 76254a18ad Parse render nodes from text files 2019-04-27 10:35:00 +02:00
281 changed files with 9363 additions and 15837 deletions
+16 -23
View File
@@ -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 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
* 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
* 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,13 +70,9 @@ 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. A number of layout managers are available:
- GtkBinLayout
- GtkBoxLayout
- GtkGridLayout
- GtkFixedLayout
- GtkCustomLayout
More layout manager implementations will appear in the future.
properties. GtkBinLayout, GtkBoxLayout, GtkGridLayout, GtkFixedLayout
and GtkCustomLayout are currently available, 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
@@ -86,11 +82,8 @@ 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 or changed to backend APIs.
removed
* GtkBuilder can specify object-valued properties inline.
+3
View File
@@ -24,6 +24,9 @@
/* Define to 1 if you have the <crt_externs.h> header file. */
#mesondefine HAVE_CRT_EXTERNS_H
/* Define to 1 if CUPS 1.6 API is available */
#mesondefine HAVE_CUPS_API_1_6
/* Define to 1 if you have the `dcgettext' function. */
#mesondefine HAVE_DCGETTEXT
-7
View File
@@ -31,7 +31,6 @@ do_expander (GtkWidget *do_widget)
GtkWidget *toplevel;
GtkWidget *area;
GtkWidget *expander;
GtkWidget *label;
GtkWidget *sw;
GtkWidget *tv;
GtkTextBuffer *buffer;
@@ -51,19 +50,13 @@ 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));
+11 -1
View File
@@ -101,41 +101,51 @@ 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_window_set_default_widget (GTK_WINDOW (window), button);
gtk_widget_set_can_default (button, TRUE);
gtk_widget_grab_default (button);
gtk_widget_show (button);
}
if (!gtk_widget_get_visible (window))
+2 -1
View File
@@ -76,7 +76,8 @@ do_password_entry (GtkWidget *do_widget)
gtk_widget_set_sensitive (button, FALSE);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
gtk_window_set_default_widget (GTK_WINDOW (window), button);
gtk_widget_set_can_default (button, TRUE);
gtk_window_set_default (GTK_WINDOW (window), button);
}
if (!gtk_widget_get_visible (window))
+2 -1
View File
@@ -99,7 +99,8 @@ 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_window_set_default_widget (GTK_WINDOW (window), button);
gtk_widget_set_can_default (button, TRUE);
gtk_window_set_default (GTK_WINDOW (window), button);
}
if (!gtk_widget_get_visible (window))
-323
View File
@@ -1,323 +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 "gtkrendererpaintableprivate.h"
#include <gtk/gtk.h>
struct _GtkRendererPaintable
{
GObject parent_instance;
GskRenderer *renderer;
GdkPaintable *paintable;
};
struct _GtkRendererPaintableClass
{
GObjectClass parent_class;
};
enum {
PROP_0,
PROP_PAINTABLE,
PROP_RENDERER,
N_PROPS
};
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gtk_renderer_paintable_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkRendererPaintable *self = GTK_RENDERER_PAINTABLE (paintable);
GtkSnapshot *node_snapshot;
GskRenderNode *node;
GdkTexture *texture;
if (self->paintable == NULL)
return;
if (self->renderer == NULL ||
!gsk_renderer_is_realized (self->renderer))
{
gdk_paintable_snapshot (self->paintable, snapshot, width, height);
return;
}
node_snapshot = gtk_snapshot_new ();
gdk_paintable_snapshot (self->paintable, node_snapshot, width, height);
node = gtk_snapshot_free_to_node (node_snapshot);
if (node == NULL)
return;
texture = gsk_renderer_render_texture (self->renderer,
node,
&GRAPHENE_RECT_INIT (0, 0, width, height));
gdk_paintable_snapshot (GDK_PAINTABLE (texture), snapshot, width, height);
g_object_unref (texture);
}
static int
gtk_renderer_paintable_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkRendererPaintable *self = GTK_RENDERER_PAINTABLE (paintable);
if (self->paintable == NULL)
return 0;
return gdk_paintable_get_intrinsic_width (self->paintable);
}
static int
gtk_renderer_paintable_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkRendererPaintable *self = GTK_RENDERER_PAINTABLE (paintable);
if (self->paintable == NULL)
return 0;
return gdk_paintable_get_intrinsic_height (self->paintable);
}
static double
gtk_renderer_paintable_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
{
GtkRendererPaintable *self = GTK_RENDERER_PAINTABLE (paintable);
if (self->paintable == NULL)
return 0.0;
return gdk_paintable_get_intrinsic_aspect_ratio (self->paintable);
}
static void
gtk_renderer_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gtk_renderer_paintable_paintable_snapshot;
iface->get_intrinsic_width = gtk_renderer_paintable_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_renderer_paintable_paintable_get_intrinsic_height;
iface->get_intrinsic_aspect_ratio = gtk_renderer_paintable_paintable_get_intrinsic_aspect_ratio;
}
G_DEFINE_TYPE_EXTENDED (GtkRendererPaintable, gtk_renderer_paintable, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_renderer_paintable_paintable_init))
static void
gtk_renderer_paintable_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkRendererPaintable *self = GTK_RENDERER_PAINTABLE (object);
switch (prop_id)
{
case PROP_PAINTABLE:
gtk_renderer_paintable_set_paintable (self, g_value_get_object (value));
break;
case PROP_RENDERER:
gtk_renderer_paintable_set_renderer (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_renderer_paintable_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkRendererPaintable *self = GTK_RENDERER_PAINTABLE (object);
switch (prop_id)
{
case PROP_PAINTABLE:
g_value_set_object (value, self->paintable);
break;
case PROP_RENDERER:
g_value_set_object (value, self->renderer);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_renderer_paintable_unset_paintable (GtkRendererPaintable *self)
{
guint flags;
if (self->paintable == NULL)
return;
flags = gdk_paintable_get_flags (self->paintable);
if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
g_signal_handlers_disconnect_by_func (self->paintable,
gdk_paintable_invalidate_contents,
self);
if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
g_signal_handlers_disconnect_by_func (self->paintable,
gdk_paintable_invalidate_size,
self);
g_clear_object (&self->paintable);
}
static void
gtk_renderer_paintable_dispose (GObject *object)
{
GtkRendererPaintable *self = GTK_RENDERER_PAINTABLE (object);
g_clear_object (&self->renderer);
gtk_renderer_paintable_unset_paintable (self);
G_OBJECT_CLASS (gtk_renderer_paintable_parent_class)->dispose (object);
}
static void
gtk_renderer_paintable_class_init (GtkRendererPaintableClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gtk_renderer_paintable_get_property;
gobject_class->set_property = gtk_renderer_paintable_set_property;
gobject_class->dispose = gtk_renderer_paintable_dispose;
properties[PROP_PAINTABLE] =
g_param_spec_object ("paintable",
"Paintable",
"The paintable to be shown",
GDK_TYPE_PAINTABLE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
properties[PROP_RENDERER] =
g_param_spec_object ("renderer",
"Renderer",
"Renderer used to render the paintable",
GSK_TYPE_RENDERER,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gtk_renderer_paintable_init (GtkRendererPaintable *self)
{
}
GdkPaintable *
gtk_renderer_paintable_new (GskRenderer *renderer,
GdkPaintable *paintable)
{
g_return_val_if_fail (renderer == NULL || GSK_IS_RENDERER (renderer), NULL);
g_return_val_if_fail (paintable == NULL || GDK_IS_PAINTABLE (paintable), NULL);
return g_object_new (GTK_TYPE_RENDERER_PAINTABLE,
"renderer", renderer,
"paintable", paintable,
NULL);
}
void
gtk_renderer_paintable_set_renderer (GtkRendererPaintable *self,
GskRenderer *renderer)
{
g_return_if_fail (GTK_IS_RENDERER_PAINTABLE (self));
g_return_if_fail (renderer == NULL || GSK_IS_RENDERER (renderer));
if (!g_set_object (&self->renderer, renderer))
return;
if (self->paintable)
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RENDERER]);
}
GskRenderer *
gtk_renderer_paintable_get_renderer (GtkRendererPaintable *self)
{
g_return_val_if_fail (GTK_IS_RENDERER_PAINTABLE (self), NULL);
return self->renderer;
}
void
gtk_renderer_paintable_set_paintable (GtkRendererPaintable *self,
GdkPaintable *paintable)
{
g_return_if_fail (GTK_IS_RENDERER_PAINTABLE (self));
g_return_if_fail (paintable == NULL || GDK_IS_PAINTABLE (paintable));
if (self->paintable == paintable)
return;
gtk_renderer_paintable_unset_paintable (self);
if (paintable)
{
const guint flags = gdk_paintable_get_flags (paintable);
self->paintable = g_object_ref (paintable);
if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
g_signal_connect_swapped (paintable,
"invalidate-contents",
G_CALLBACK (gdk_paintable_invalidate_contents),
self);
if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
g_signal_connect_swapped (paintable,
"invalidate-size",
G_CALLBACK (gdk_paintable_invalidate_size),
self);
}
gdk_paintable_invalidate_size (GDK_PAINTABLE (self));
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PAINTABLE]);
}
GdkPaintable *
gtk_renderer_paintable_get_paintable (GtkRendererPaintable *self)
{
g_return_val_if_fail (GTK_IS_RENDERER_PAINTABLE (self), NULL);
return self->paintable;
}
@@ -1,43 +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 __GTK_RENDERER_PAINTABLE_H__
#define __GTK_RENDERER_PAINTABLE_H__
#include <gsk/gsk.h>
G_BEGIN_DECLS
#define GTK_TYPE_RENDERER_PAINTABLE (gtk_renderer_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkRendererPaintable, gtk_renderer_paintable, GTK, RENDERER_PAINTABLE, GObject)
GdkPaintable * gtk_renderer_paintable_new (GskRenderer *renderer,
GdkPaintable *paintable);
void gtk_renderer_paintable_set_renderer (GtkRendererPaintable *self,
GskRenderer *renderer);
GskRenderer * gtk_renderer_paintable_get_renderer (GtkRendererPaintable *self) G_GNUC_PURE;
void gtk_renderer_paintable_set_paintable (GtkRendererPaintable *self,
GdkPaintable *paintable);
GdkPaintable * gtk_renderer_paintable_get_paintable (GtkRendererPaintable *self) G_GNUC_PURE;
G_END_DECLS
#endif /* __GTK_RENDERER_PAINTABLE_H__ */
-1
View File
@@ -1,5 +1,4 @@
node_editor_sources = [
'gtkrendererpaintable.c',
'main.c',
'node-editor-application.c',
'node-editor-window.c',
+4 -22
View File
@@ -23,16 +23,6 @@
#include "node-editor-window.h"
static const char *css =
"textview.editor {"
" color: rgb(192, 197, 206);"
" caret-color: white;"
"}"
"textview.editor text {"
" background-color: rgb(43, 48, 59);"
"}"
;
struct _NodeEditorApplication
{
GtkApplication parent;
@@ -66,24 +56,16 @@ static GActionEntry app_entries[] =
static void
node_editor_application_startup (GApplication *app)
{
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
const char *open_accels[2] = { "<Ctrl>O", NULL };
GtkCssProvider *provider;
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);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, css, -1);
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
}
static void
+6 -276
View File
@@ -21,8 +21,6 @@
#include "node-editor-window.h"
#include "gtkrendererpaintableprivate.h"
#include "gsk/gskrendernodeparserprivate.h"
typedef struct
@@ -39,11 +37,6 @@ struct _NodeEditorWindow
GtkWidget *picture;
GtkWidget *text_view;
GtkTextBuffer *text_buffer;
GtkTextTagTable *tag_table;
GtkWidget *renderer_listbox;
GListStore *renderers;
GdkPaintable *paintable;
GArray *errors;
};
@@ -100,42 +93,6 @@ deserialize_error_func (const GtkCssSection *section,
g_array_append_val (self->errors, text_view_error);
}
static void
text_iter_skip_alpha_backward (GtkTextIter *iter)
{
/* Just skip to the previous non-whitespace char */
while (!gtk_text_iter_is_start (iter))
{
gunichar c = gtk_text_iter_get_char (iter);
if (g_unichar_isspace (c))
{
gtk_text_iter_forward_char (iter);
break;
}
gtk_text_iter_backward_char (iter);
}
}
static void
text_iter_skip_whitespace_backward (GtkTextIter *iter)
{
while (!gtk_text_iter_is_start (iter))
{
gunichar c = gtk_text_iter_get_char (iter);
if (g_unichar_isalpha (c))
{
gtk_text_iter_forward_char (iter);
break;
}
gtk_text_iter_backward_char (iter);
}
}
static void
text_changed (GtkTextBuffer *buffer,
NodeEditorWindow *self)
@@ -157,7 +114,6 @@ text_changed (GtkTextBuffer *buffer,
GtkSnapshot *snapshot;
GdkPaintable *paintable;
graphene_rect_t bounds;
guint i;
snapshot = gtk_snapshot_new ();
gsk_render_node_get_bounds (node, &bounds);
@@ -166,83 +122,12 @@ text_changed (GtkTextBuffer *buffer,
gsk_render_node_unref (node);
paintable = gtk_snapshot_free_to_paintable (snapshot, &bounds.size);
gtk_picture_set_paintable (GTK_PICTURE (self->picture), paintable);
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->renderers)); i++)
{
gpointer item = g_list_model_get_item (G_LIST_MODEL (self->renderers), i);
gtk_renderer_paintable_set_paintable (item, paintable);
g_object_unref (item);
}
g_clear_object (&paintable);
}
else
{
gtk_picture_set_paintable (GTK_PICTURE (self->picture), NULL);
}
GtkTextIter iter;
gtk_text_buffer_get_start_iter (self->text_buffer, &iter);
while (!gtk_text_iter_is_end (&iter))
{
gunichar c = gtk_text_iter_get_char (&iter);
if (c == '{')
{
GtkTextIter word_end = iter;
GtkTextIter word_start;
gtk_text_iter_backward_char (&word_end);
text_iter_skip_whitespace_backward (&word_end);
word_start = word_end;
gtk_text_iter_backward_word_start (&word_start);
text_iter_skip_alpha_backward (&word_start);
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "nodename",
&word_start, &word_end);
}
else if (c == ':')
{
GtkTextIter word_end = iter;
GtkTextIter word_start;
gtk_text_iter_backward_char (&word_end);
text_iter_skip_whitespace_backward (&word_end);
word_start = word_end;
gtk_text_iter_backward_word_start (&word_start);
text_iter_skip_alpha_backward (&word_start);
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "propname",
&word_start, &word_end);
}
else if (c == '"')
{
GtkTextIter string_start = iter;
GtkTextIter string_end = iter;
gtk_text_iter_forward_char (&iter);
while (!gtk_text_iter_is_end (&iter))
{
c = gtk_text_iter_get_char (&iter);
if (c == '"')
{
gtk_text_iter_forward_char (&iter);
string_end = iter;
break;
}
gtk_text_iter_forward_char (&iter);
}
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "string",
&string_start, &string_end);
}
gtk_text_iter_forward_char (&iter);
}
}
static gboolean
@@ -313,8 +198,6 @@ node_editor_window_load (NodeEditorWindow *self,
g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes));
g_bytes_unref (bytes);
return TRUE;
}
@@ -338,12 +221,13 @@ open_response_cb (GtkWidget *dialog,
}
static void
show_open_filechooser (NodeEditorWindow *self)
open_cb (GtkWidget *button,
NodeEditorWindow *self)
{
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("Open node file",
GTK_WINDOW (self),
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
GTK_FILE_CHOOSER_ACTION_OPEN,
"_Cancel", GTK_RESPONSE_CANCEL,
"_Load", GTK_RESPONSE_ACCEPT,
@@ -356,13 +240,6 @@ show_open_filechooser (NodeEditorWindow *self)
gtk_widget_show (dialog);
}
static void
open_cb (GtkWidget *button,
NodeEditorWindow *self)
{
show_open_filechooser (self);
}
static void
save_response_cb (GtkWidget *dialog,
gint response,
@@ -511,76 +388,9 @@ node_editor_window_finalize (GObject *object)
g_array_free (self->errors, TRUE);
g_clear_object (&self->renderers);
G_OBJECT_CLASS (node_editor_window_parent_class)->finalize (object);
}
static void
node_editor_window_add_renderer (NodeEditorWindow *self,
GskRenderer *renderer,
const char *description)
{
GdkSurface *surface;
GdkPaintable *paintable;
surface = gtk_widget_get_surface (GTK_WIDGET (self));
g_assert (surface != NULL);
if (renderer != NULL && !gsk_renderer_realize (renderer, surface, NULL))
{
g_object_unref (renderer);
return;
}
paintable = gtk_renderer_paintable_new (renderer, gtk_picture_get_paintable (GTK_PICTURE (self->picture)));
g_object_set_data_full (G_OBJECT (paintable), "description", g_strdup (description), g_free);
g_clear_object (&renderer);
g_list_store_append (self->renderers, paintable);
g_object_unref (paintable);
}
static void
node_editor_window_realize (GtkWidget *widget)
{
NodeEditorWindow *self = NODE_EDITOR_WINDOW (widget);
GTK_WIDGET_CLASS (node_editor_window_parent_class)->realize (widget);
#if 0
node_editor_window_add_renderer (self,
NULL,
"Default");
#endif
node_editor_window_add_renderer (self,
gsk_gl_renderer_new (),
"OpenGL");
#ifdef GDK_RENDERING_VULKAN
node_editor_window_add_renderer (self,
gsk_vulkan_renderer_new (),
"Vulkan");
#endif
#ifdef GDK_WINDOWING_BROADWAY
node_editor_window_add_renderer (self,
gsk_broadway_renderer_new (),
"Broadway");
#endif
node_editor_window_add_renderer (self,
gsk_cairo_renderer_new (),
"Cairo");
}
static void
node_editor_window_unrealize (GtkWidget *widget)
{
NodeEditorWindow *self = NODE_EDITOR_WINDOW (widget);
g_list_store_remove_all (self->renderers);
GTK_WIDGET_CLASS (node_editor_window_parent_class)->unrealize (widget);
}
static void
node_editor_window_class_init (NodeEditorWindowClass *class)
{
@@ -589,107 +399,27 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
object_class->finalize = node_editor_window_finalize;
gtk_widget_class_set_template_from_resource (widget_class,
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/gtk4/node-editor/node-editor-window.ui");
widget_class->realize = node_editor_window_realize;
widget_class->unrealize = node_editor_window_unrealize;
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_child (widget_class, NodeEditorWindow, renderer_listbox);
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 GtkWidget *
node_editor_window_create_renderer_widget (gpointer item,
gpointer user_data)
{
GdkPaintable *paintable = item;
GtkWidget *box, *label, *picture;
GtkWidget *row;
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_size_request (box, 120, 90);
label = gtk_label_new (g_object_get_data (G_OBJECT (paintable), "description"));
gtk_container_add (GTK_CONTAINER (box), label);
picture = gtk_picture_new_for_paintable (paintable);
gtk_container_add (GTK_CONTAINER (box), picture);
row = gtk_list_box_row_new ();
gtk_container_add (GTK_CONTAINER (row), box);
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
return row;
}
static void
window_open (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
NodeEditorWindow *self = user_data;
show_open_filechooser (self);
}
static GActionEntry win_entries[] = {
{ "open", window_open, NULL, NULL, NULL },
};
static void
node_editor_window_init (NodeEditorWindow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->renderers = g_list_store_new (GDK_TYPE_PAINTABLE);
gtk_list_box_bind_model (GTK_LIST_BOX (self->renderer_listbox),
G_LIST_MODEL (self->renderers),
node_editor_window_create_renderer_widget,
self,
NULL);
self->errors = g_array_new (FALSE, TRUE, sizeof (TextViewError));
g_array_set_clear_func (self->errors, (GDestroyNotify)text_view_error_free);
g_action_map_add_action_entries (G_ACTION_MAP (self), win_entries, G_N_ELEMENTS (win_entries), self);
self->tag_table = gtk_text_tag_table_new ();
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,
"name", "error",
"underline", PANGO_UNDERLINE_ERROR,
NULL));
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,
"name", "nodename",
"foreground-rgba", &(GdkRGBA) { 0.9, 0.78, 0.53, 1},
NULL));
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,
"name", "propname",
"foreground-rgba", &(GdkRGBA) { 0.7, 0.55, 0.67, 1},
NULL));
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,
"name", "string",
"foreground-rgba", &(GdkRGBA) { 0.63, 0.73, 0.54, 1},
NULL));
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,
"name", "number",
"foreground-rgba", &(GdkRGBA) { 0.8, 0.52, 0.43, 1},
NULL));
self->text_buffer = gtk_text_buffer_new (self->tag_table);
g_signal_connect (self->text_buffer, "changed", G_CALLBACK (text_changed), self);
gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->text_view), self->text_buffer);
}
NodeEditorWindow *
+22 -26
View File
@@ -1,5 +1,17 @@
<?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"/>
@@ -49,6 +61,7 @@
<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>
@@ -58,39 +71,22 @@
<property name="bottom-margin">6</property>
<property name="has-tooltip">1</property>
<signal name="query-tooltip" handler="text_view_query_tooltip_cb"/>
<style>
<class name="editor" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<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="GtkScrolledWindow">
<property name="expand">1</property>
<property name="min-content-height">100</property>
<property name="min-content-width">100</property>
<object class="GtkViewport">
<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>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkListBox" id="renderer_listbox">
<property name="selection-mode">none</property>
<object class="GtkPicture" id="picture">
<property name="can-shrink">0</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
</object>
+9 -85
View File
@@ -2880,17 +2880,6 @@ 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>
@@ -3154,7 +3143,6 @@ 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>
@@ -3176,6 +3164,8 @@ 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>
@@ -3313,7 +3303,6 @@ 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>
@@ -3335,6 +3324,8 @@ 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>
@@ -3395,7 +3386,6 @@ 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>
@@ -3408,52 +3398,22 @@ 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">fill</property>
<property name="halign">end</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">2</property>
<property name="top-attach">3</property>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
@@ -3479,9 +3439,8 @@ bad things might happen.</property>
</widgets>
</object>
<object class="GtkPopover" id="notebook_info_popover">
<property name="modal">0</property>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="notebook_info_label">
<property name="label">No updates at this time</property>
<accessibility>
<role type="static"/>
@@ -3489,39 +3448,4 @@ 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>
+1 -1
View File
@@ -231,7 +231,6 @@ 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
@@ -989,6 +988,7 @@ 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
+1 -10
View File
@@ -1,17 +1,12 @@
<SECTION>
<FILE>GskRenderer</FILE>
gsk_renderer_new_for_surface
gsk_renderer_get_surface
gsk_renderer_realize
gsk_renderer_unrealize
gsk_renderer_is_realized
gsk_renderer_render
gsk_renderer_render_texture
<SUBSECTION>
gsk_renderer_new_for_surface
gsk_gl_renderer_new
gsk_cairo_renderer_new
gsk_vulkan_renderer_new
gsk_broadway_renderer_new
<SUBSECTION Standard>
GSK_IS_RENDERER
GSK_RENDERER
@@ -67,7 +62,6 @@ 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
@@ -94,7 +88,6 @@ 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
@@ -110,7 +103,6 @@ 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
@@ -170,7 +162,6 @@ 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
-373
View File
@@ -1,373 +0,0 @@
<?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>
+1 -1
View File
@@ -12,7 +12,7 @@
<refnamediv>
<refname>The GTK Drawing Model</refname>
<refpurpose>
How widgets draw
The GTK drawing model in detail
</refpurpose>
</refnamediv>
+1 -2
View File
@@ -24,9 +24,8 @@
<xi:include href="xml/getting_started.xml"/>
<xi:include href="resources.sgml" />
<xi:include href="xml/question_index.sgml" />
<xi:include href="xml/drawing-model.xml" />
<xi:include href="drawing-model.xml" />
<xi:include href="xml/input-handling.xml" />
<xi:include href="xml/actions.xml" />
</part>
<part id="gtkobjects">
+8 -4
View File
@@ -1779,6 +1779,7 @@ 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
@@ -4432,6 +4433,7 @@ 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
@@ -4502,6 +4504,8 @@ 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
@@ -4534,15 +4538,13 @@ 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
@@ -4645,6 +4647,8 @@ 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
@@ -4667,7 +4671,7 @@ gtk_window_propagate_key_event
gtk_window_get_focus
gtk_window_set_focus
gtk_window_get_default_widget
gtk_window_set_default_widget
gtk_window_set_default
gtk_window_present
gtk_window_present_with_time
gtk_window_close
+123 -133
View File
@@ -4,15 +4,15 @@
]>
<refentry id="chap-input-handling">
<refmeta>
<refentrytitle>The GTK Input Model</refentrytitle>
<refentrytitle>The GTK Input and Event Handling Model</refentrytitle>
<manvolnum>3</manvolnum>
<refmiscinfo>GTK Library</refmiscinfo>
</refmeta>
<refnamediv>
<refname>The GTK Input Model</refname>
<refname>The GTK Input and Event Handling Model</refname>
<refpurpose>
input and event handling in detail
GTK input and event handling in detail
</refpurpose>
</refnamediv>
@@ -52,12 +52,13 @@
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 surface - for pointer events,
the surface under the pointer (grabs complicate this), for keyboard events,
the surface with the keyboard focus.
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.
</para>
<para>
GDK translates these raw windowing system events into #GdkEvents.
@@ -80,10 +81,9 @@
</simplelist>
</para>
<para>
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.
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).
</para>
</refsect2>
@@ -91,8 +91,8 @@
<title>Event propagation</title>
<para>
The function which initially receives input events on the GTK
side is gtk_main_do_event(). See its documentation
For widgets which have a #GdkSurface set, events are received from the
windowing system and passed to 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,55 +120,62 @@
<para>
An event is propagated to a widget using gtk_propagate_event().
Propagation goes down and up the widget hierarchy in three phases
(see #GtkPropagationPhase) towards a target widget.
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).
</para>
<para>
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()).
For key events, the top-level windows 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 windows current focus widget (gtk_window_get_focus()) to the
top-level.
</para>
<para>
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
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
#GtkWindow or grab widget) down to the target #GtkWidget.
<link linkend="event-controllers-and-gestures">Event
controllers</link> that are attached with %GTK_PHASE_CAPTURE
get a chance to react to the event.
<link linkend="event-controllers-and-gestures">Gestures</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 event controllers 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 gestures attached to it with
%GTK_PHASE_TARGET. This is known as the “target” phase, and only
happens on that widget.
</para>
<para>
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.
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.
</para>
<para>
Events are not delivered to a widget which is insensitive or
unmapped.
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.
</para>
<para>
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.
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.
</para>
</refsect2>
@@ -176,10 +183,27 @@
<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.
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.
</para>
</refsect2>
@@ -187,66 +211,43 @@
<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>
<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>
<!-- focus, tab, directional navigation -->
<!-- mnemonics, accelerators, bindings -->
</refsect2>
@@ -254,43 +255,37 @@
<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 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.
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.
</para>
<para>
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
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
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
recognition 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 gesture 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>
@@ -299,39 +294,34 @@
<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>
-2
View File
@@ -333,7 +333,6 @@ images = [
]
content_files = [
'actions.xml',
'broadway.xml',
'building.sgml',
'compiling.sgml',
@@ -369,7 +368,6 @@ content_files = [
]
expand_content_files = [
'actions.xml',
'compiling.sgml',
'drawing-model.xml',
'glossary.xml',
+27 -108
View File
@@ -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 number of adjustments that you may have to do
that, there's a small 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 using
to help you port your application to GTK 4. If you are still 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
<literal>gdk_window_set_visual (gdk_screen_get_rgba_visual ())</literal>
after creating your window.
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.
</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>
GTK 4 removes these #GtkBox child properties, so you should not use them.
GTK4 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,30 +172,35 @@
<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 application ID</title>
<title>Set a proper app_id</title>
<para>
In GTK 4 we want the application's #GApplication
In GTK4 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 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.
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.
</para>
<para>
The call to g_set_prgname() can be removed once you fully migrated
to GTK 4.
to GTK4.
</para>
</section>
<section>
<title>Stop using GtkBox's pack-type child property</title>
<para>
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.
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.
</para>
</section>
@@ -211,17 +216,6 @@
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>
@@ -307,9 +301,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
@@ -401,10 +395,6 @@
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>
@@ -421,7 +411,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, GTK 4 uses
family of functions. To simplify widget implementations, GTK4 uses
only one virtual function, GtkWidgetClass::measure() that widgets
have to implement.
</para>
@@ -650,7 +640,7 @@
</section>
<section>
<title>Adapt to changes in the API of GtkEntry, GtkSearchEntry and GtkSpinButton</title>
<title>Adapt to changes in the API of GtkEntry, GtkSearchEntry adn 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,
@@ -685,77 +675,6 @@
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>
+2 -20
View File
@@ -79,30 +79,12 @@ 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 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.
windowing systems. GDK provides window system facilities on X11, Windows,
and OS X.
</para></listitem>
</varlistentry>
-26
View File
@@ -574,32 +574,6 @@ nevertheless.
</refsect2>
<refsect2 id="profiling">
<title>Profiling</title>
<para>
GTK supports profiling with sysprof. It exports timing information
about frameclock phases and various characteristics of GskRenders
in a format that can be displayed by sysprof or GNOME Builder.
</para>
<para>
A simple way to capture data is to set the <envar>GTK_TRACE</envar>
environment variable. When it is set, GTK will write profiling
data to a file called
<filename>gtk.<replaceable>PID</replaceable>.syscap</filename>.
</para>
<para>
When launching the application from sysprof, it will set the
<envar>SYSPROF_TRACE_FD</envar> environment variable to point
GTK at a file descriptor to write profiling data to.
</para>
<para>
When GtkApplication registers with D-Bus, it exports the
<literal>org.gnome.Sysprof2.Profiler</literal> interface
that lets sysprof request profiling data at runtime.
</para>
</refsect2>
</refsect1>
</refentry>
+3 -1
View File
@@ -24,7 +24,9 @@ gdk_broadway_public_headers = [
'gdkbroadwaymonitor.h',
]
install_headers(gdk_broadway_public_headers, 'gdkbroadway.h', subdir: 'gtk-4.0/gdk/broadway/')
# Broadway backend headers aren't installed it seems
#install_headers(gdk_broadway_public_headers, subdir: 'gtk-4.0/gdk/broadway/')
#install_headers('gdkbroadway.h', subdir: 'gtk-4.0/gdk/')
gdk_broadway_deps = [shmlib]
-224
View File
@@ -1,224 +0,0 @@
/* sp-capture-types.h
*
* Copyright © 2016 Christian Hergert <chergert@redhat.com>
*
* This file 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 of the License, or (at your option)
* any later version.
*
* This file 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 General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SP_CAPTURE_FORMAT_H
#define SP_CAPTURE_FORMAT_H
#include <glib.h>
#ifndef SP_DISABLE_GOBJECT
# include <glib-object.h>
#endif
#include "sp-clock.h"
G_BEGIN_DECLS
#define SP_CAPTURE_MAGIC (GUINT32_TO_LE(0xFDCA975E))
#define SP_CAPTURE_ALIGN (sizeof(SpCaptureAddress))
#if __WORDSIZE == 64
# define SP_CAPTURE_JITMAP_MARK G_GUINT64_CONSTANT(0xE000000000000000)
# define SP_CAPTURE_ADDRESS_FORMAT "0x%016lx"
#else
# define SP_CAPTURE_JITMAP_MARK G_GUINT64_CONSTANT(0xE0000000)
# define SP_CAPTURE_ADDRESS_FORMAT "0x%016llx"
#endif
#define SP_CAPTURE_CURRENT_TIME (sp_clock_get_current_time())
#define SP_CAPTURE_COUNTER_INT64 0
#define SP_CAPTURE_COUNTER_DOUBLE 1
typedef struct _SpCaptureReader SpCaptureReader;
typedef struct _SpCaptureWriter SpCaptureWriter;
typedef struct _SpCaptureCursor SpCaptureCursor;
typedef struct _SpCaptureCondition SpCaptureCondition;
typedef guint64 SpCaptureAddress;
typedef union
{
gint64 v64;
gdouble vdbl;
} SpCaptureCounterValue;
typedef enum
{
SP_CAPTURE_FRAME_TIMESTAMP = 1,
SP_CAPTURE_FRAME_SAMPLE = 2,
SP_CAPTURE_FRAME_MAP = 3,
SP_CAPTURE_FRAME_PROCESS = 4,
SP_CAPTURE_FRAME_FORK = 5,
SP_CAPTURE_FRAME_EXIT = 6,
SP_CAPTURE_FRAME_JITMAP = 7,
SP_CAPTURE_FRAME_CTRDEF = 8,
SP_CAPTURE_FRAME_CTRSET = 9,
SP_CAPTURE_FRAME_MARK = 10,
} SpCaptureFrameType;
#pragma pack(push, 1)
typedef struct
{
guint32 magic;
guint8 version;
guint32 little_endian : 1;
guint32 padding : 23;
gchar capture_time[64];
gint64 time;
gint64 end_time;
gchar suffix[168];
} SpCaptureFileHeader;
typedef struct
{
guint16 len;
gint16 cpu;
gint32 pid;
gint64 time;
guint8 type;
guint64 padding : 56;
guint8 data[0];
} SpCaptureFrame;
typedef struct
{
SpCaptureFrame frame;
guint64 start;
guint64 end;
guint64 offset;
guint64 inode;
gchar filename[0];
} SpCaptureMap;
typedef struct
{
SpCaptureFrame frame;
guint32 n_jitmaps;
guint8 data[0];
} SpCaptureJitmap;
typedef struct
{
SpCaptureFrame frame;
gchar cmdline[0];
} SpCaptureProcess;
typedef struct
{
SpCaptureFrame frame;
guint16 n_addrs;
guint64 padding : 48;
SpCaptureAddress addrs[0];
} SpCaptureSample;
typedef struct
{
SpCaptureFrame frame;
GPid child_pid;
} SpCaptureFork;
typedef struct
{
SpCaptureFrame frame;
} SpCaptureExit;
typedef struct
{
SpCaptureFrame frame;
} SpCaptureTimestamp;
typedef struct
{
gchar category[32];
gchar name[32];
gchar description[52];
guint32 id : 24;
guint8 type;
SpCaptureCounterValue value;
} SpCaptureCounter;
typedef struct
{
SpCaptureFrame frame;
guint16 n_counters;
guint64 padding : 48;
SpCaptureCounter counters[0];
} SpCaptureFrameCounterDefine;
typedef struct
{
/*
* 96 bytes might seem a bit odd, but the counter frame header is 32
* bytes. So this makes a nice 2-cacheline aligned size which is
* useful when the number of counters is rather small.
*/
guint32 ids[8];
SpCaptureCounterValue values[8];
} SpCaptureCounterValues;
typedef struct
{
SpCaptureFrame frame;
guint16 n_values;
guint64 padding : 48;
SpCaptureCounterValues values[0];
} SpCaptureFrameCounterSet;
typedef struct
{
SpCaptureFrame frame;
gint64 duration;
gchar group[24];
gchar name[40];
gchar message[0];
} SpCaptureMark;
#pragma pack(pop)
G_STATIC_ASSERT (sizeof (SpCaptureFileHeader) == 256);
G_STATIC_ASSERT (sizeof (SpCaptureFrame) == 24);
G_STATIC_ASSERT (sizeof (SpCaptureMap) == 56);
G_STATIC_ASSERT (sizeof (SpCaptureJitmap) == 28);
G_STATIC_ASSERT (sizeof (SpCaptureProcess) == 24);
G_STATIC_ASSERT (sizeof (SpCaptureSample) == 32);
G_STATIC_ASSERT (sizeof (SpCaptureFork) == 28);
G_STATIC_ASSERT (sizeof (SpCaptureExit) == 24);
G_STATIC_ASSERT (sizeof (SpCaptureTimestamp) == 24);
G_STATIC_ASSERT (sizeof (SpCaptureCounter) == 128);
G_STATIC_ASSERT (sizeof (SpCaptureCounterValues) == 96);
G_STATIC_ASSERT (sizeof (SpCaptureFrameCounterDefine) == 32);
G_STATIC_ASSERT (sizeof (SpCaptureFrameCounterSet) == 32);
G_STATIC_ASSERT (sizeof (SpCaptureMark) == 96);
static inline gint
sp_capture_address_compare (SpCaptureAddress a,
SpCaptureAddress b)
{
if (a < b)
return -1;
if (a > b)
return 1;
else
return 0;
}
G_END_DECLS
#endif /* SP_CAPTURE_FORMAT_H */
File diff suppressed because it is too large Load Diff
-132
View File
@@ -1,132 +0,0 @@
/* sp-capture-writer.h
*
* Copyright © 2016 Christian Hergert <chergert@redhat.com>
*
* This file 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 of the License, or (at your option)
* any later version.
*
* This file 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 General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SP_CAPTURE_WRITER_H
#define SP_CAPTURE_WRITER_H
#include "capture/sp-capture-types.h"
G_BEGIN_DECLS
typedef struct _SpCaptureWriter SpCaptureWriter;
typedef struct
{
/*
* The number of frames indexed by SpCaptureFrameType
*/
gsize frame_count[16];
/*
* Padding for future expansion.
*/
gsize padding[48];
} SpCaptureStat;
SpCaptureWriter *sp_capture_writer_new (const gchar *filename,
gsize buffer_size);
SpCaptureWriter *sp_capture_writer_new_from_fd (int fd,
gsize buffer_size);
SpCaptureWriter *sp_capture_writer_ref (SpCaptureWriter *self);
void sp_capture_writer_unref (SpCaptureWriter *self);
void sp_capture_writer_stat (SpCaptureWriter *self,
SpCaptureStat *stat);
gboolean sp_capture_writer_add_map (SpCaptureWriter *self,
gint64 time,
gint cpu,
GPid pid,
guint64 start,
guint64 end,
guint64 offset,
guint64 inode,
const gchar *filename);
gboolean sp_capture_writer_add_mark (SpCaptureWriter *self,
gint64 time,
gint cpu,
GPid pid,
guint64 duration,
const gchar *group,
const gchar *name,
const gchar *message);
guint64 sp_capture_writer_add_jitmap (SpCaptureWriter *self,
const gchar *name);
gboolean sp_capture_writer_add_process (SpCaptureWriter *self,
gint64 time,
gint cpu,
GPid pid,
const gchar *cmdline);
gboolean sp_capture_writer_add_sample (SpCaptureWriter *self,
gint64 time,
gint cpu,
GPid pid,
const SpCaptureAddress *addrs,
guint n_addrs);
gboolean sp_capture_writer_add_fork (SpCaptureWriter *self,
gint64 time,
gint cpu,
GPid pid,
GPid child_pid);
gboolean sp_capture_writer_add_exit (SpCaptureWriter *self,
gint64 time,
gint cpu,
GPid pid);
gboolean sp_capture_writer_add_timestamp (SpCaptureWriter *self,
gint64 time,
gint cpu,
GPid pid);
gboolean sp_capture_writer_define_counters (SpCaptureWriter *self,
gint64 time,
gint cpu,
GPid pid,
const SpCaptureCounter *counters,
guint n_counters);
gboolean sp_capture_writer_set_counters (SpCaptureWriter *self,
gint64 time,
gint cpu,
GPid pid,
const guint *counters_ids,
const SpCaptureCounterValue *values,
guint n_counters);
gboolean sp_capture_writer_flush (SpCaptureWriter *self);
gboolean sp_capture_writer_save_as (SpCaptureWriter *self,
const gchar *filename,
GError **error);
gint sp_capture_writer_request_counter (SpCaptureWriter *self,
guint n_counters);
SpCaptureReader *sp_capture_writer_create_reader (SpCaptureWriter *self,
GError **error);
gboolean sp_capture_writer_splice (SpCaptureWriter *self,
SpCaptureWriter *dest,
GError **error);
gboolean _sp_capture_writer_splice_from_fd (SpCaptureWriter *self,
int fd,
GError **error) G_GNUC_INTERNAL;
#ifndef SP_DISABLE_GOBJECT
# define SP_TYPE_CAPTURE_WRITER (sp_capture_writer_get_type())
GType sp_capture_writer_get_type (void);
#endif
#if GLIB_CHECK_VERSION(2, 44, 0)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SpCaptureWriter, sp_capture_writer_unref)
#endif
G_END_DECLS
#endif /* SP_CAPTURE_WRITER_H */
-52
View File
@@ -1,52 +0,0 @@
/* sp-clock.c
*
* Copyright © 2016 Christian Hergert <chergert@redhat.com>
*
* This file 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 of the License, or (at your option)
* any later version.
*
* This file 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 General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sp-clock.h"
gint sp_clock = -1;
void
sp_clock_init (void)
{
static const gint clock_ids[] = {
CLOCK_MONOTONIC_RAW,
CLOCK_MONOTONIC_COARSE,
CLOCK_MONOTONIC,
CLOCK_REALTIME_COARSE,
CLOCK_REALTIME,
};
guint i;
if (sp_clock != -1)
return;
for (i = 0; i < G_N_ELEMENTS (clock_ids); i++)
{
struct timespec ts;
int clock_id = clock_ids [i];
if (0 == clock_gettime (clock_id, &ts))
{
sp_clock = clock_id;
return;
}
}
g_assert_not_reached ();
}
-55
View File
@@ -1,55 +0,0 @@
/* sp-clock.h
*
* Copyright © 2016 Christian Hergert <chergert@redhat.com>
*
* This file 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 of the License, or (at your option)
* any later version.
*
* This file 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 General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SP_CLOCK_H
#define SP_CLOCK_H
#include <glib.h>
#include <time.h>
G_BEGIN_DECLS
typedef gint SpClock;
typedef gint64 SpTimeStamp;
typedef gint32 SpTimeSpan;
extern SpClock sp_clock;
static inline SpTimeStamp
sp_clock_get_current_time (void)
{
struct timespec ts;
clock_gettime (sp_clock, &ts);
return (ts.tv_sec * G_GINT64_CONSTANT (1000000000)) + ts.tv_nsec;
}
static inline SpTimeSpan
sp_clock_get_relative_time (SpTimeStamp epoch)
{
return sp_clock_get_current_time () - epoch;
}
void sp_clock_init (void);
G_END_DECLS
#endif /* SP_CLOCK_H */
-6
View File
@@ -26,7 +26,6 @@
#include "gdkversionmacros.h"
#include "gdkprofilerprivate.h"
#include "gdkinternals.h"
#include "gdkintl.h"
@@ -212,11 +211,6 @@ gdk_pre_parse (void)
_gdk_debug_flags = g_parse_debug_string (debug_string,
(GDebugKey *) gdk_debug_keys,
G_N_ELEMENTS (gdk_debug_keys));
if (g_getenv ("SYSPROF_TRACE_FD"))
gdk_profiler_start (atoi (g_getenv ("SYSPROF_TRACE_FD")));
else if (g_getenv ("GTK_TRACE"))
gdk_profiler_start (-1);
}
#endif /* G_ENABLE_DEBUG */
+5 -38
View File
@@ -146,47 +146,14 @@ gdk_event_class_init (GdkEventClass *klass)
g_object_class_install_properties (object_class, N_PROPS, event_props);
}
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 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_event_get_event_type (event) == GDK_NOTHING)
{
g_warning ("Ignoring GDK_NOTHING events; they're good for nothing");
return;
}
if (gdk_drag_handle_source_event (event))
return;
-2
View File
@@ -645,7 +645,5 @@ 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__ */
+3 -105
View File
@@ -29,7 +29,6 @@
#include "gdkinternals.h"
#include "gdkframeclockprivate.h"
#include "gdk.h"
#include "gdkprofilerprivate.h"
#ifdef G_OS_WIN32
#include <windows.h>
@@ -114,96 +113,6 @@ get_sleep_serial (void)
return sleep_serial;
}
static guint fps_counter = 0;
static void
add_timings_to_profiler (GdkFrameTimings *timings)
{
gdk_profiler_add_mark (timings->frame_time * 1000,
(timings->frame_end_time - timings->frame_time) * 1000,
"frame", "");
if (timings->layout_start_time != 0)
gdk_profiler_add_mark (timings->layout_start_time * 1000,
(timings->paint_start_time - timings->layout_start_time) * 1000,
"layout", "");
if (timings->paint_start_time != 0)
gdk_profiler_add_mark (timings->paint_start_time * 1000,
(timings->frame_end_time - timings->paint_start_time) * 1000,
"paint", "");
}
static gint64
guess_refresh_interval (GdkFrameClock *frame_clock)
{
gint64 interval;
gint64 i;
interval = G_MAXINT64;
for (i = gdk_frame_clock_get_history_start (frame_clock);
i < gdk_frame_clock_get_frame_counter (frame_clock);
i++)
{
GdkFrameTimings *t, *before;
gint64 ts, before_ts;
t = gdk_frame_clock_get_timings (frame_clock, i);
before = gdk_frame_clock_get_timings (frame_clock, i - 1);
if (t == NULL || before == NULL)
continue;
ts = gdk_frame_timings_get_frame_time (t);
before_ts = gdk_frame_timings_get_frame_time (before);
if (ts == 0 || before_ts == 0)
continue;
interval = MIN (interval, ts - before_ts);
}
if (interval == G_MAXINT64)
return 0;
return interval;
}
static double
frame_clock_get_fps (GdkFrameClock *frame_clock)
{
GdkFrameTimings *start, *end;
gint64 start_counter, end_counter;
gint64 start_timestamp, end_timestamp;
gint64 interval;
start_counter = gdk_frame_clock_get_history_start (frame_clock);
end_counter = gdk_frame_clock_get_frame_counter (frame_clock);
start = gdk_frame_clock_get_timings (frame_clock, start_counter);
for (end = gdk_frame_clock_get_timings (frame_clock, end_counter);
end_counter > start_counter && end != NULL && !gdk_frame_timings_get_complete (end);
end = gdk_frame_clock_get_timings (frame_clock, end_counter))
end_counter--;
if (end_counter - start_counter < 4)
return 0.0;
start_timestamp = gdk_frame_timings_get_presentation_time (start);
end_timestamp = gdk_frame_timings_get_presentation_time (end);
if (start_timestamp == 0 || end_timestamp == 0)
{
start_timestamp = gdk_frame_timings_get_frame_time (start);
end_timestamp = gdk_frame_timings_get_frame_time (end);
}
interval = gdk_frame_timings_get_refresh_interval (end);
if (interval == 0)
{
interval = guess_refresh_interval (frame_clock);
if (interval == 0)
return 0.0;
}
return ((double) end_counter - start_counter) * G_USEC_PER_SEC / (end_timestamp - start_timestamp);
}
static void
gdk_frame_clock_idle_init (GdkFrameClockIdle *frame_clock_idle)
{
@@ -214,11 +123,6 @@ gdk_frame_clock_idle_init (GdkFrameClockIdle *frame_clock_idle)
priv->frame_time = g_get_monotonic_time (); /* more sane than zero */
priv->freeze_count = 0;
#ifdef G_ENABLE_DEBUG
if (fps_counter == 0)
fps_counter = gdk_profiler_define_counter ("fps", "Frames per Second");
#endif
}
static void
@@ -501,7 +405,7 @@ gdk_frame_clock_paint_idle (void *data)
{
int iter;
#ifdef G_ENABLE_DEBUG
if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ())
if (GDK_DEBUG_CHECK (FRAMES))
{
if (priv->phase != GDK_FRAME_CLOCK_PHASE_LAYOUT &&
(priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT))
@@ -531,7 +435,7 @@ gdk_frame_clock_paint_idle (void *data)
if (priv->freeze_count == 0)
{
#ifdef G_ENABLE_DEBUG
if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ())
if (GDK_DEBUG_CHECK (FRAMES))
{
if (priv->phase != GDK_FRAME_CLOCK_PHASE_PAINT &&
(priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT))
@@ -558,7 +462,7 @@ gdk_frame_clock_paint_idle (void *data)
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
#ifdef G_ENABLE_DEBUG
if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ())
if (GDK_DEBUG_CHECK (FRAMES))
timings->frame_end_time = g_get_monotonic_time ();
#endif /* G_ENABLE_DEBUG */
}
@@ -571,12 +475,6 @@ gdk_frame_clock_paint_idle (void *data)
}
#ifdef G_ENABLE_DEBUG
if (gdk_profiler_is_running ())
{
add_timings_to_profiler (timings);
gdk_profiler_set_counter (fps_counter, timings->frame_end_time * 1000, frame_clock_get_fps (clock));
}
if (GDK_DEBUG_CHECK (FRAMES))
{
if (timings && timings->complete)
-230
View File
@@ -1,230 +0,0 @@
/* GDK - The GIMP Drawing Kit
*
* gdkprofiler.c: A simple profiler
*
* Copyright © 2018 Matthias Clasen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "gdkversionmacros.h"
#include "gdkprofilerprivate.h"
#include "gdkframeclockprivate.h"
#ifndef G_OS_WIN32
#include "capture/sp-capture-writer.h"
static SpCaptureWriter *writer = NULL;
static gboolean running = FALSE;
static void
profiler_stop (void)
{
if (writer)
sp_capture_writer_unref (writer);
}
void
gdk_profiler_start (int fd)
{
if (writer)
return;
sp_clock_init ();
if (fd == -1)
{
gchar *filename;
filename = g_strdup_printf ("gtk.%d.syscap", getpid ());
g_print ("Writing profiling data to %s\n", filename);
writer = sp_capture_writer_new (filename, 16*1024);
g_free (filename);
}
else if (fd > 2)
writer = sp_capture_writer_new_from_fd (fd, 16*1024);
if (writer)
running = TRUE;
atexit (profiler_stop);
}
void
gdk_profiler_stop (void)
{
running = FALSE;
}
gboolean
gdk_profiler_is_running (void)
{
return running;
}
void
gdk_profiler_add_mark (gint64 start,
guint64 duration,
const char *name,
const char *message)
{
if (!running)
return;
sp_capture_writer_add_mark (writer,
start,
-1, getpid (),
duration,
"gtk", name, message);
}
static guint
define_counter (const char *name,
const char *description,
int type)
{
SpCaptureCounter counter;
if (!writer)
return 0;
counter.id = (guint) sp_capture_writer_request_counter (writer, 1);
counter.type = type;
counter.value.vdbl = 0;
g_strlcpy (counter.category, "gtk", sizeof counter.category);
g_strlcpy (counter.name, name, sizeof counter.name);
g_strlcpy (counter.description, description, sizeof counter.name);
sp_capture_writer_define_counters (writer,
SP_CAPTURE_CURRENT_TIME,
-1,
getpid (),
&counter,
1);
return counter.id;
}
guint
gdk_profiler_define_counter (const char *name,
const char *description)
{
return define_counter (name, description, SP_CAPTURE_COUNTER_DOUBLE);
}
guint
gdk_profiler_define_int_counter (const char *name,
const char *description)
{
return define_counter (name, description, SP_CAPTURE_COUNTER_INT64);
}
void
gdk_profiler_set_counter (guint id,
gint64 time,
double val)
{
SpCaptureCounterValue value;
if (!running)
return;
value.vdbl = val;
sp_capture_writer_set_counters (writer,
time,
-1, getpid (),
&id, &value, 1);
}
void
gdk_profiler_set_int_counter (guint id,
gint64 time,
gint64 val)
{
SpCaptureCounterValue value;
if (!running)
return;
value.v64 = val;
sp_capture_writer_set_counters (writer,
time,
-1, getpid (),
&id, &value, 1);
}
#else
void
gdk_profiler_start (int fd)
{
}
void
gdk_profiler_stop (void)
{
}
gboolean
gdk_profiler_is_running (void)
{
return FALSE;
}
void
gdk_profiler_add_mark (gint64 start,
guint64 duration,
const char *name,
const char *message)
{
}
guint
gdk_profiler_define_counter (const char *name,
const char *description)
{
return 0;
}
void
gdk_profiler_set_counter (guint id,
gint64 time,
double value)
{
}
guint
gdk_profiler_define_int_counter (const char *name,
const char *description)
{
return 0;
}
void
gdk_profiler_set_int_counter (guint id,
gint64 time,
gint64 value)
{
}
#endif /* G_OS_WIN32 */
-46
View File
@@ -1,46 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2018 Red Hat, Inc.
*
* 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 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/>.
*/
#ifndef __GDK_PROFILER_PRIVATE_H__
#define __GDK_PROFILER_PRIVATE_H__
#include "gdk/gdkframeclock.h"
#include "gdk/gdkdisplay.h"
G_BEGIN_DECLS
void gdk_profiler_start (int fd);
void gdk_profiler_stop (void);
gboolean gdk_profiler_is_running (void);
void gdk_profiler_add_mark (gint64 start,
guint64 duration,
const char *name,
const char *message);
guint gdk_profiler_define_counter (const char *name,
const char *description);
void gdk_profiler_set_counter (guint id,
gint64 time,
double value);
guint gdk_profiler_define_int_counter (const char *name,
const char *description);
void gdk_profiler_set_int_counter (guint id,
gint64 time,
gint64 value);
G_END_DECLS
#endif /* __GDK_PROFILER_PRIVATE_H__ */
-1
View File
@@ -293,7 +293,6 @@ 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);
+1 -20
View File
@@ -107,7 +107,6 @@ enum {
PROP_0,
PROP_CURSOR,
PROP_DISPLAY,
PROP_FRAME_CLOCK,
PROP_STATE,
PROP_MAPPED,
LAST_PROP
@@ -269,13 +268,6 @@ 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"),
@@ -470,10 +462,6 @@ 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;
@@ -498,10 +486,6 @@ 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;
@@ -4202,10 +4186,7 @@ void
gdk_surface_set_startup_id (GdkSurface *surface,
const gchar *startup_id)
{
GdkSurfaceImplClass *klass = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
if (klass->set_startup_id)
klass->set_startup_id (surface, startup_id);
GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_startup_id (surface, startup_id);
}
/**
-8
View File
@@ -45,16 +45,8 @@ gdk_public_sources = files([
'gdkvulkancontext.c',
'gdksurface.c',
'gdksurfaceimpl.c',
'gdkprofiler.c'
])
if not win32_enabled
gdk_public_sources += files([
'capture/sp-capture-writer.c',
'capture/sp-clock.c'
])
endif
gdk_public_headers = files([
'gdk-autocleanup.h',
'gdk.h',
+2 -1
View File
@@ -33,7 +33,8 @@ gdk_quartz_public_headers = files([
'gdkquartzsurface.h',
])
install_headers(gdk_quartz_public_headers, 'gdkquartz.h', subdir: 'gtk-4.0/gdk/quartz/')
install_headers(gdk_quartz_public_headers, subdir: 'gtk-4.0/gdk/quartz/')
install_headers('gdkquartz.h', subdir: 'gtk-4.0/gdk/')
gdk_quartz_deps = [ # FIXME
]
+9 -7
View File
@@ -5028,29 +5028,31 @@ _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 (GdkWaylandSeat *seat,
_gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *seat,
GdkEventSequence **sequence)
{
GdkWaylandSeat *wayland_seat;
GdkWaylandTouchData *touch;
GHashTableIter iter;
GList *l;
uint32_t serial;
g_hash_table_iter_init (&iter, seat->touches);
wayland_seat = GDK_WAYLAND_SEAT (seat);
g_hash_table_iter_init (&iter, wayland_seat->touches);
if (sequence)
*sequence = NULL;
serial = seat->keyboard_key_serial;
serial = wayland_seat->keyboard_key_serial;
if (seat->pointer_info.press_serial > serial)
serial = seat->pointer_info.press_serial;
if (wayland_seat->pointer_info.press_serial > serial)
serial = wayland_seat->pointer_info.press_serial;
for (l = seat->tablets; l; l = l->next)
for (l = wayland_seat->tablets; l; l = l->next)
{
GdkWaylandTabletData *tablet = l->data;
+21 -155
View File
@@ -396,8 +396,6 @@ 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,
@@ -529,13 +527,6 @@ 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));
@@ -2179,123 +2170,6 @@ 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,
@@ -2314,17 +2188,13 @@ 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)));
monitor->x = x;
monitor->y = y;
gdk_monitor_set_position (GDK_MONITOR (monitor), x, 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 (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
apply_monitor_change (monitor);
if (should_update_monitor (monitor))
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
update_scale (GDK_MONITOR (monitor)->display);
}
@@ -2333,14 +2203,19 @@ 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));
monitor->wl_output_done = TRUE;
if (!monitor->added)
{
monitor->added = TRUE;
g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
gdk_display_monitor_added (display, GDK_MONITOR (monitor));
}
if (!monitor_has_xdg_output (monitor) || monitor->xdg_output_done)
apply_monitor_change (monitor);
update_scale (display);
}
static void
@@ -2357,9 +2232,6 @@ 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));
@@ -2367,11 +2239,10 @@ output_handle_scale (void *data,
height = previous_geometry.height * previous_scale;
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
monitor->width = width / scale;
monitor->height = height / scale;
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
if (should_update_monitor (monitor))
apply_monitor_change (monitor);
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
update_scale (GDK_MONITOR (monitor)->display);
}
static void
@@ -2393,12 +2264,11 @@ output_handle_mode (void *data,
return;
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
monitor->width = width / scale;
monitor->height = height / scale;
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
apply_monitor_change (monitor);
if (width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
update_scale (GDK_MONITOR (monitor)->display);
}
static const struct wl_output_listener output_listener =
@@ -2425,17 +2295,13 @@ gdk_wayland_display_add_output (GdkWaylandDisplay *display_wayland,
monitor->output = output;
monitor->version = version;
g_ptr_array_add (display_wayland->monitors, monitor);
gdk_display_monitor_added (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
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));
}
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 *
-2
View File
@@ -35,7 +35,6 @@
#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>
@@ -110,7 +109,6 @@ 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;
-3
View File
@@ -151,9 +151,6 @@ _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));
-9
View File
@@ -30,15 +30,6 @@ 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 {
+1 -2
View File
@@ -34,7 +34,6 @@
#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>
@@ -139,7 +138,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 (GdkWaylandSeat *seat,
uint32_t _gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *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,
+20 -23
View File
@@ -33,7 +33,6 @@
#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>
@@ -862,7 +861,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);
@@ -2186,12 +2185,14 @@ create_simple_positioner (GdkSurface *surface,
static void
gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
GdkSurface *parent,
GdkWaylandSeat *grab_input_seat)
struct wl_seat *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;
@@ -2209,11 +2210,10 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
g_warning ("Can't map popup, already mapped");
return;
}
if (grab_input_seat &&
((display->current_popups &&
g_list_last (display->current_popups)->data != parent) ||
(!display->current_popups &&
!is_realized_toplevel (parent))))
if ((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,13 +2264,10 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
g_assert_not_reached ();
}
if (grab_input_seat)
if (seat)
{
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);
gdk_seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_seat, NULL);
switch (display->shell_variant)
{
@@ -2291,7 +2288,7 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
display->current_popups = g_list_append (display->current_popups, surface);
}
static GdkWaylandSeat *
static struct wl_seat *
find_grab_input_seat (GdkSurface *surface,
GdkSurface *transient_for)
{
@@ -2304,7 +2301,7 @@ find_grab_input_seat (GdkSurface *surface,
* grab before showing the popup surface.
*/
if (impl->grab_input_seat)
return GDK_WAYLAND_SEAT (impl->grab_input_seat);
return gdk_wayland_seat_get_wl_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
@@ -2317,7 +2314,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 (tmp_impl->grab_input_seat);
return gdk_wayland_seat_get_wl_seat (tmp_impl->grab_input_seat);
}
while (transient_for)
@@ -2325,7 +2322,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 (tmp_impl->grab_input_seat);
return gdk_wayland_seat_get_wl_seat (tmp_impl->grab_input_seat);
transient_for = tmp_impl->transient_for;
}
@@ -2421,7 +2418,7 @@ gdk_wayland_surface_map (GdkSurface *surface)
if (should_map_as_popup (surface))
{
gboolean create_fallback = FALSE;
GdkWaylandSeat *grab_input_seat;
struct wl_seat *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
@@ -2495,8 +2492,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
{
@@ -3584,7 +3581,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_WAYLAND_SEAT (gdk_device_get_seat (device)),
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_device_get_seat (device),
&sequence);
switch (display_wayland->shell_variant)
@@ -3635,7 +3632,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_WAYLAND_SEAT (gdk_device_get_seat (device)),
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_device_get_seat (device),
&sequence);
switch (display_wayland->shell_variant)
{
+2 -2
View File
@@ -26,7 +26,8 @@ gdk_wayland_public_headers = files([
'gdkwaylandsurface.h'
])
install_headers(gdk_wayland_public_headers, 'gdkwayland.h', subdir: 'gtk-4.0/gdk/wayland/')
install_headers(gdk_wayland_public_headers, subdir: 'gtk-4.0/gdk/wayland/')
install_headers('gdkwayland.h', subdir: 'gtk-4.0/gdk/')
gdk_wayland_deps = [
shmlib,
@@ -57,7 +58,6 @@ proto_sources = [
['tablet', 'unstable', 'v2', ],
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
['server-decoration', 'private' ],
['xdg-output', 'unstable', 'v1', ],
]
gdk_wayland_gen_headers = []
+2 -2
View File
@@ -31,7 +31,7 @@
G_DEFINE_TYPE (GdkWin32CairoContext, gdk_win32_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
void
static 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;
}
void
static void
gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
RECT window_rect)
{
+1 -21
View File
@@ -166,27 +166,6 @@ 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))
@@ -197,6 +176,7 @@ 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),
-9
View File
@@ -384,15 +384,6 @@ 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__ */
+2 -1
View File
@@ -42,7 +42,8 @@ gdk_win32_public_headers = files([
'gdkwin32surface.h',
])
install_headers(gdk_win32_public_headers, 'gdkwin32.h', subdir: 'gtk-4.0/gdk/win32/')
install_headers(gdk_win32_public_headers, subdir: 'gtk-4.0/gdk/win32/')
install_headers('gdkwin32.h', subdir: 'gtk-4.0/gdk/')
gdk_win32_deps = [ # FIXME
pangowin32_dep
+4 -4
View File
@@ -31,8 +31,8 @@
#define HAS_FOCUS(toplevel) \
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
#define APPEARS_FOCUSED(toplevel) \
((toplevel)->has_focus || (toplevel)->has_focus_window || (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 = HAS_FOCUS (toplevel);
had_focus = APPEARS_FOCUSED (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 (HAS_FOCUS (toplevel) != had_focus)
if (APPEARS_FOCUSED (toplevel) != had_focus)
{
GdkEvent *event;
+4 -4
View File
@@ -36,8 +36,8 @@ static void gdk_event_source_finalize (GSource *source);
static GQuark quark_needs_enter = 0;
#define HAS_FOCUS(toplevel) \
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
#define APPEARS_FOCUSED(toplevel) \
((toplevel)->has_focus || (toplevel)->has_focus_window || (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 = HAS_FOCUS (toplevel);
had_focus = APPEARS_FOCUSED (toplevel);
toplevel->has_pointer_focus = focus_in;
if (HAS_FOCUS (toplevel) != had_focus)
if (APPEARS_FOCUSED (toplevel) != had_focus)
{
GdkEvent *focus_event;
-32
View File
@@ -1867,14 +1867,6 @@ 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)
@@ -1896,14 +1888,6 @@ 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)
@@ -1925,14 +1909,6 @@ 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)
@@ -3401,14 +3377,6 @@ 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)
+2 -1
View File
@@ -54,7 +54,8 @@ gdk_x11_public_headers = files([
'gdkx11surface.h',
])
install_headers(gdk_x11_public_headers, 'gdkx.h', subdir: 'gtk-4.0/gdk/x11/')
install_headers(gdk_x11_public_headers, subdir: 'gtk-4.0/gdk/x11/')
install_headers('gdkx.h', subdir: 'gtk-4.0/gdk/')
gdk_x11_deps = [
xrender_dep,
+1 -22
View File
@@ -1,7 +1,6 @@
#include "config.h"
#include "gskbroadwayrenderer.h"
#include "gskbroadwayrendererprivate.h"
#include "broadway/gdkprivate-broadway.h"
#include "gskdebugprivate.h"
@@ -828,23 +827,3 @@ static void
gsk_broadway_renderer_init (GskBroadwayRenderer *self)
{
}
/**
* gsk_broadway_renderer_new:
*
* Creates a new Broadway renderer.
*
* The Broadway renderer is the default renderer for the broadway backend.
* It will only work with broadway surfaces, otherwise it will fail the
* call to gdk_renderer_realize().
*
* This function is only available when GTK was compiled with Broadway
* support.
*
* Returns: a new Broadway renderer.
**/
GskRenderer *
gsk_broadway_renderer_new (void)
{
return g_object_new (GSK_TYPE_BROADWAY_RENDERER, NULL);
}
-52
View File
@@ -1,52 +0,0 @@
/*
* Copyright © 2019 Alexander Larsson
*
* 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/>.
*/
#ifndef __GSK_BROADWAY_RENDERER_H__
#define __GSK_BROADWAY_RENDERER_H__
#include <gdk/gdk.h>
#include <gsk/gskrenderer.h>
#ifdef GDK_WINDOWING_BROADWAY
#include <gdk/broadway/gdkbroadway.h>
G_BEGIN_DECLS
#define GSK_TYPE_BROADWAY_RENDERER (gsk_broadway_renderer_get_type ())
#define GSK_BROADWAY_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_BROADWAY_RENDERER, GskBroadwayRenderer))
#define GSK_IS_BROADWAY_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_BROADWAY_RENDERER))
#define GSK_BROADWAY_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_BROADWAY_RENDERER, GskBroadwayRendererClass))
#define GSK_IS_BROADWAY_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_BROADWAY_RENDERER))
#define GSK_BROADWAY_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_BROADWAY_RENDERER, GskBroadwayRendererClass))
typedef struct _GskBroadwayRenderer GskBroadwayRenderer;
typedef struct _GskBroadwayRendererClass GskBroadwayRendererClass;
GDK_AVAILABLE_IN_ALL
GType gsk_broadway_renderer_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GskRenderer * gsk_broadway_renderer_new (void);
G_END_DECLS
#endif /* GDK_WINDOWING_BROADWAY */
#endif /* __GSK_BROADWAY_RENDERER_H__ */
+24
View File
@@ -0,0 +1,24 @@
#ifndef __GSK_BROADWAY_RENDERER_PRIVATE_H__
#define __GSK_BROADWAY_RENDERER_PRIVATE_H__
#include "broadway/gdkbroadway.h"
#include <gsk/gskrenderer.h>
G_BEGIN_DECLS
#define GSK_TYPE_BROADWAY_RENDERER (gsk_broadway_renderer_get_type ())
#define GSK_BROADWAY_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_BROADWAY_RENDERER, GskBroadwayRenderer))
#define GSK_IS_BROADWAY_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_BROADWAY_RENDERER))
#define GSK_BROADWAY_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_BROADWAY_RENDERER, GskBroadwayRendererClass))
#define GSK_IS_BROADWAY_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_BROADWAY_RENDERER))
#define GSK_BROADWAY_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_BROADWAY_RENDERER, GskBroadwayRendererClass))
typedef struct _GskBroadwayRenderer GskBroadwayRenderer;
typedef struct _GskBroadwayRendererClass GskBroadwayRendererClass;
GType gsk_broadway_renderer_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GSK_BROADWAY_RENDERER_PRIVATE_H__ */
+4 -31
View File
@@ -1,6 +1,6 @@
#include "config.h"
#include "gskglrenderer.h"
#include "gskglrendererprivate.h"
#include "gskdebugprivate.h"
#include "gskenums.h"
@@ -21,7 +21,6 @@
#include "gdk/gdkgltextureprivate.h"
#include "gdk/gdkglcontextprivate.h"
#include "gdk/gdkprofilerprivate.h"
#include <epoxy/gl.h>
#include <cairo-ft.h>
@@ -1269,17 +1268,10 @@ render_blur_node (GskGLRenderer *self,
const float min_y = builder->dy + node->bounds.origin.y;
const float max_x = min_x + node->bounds.size.width;
const float max_y = min_y + node->bounds.size.height;
const float blur_radius = gsk_blur_node_get_radius (node);
int texture_id;
gboolean is_offscreen;
RenderOp op;
if (blur_radius <= 0)
{
gsk_gl_renderer_add_render_ops (self, gsk_blur_node_get_child (node), builder);
return;
}
/* TODO(perf): We're forcing the child offscreen even if it's a texture
* so the resulting offscreen texture is bigger by the gaussian blur factor
* (see gsk_blur_node_new), but we didn't have to do that if the blur
@@ -1891,13 +1883,13 @@ render_cross_fade_node (GskGLRenderer *self,
&node->bounds,
start_node,
&start_texture_id, &is_offscreen1,
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY);
FORCE_OFFSCREEN | RESET_CLIP);
add_offscreen_ops (self, builder,
&node->bounds,
end_node,
&end_texture_id, &is_offscreen2,
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY);
FORCE_OFFSCREEN | RESET_CLIP);
ops_set_program (builder, &self->cross_fade_program);
op.op = OP_CHANGE_CROSS_FADE;
@@ -3009,7 +3001,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
gsize buffer_size;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
gint64 gpu_time, cpu_time, start_time;
gint64 gpu_time, cpu_time;
#endif
#ifdef G_ENABLE_DEBUG
@@ -3117,7 +3109,6 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
#ifdef G_ENABLE_DEBUG
gsk_profiler_counter_inc (profiler, self->profile_counters.frames);
start_time = gsk_profiler_timer_get_start (profiler, self->profile_timers.cpu_time);
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
@@ -3125,10 +3116,6 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
gsk_profiler_timer_set (profiler, self->profile_timers.gpu_time, gpu_time);
gsk_profiler_push_samples (profiler);
if (gdk_profiler_is_running ())
gdk_profiler_add_mark (start_time, cpu_time, "render", "");
#endif
}
@@ -3294,17 +3281,3 @@ gsk_gl_renderer_init (GskGLRenderer *self)
}
#endif
}
/**
* gsk_gl_renderer_new:
*
* Creates a new #GskRenderer using OpenGL. This is the default renderer
* used by GTK.
*
* Returns: a new GL renderer
**/
GskRenderer *
gsk_gl_renderer_new (void)
{
return g_object_new (GSK_TYPE_GL_RENDERER, NULL);
}
-47
View File
@@ -1,47 +0,0 @@
/*
* Copyright © 2016 Endless
* 2018 Timm Bäder <mail@baedert.org>
*
* 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: Timm Bäder <mail@baedert.org>
*/
#ifndef __GSK_GL_RENDERER_H__
#define __GSK_GL_RENDERER_H__
#include <gsk/gskrenderer.h>
G_BEGIN_DECLS
#define GSK_TYPE_GL_RENDERER (gsk_gl_renderer_get_type ())
#define GSK_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_GL_RENDERER, GskGLRenderer))
#define GSK_IS_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_GL_RENDERER))
#define GSK_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
#define GSK_IS_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_GL_RENDERER))
#define GSK_GL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
typedef struct _GskGLRenderer GskGLRenderer;
typedef struct _GskGLRendererClass GskGLRendererClass;
GDK_AVAILABLE_IN_ALL
GType gsk_gl_renderer_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GskRenderer * gsk_gl_renderer_new (void);
G_END_DECLS
#endif /* __GSK_GL_RENDERER_H__ */
+23
View File
@@ -0,0 +1,23 @@
#ifndef __GSK_GL_RENDERER_PRIVATE_H__
#define __GSK_GL_RENDERER_PRIVATE_H__
#include <gsk/gskrenderer.h>
G_BEGIN_DECLS
#define GSK_TYPE_GL_RENDERER (gsk_gl_renderer_get_type ())
#define GSK_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_GL_RENDERER, GskGLRenderer))
#define GSK_IS_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_GL_RENDERER))
#define GSK_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
#define GSK_IS_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_GL_RENDERER))
#define GSK_GL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
typedef struct _GskGLRenderer GskGLRenderer;
typedef struct _GskGLRendererClass GskGLRendererClass;
GType gsk_gl_renderer_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GSK_GL_RENDERER_PRIVATE_H__ */
+1 -1
View File
@@ -7,7 +7,7 @@
#include "gskgldriverprivate.h"
#include "gskroundedrectprivate.h"
#include "gskglrenderer.h"
#include "gskglrendererprivate.h"
#include "gskrendernodeprivate.h"
#define GL_N_VERTICES 6
-5
View File
@@ -26,11 +26,6 @@
#include <gsk/gskroundedrect.h>
#include <gsk/gsktransform.h>
#include <gsk/gskcairorenderer.h>
#include <gsk/gl/gskglrenderer.h>
#include <gsk/broadway/gskbroadwayrenderer.h>
#include <gsk/vulkan/gskvulkanrenderer.h>
#include <gsk/gsktypes.h>
#include <gsk/gskenumtypes.h>
+1 -41
View File
@@ -1,26 +1,6 @@
/*
* Copyright © 2016 Endless
* 2018 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 "gskcairorenderer.h"
#include "gskcairorendererprivate.h"
#include "gskdebugprivate.h"
#include "gskrendererprivate.h"
@@ -179,23 +159,3 @@ gsk_cairo_renderer_init (GskCairoRenderer *self)
self->profile_timers.cpu_time = gsk_profiler_add_timer (profiler, "cpu-time", "CPU time", FALSE, TRUE);
#endif
}
/**
* gsk_cairo_renderer_new:
*
* Creates a new Cairo renderer.
*
* The Cairo renderer is the fallback renderer drawing in ways similar
* to how GTK 3 drew its content. Its primary use is as comparison tool.
*
* The Cairo renderer is incomplete. It cannot render 3D transformed
* content and will instead render an error marker. Its usage should be
* avoided.
*
* Returns: a new Cairo renderer.
**/
GskRenderer *
gsk_cairo_renderer_new (void)
{
return g_object_new (GSK_TYPE_CAIRO_RENDERER, NULL);
}
-48
View File
@@ -1,48 +0,0 @@
/*
* Copyright © 2016 Endless
* 2018 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 __GSK_CAIRO_RENDERER_H__
#define __GSK_CAIRO_RENDERER_H__
#include <cairo.h>
#include <gsk/gskrenderer.h>
G_BEGIN_DECLS
#define GSK_TYPE_CAIRO_RENDERER (gsk_cairo_renderer_get_type ())
#define GSK_CAIRO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_CAIRO_RENDERER, GskCairoRenderer))
#define GSK_IS_CAIRO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_CAIRO_RENDERER))
#define GSK_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_CAIRO_RENDERER, GskCairoRendererClass))
#define GSK_IS_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_CAIRO_RENDERER))
#define GSK_CAIRO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_CAIRO_RENDERER, GskCairoRendererClass))
typedef struct _GskCairoRenderer GskCairoRenderer;
typedef struct _GskCairoRendererClass GskCairoRendererClass;
GDK_AVAILABLE_IN_ALL
GType gsk_cairo_renderer_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GskRenderer * gsk_cairo_renderer_new (void);
G_END_DECLS
#endif /* __GSK_CAIRO_RENDERER_H__ */
+24
View File
@@ -0,0 +1,24 @@
#ifndef __GSK_CAIRO_RENDERER_PRIVATE_H__
#define __GSK_CAIRO_RENDERER_PRIVATE_H__
#include <cairo.h>
#include <gsk/gskrenderer.h>
G_BEGIN_DECLS
#define GSK_TYPE_CAIRO_RENDERER (gsk_cairo_renderer_get_type ())
#define GSK_CAIRO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_CAIRO_RENDERER, GskCairoRenderer))
#define GSK_IS_CAIRO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_CAIRO_RENDERER))
#define GSK_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_CAIRO_RENDERER, GskCairoRendererClass))
#define GSK_IS_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_CAIRO_RENDERER))
#define GSK_CAIRO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_CAIRO_RENDERER, GskCairoRendererClass))
typedef struct _GskCairoRenderer GskCairoRenderer;
typedef struct _GskCairoRendererClass GskCairoRendererClass;
GType gsk_cairo_renderer_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GSK_CAIRO_RENDERER_PRIVATE_H__ */
-13
View File
@@ -365,19 +365,6 @@ gsk_profiler_timer_get (GskProfiler *profiler,
return timer->value;
}
gint64
gsk_profiler_timer_get_start (GskProfiler *profiler,
GQuark timer_id)
{
NamedTimer *timer;
timer = gsk_profiler_get_timer (profiler, timer_id);
if (timer == NULL)
return 0;
return timer->start_time;
}
void
gsk_profiler_reset (GskProfiler *profiler)
{
-2
View File
@@ -40,8 +40,6 @@ gint64 gsk_profiler_counter_get (GskProfiler *profiler,
GQuark counter_id);
gint64 gsk_profiler_timer_get (GskProfiler *profiler,
GQuark timer_id);
gint64 gsk_profiler_timer_get_start (GskProfiler *profiler,
GQuark timer_id);
void gsk_profiler_reset (GskProfiler *profiler);
+4 -4
View File
@@ -36,9 +36,9 @@
#include "gskrendererprivate.h"
#include "gskcairorenderer.h"
#include "gskcairorendererprivate.h"
#include "gskdebugprivate.h"
#include "gl/gskglrenderer.h"
#include "gl/gskglrendererprivate.h"
#include "gskprofilerprivate.h"
#include "gskrendernodeprivate.h"
@@ -55,10 +55,10 @@
#include <gdk/wayland/gdkwayland.h>
#endif
#ifdef GDK_WINDOWING_BROADWAY
#include "broadway/gskbroadwayrenderer.h"
#include "broadway/gskbroadwayrendererprivate.h"
#endif
#ifdef GDK_RENDERING_VULKAN
#include "vulkan/gskvulkanrenderer.h"
#include "vulkan/gskvulkanrendererprivate.h"
#endif
typedef struct
+9 -19
View File
@@ -449,32 +449,22 @@ gsk_border_node_draw (GskRenderNode *node,
* Note that the call to cairo_fill() will add the potential final
* segment by closing the path, so we don't have to care.
*/
float dst = MIN (bounds->size.width, bounds->size.height) / 2.0;
cairo_pattern_t *mesh;
cairo_matrix_t mat;
graphene_point_t tl, br;
float scale;
mesh = cairo_pattern_create_mesh ();
cairo_matrix_init_translate (&mat, -bounds->origin.x, -bounds->origin.y);
cairo_pattern_set_matrix (mesh, &mat);
scale = MIN (bounds->size.width / (self->border_width[1] + self->border_width[3]),
bounds->size.height / (self->border_width[0] + self->border_width[2]));
graphene_point_init (&tl,
self->border_width[3] * scale,
self->border_width[0] * scale);
graphene_point_init (&br,
bounds->size.width - self->border_width[1] * scale,
bounds->size.height - self->border_width[2] * scale);
/* Top */
if (self->border_width[0] > 0)
{
gsk_border_node_mesh_add_patch (mesh,
&self->border_color[0],
0, 0,
tl.x, tl.y,
br.x, tl.y,
dst * self->border_width[3] / self->border_width[0], dst,
bounds->size.width - dst * self->border_width[1] / self->border_width[0], dst,
bounds->size.width, 0);
}
@@ -484,8 +474,8 @@ gsk_border_node_draw (GskRenderNode *node,
gsk_border_node_mesh_add_patch (mesh,
&self->border_color[1],
bounds->size.width, 0,
br.x, tl.y,
br.x, br.y,
bounds->size.width - dst, dst * self->border_width[0] / self->border_width[1],
bounds->size.width - dst, bounds->size.height - dst * self->border_width[2] / self->border_width[1],
bounds->size.width, bounds->size.height);
}
@@ -495,8 +485,8 @@ gsk_border_node_draw (GskRenderNode *node,
gsk_border_node_mesh_add_patch (mesh,
&self->border_color[2],
0, bounds->size.height,
tl.x, br.y,
br.x, br.y,
dst * self->border_width[3] / self->border_width[2], bounds->size.height - dst,
bounds->size.width - dst * self->border_width[1] / self->border_width[2], bounds->size.height - dst,
bounds->size.width, bounds->size.height);
}
@@ -506,8 +496,8 @@ gsk_border_node_draw (GskRenderNode *node,
gsk_border_node_mesh_add_patch (mesh,
&self->border_color[3],
0, 0,
tl.x, tl.y,
tl.x, br.y,
dst, dst * self->border_width[0] / self->border_width[3],
dst, bounds->size.height - dst * self->border_width[2] / self->border_width[3],
0, bounds->size.height);
}
+47 -26
View File
@@ -106,6 +106,7 @@ static gboolean
parse_rounded_rect (GtkCssParser *parser,
gpointer out_rect)
{
const GtkCssToken *token;
graphene_rect_t r;
graphene_size_t corners[4];
double d;
@@ -114,17 +115,21 @@ parse_rounded_rect (GtkCssParser *parser,
if (!parse_rect_without_semicolon (parser, &r))
return FALSE;
if (!gtk_css_parser_try_delim (parser, '/'))
token = gtk_css_parser_get_token (parser);
if (!gtk_css_token_is_delim (token, '/'))
{
if (!parse_semicolon (parser))
return FALSE;
gsk_rounded_rect_init_from_rect (out_rect, &r, 0);
return TRUE;
}
gtk_css_parser_consume_token (parser);
for (i = 0; i < 4; i++)
{
if (!gtk_css_parser_has_number (parser))
token = gtk_css_parser_get_token (parser);
if (gtk_css_token_is (token, GTK_CSS_TOKEN_SEMICOLON) ||
gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
break;
if (!gtk_css_parser_consume_number (parser, &d))
return FALSE;
@@ -143,13 +148,16 @@ parse_rounded_rect (GtkCssParser *parser,
for (; i < 4; i++)
corners[i].width = corners[(i - 1) >> 1].width;
if (gtk_css_parser_try_delim (parser, '/'))
token = gtk_css_parser_get_token (parser);
if (gtk_css_token_is_delim (token, '/'))
{
gtk_css_parser_consume_token (parser);
for (i = 0; i < 4; i++)
{
if (!gtk_css_parser_has_number (parser))
token = gtk_css_parser_get_token (parser);
if (gtk_css_token_is (token, GTK_CSS_TOKEN_SEMICOLON) ||
gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
break;
if (!gtk_css_parser_consume_number (parser, &d))
return FALSE;
@@ -1160,6 +1168,13 @@ gsk_render_node_parser_error (GtkCssParser *parser,
error_func_pair->error_func (section, error, error_func_pair->user_data);
gtk_css_section_unref (section);
}
#if 0
g_print ("ERROR: %zu:%zu: %s\n",
start->lines + 1,
start->line_chars,
error->message);
#endif
}
GskRenderNode *
@@ -1312,7 +1327,7 @@ append_rounded_rect (GString *str,
g_string_append_c (str, ' ');
}
string_append_double (str, r->corner[3].height);
string_append_double (str, r->corner[4].height);
}
}
}
@@ -1485,7 +1500,7 @@ render_node_print (Printer *p,
}
end_node (p);
}
break;
break;
case GSK_COLOR_NODE:
{
@@ -1494,7 +1509,7 @@ render_node_print (Printer *p,
append_rgba_param (p, "color", gsk_color_node_peek_color (node));
end_node (p);
}
break;
break;
case GSK_CROSS_FADE_NODE:
{
@@ -1506,7 +1521,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_LINEAR_GRADIENT_NODE:
{
@@ -1542,7 +1557,12 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
{
g_error ("Add public api to access the repeating linear gradient node data");
}
break;
case GSK_OPACITY_NODE:
{
@@ -1553,7 +1573,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_OUTSET_SHADOW_NODE:
{
@@ -1568,7 +1588,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_CLIP_NODE:
{
@@ -1579,7 +1599,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_ROUNDED_CLIP_NODE:
{
@@ -1591,7 +1611,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_TRANSFORM_NODE:
{
@@ -1602,7 +1622,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_COLOR_MATRIX_NODE:
{
@@ -1614,7 +1634,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_BORDER_NODE:
{
@@ -1646,7 +1666,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_SHADOW_NODE:
{
@@ -1684,7 +1704,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_INSET_SHADOW_NODE:
{
@@ -1699,7 +1719,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_TEXTURE_NODE:
{
@@ -1729,7 +1749,7 @@ render_node_print (Printer *p,
g_free (b64);
g_free (data);
}
break;
break;
case GSK_TEXT_NODE:
{
@@ -1773,7 +1793,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_DEBUG_NODE:
{
@@ -1781,12 +1801,12 @@ render_node_print (Printer *p,
_indent (p);
/* TODO: We potentially need to escape certain characters in the message */
g_string_append_printf (p->str, "message: \"%s\";\n", gsk_debug_node_get_message (node));
g_string_append_printf (p->str, "message: \"%s\"\n", gsk_debug_node_get_message (node));
append_node_param (p, "child", gsk_debug_node_get_child (node));
end_node (p);
}
break;
break;
case GSK_BLUR_NODE:
{
@@ -1797,7 +1817,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_REPEAT_NODE:
{
@@ -1809,7 +1829,7 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_BLEND_NODE:
{
@@ -1832,17 +1852,18 @@ render_node_print (Printer *p,
end_node (p);
}
break;
break;
case GSK_NOT_A_RENDER_NODE:
g_assert_not_reached ();
break;
case GSK_CAIRO_NODE:
break;
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
default:
g_error ("Unhandled node: %s", node->node_class->type_name);
break;
}
}
+7 -13
View File
@@ -197,10 +197,9 @@ gsk_rounded_rect_offset (GskRoundedRect *self,
}
static void
border_radius_shrink (graphene_size_t *corner,
double width,
double height,
const graphene_size_t *max)
border_radius_shrink (graphene_size_t *corner,
double width,
double height)
{
if (corner->width > 0)
corner->width -= width;
@@ -212,11 +211,6 @@ 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);
}
}
/**
@@ -266,10 +260,10 @@ gsk_rounded_rect_shrink (GskRoundedRect *self,
self->bounds.size.height -= top + 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);
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);
return self;
}
+31 -24
View File
@@ -19,7 +19,7 @@
/**
* SECTION:GskTransform
* SECTION:gsktransform
* @Title: GskTransform
* @Short_description: A description for transform operations
*
@@ -42,7 +42,8 @@ typedef struct _GskTransformClass GskTransformClass;
struct _GskTransform
{
const GskTransformClass *transform_class;
volatile int ref_count;
GskTransformCategory category;
GskTransform *next;
};
@@ -112,9 +113,10 @@ gsk_transform_alloc (const GskTransformClass *transform_class,
g_return_val_if_fail (transform_class != NULL, NULL);
self = g_atomic_rc_box_alloc0 (transform_class->struct_size);
self = g_malloc0 (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;
@@ -310,15 +312,15 @@ gsk_matrix_transform_apply_affine (GskTransform *transform,
break;
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
*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);
*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);
break;
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
*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_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);
break;
case GSK_TRANSFORM_CATEGORY_IDENTITY:
@@ -345,8 +347,8 @@ gsk_matrix_transform_apply_translate (GskTransform *transform,
break;
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
*out_dx += graphene_matrix_get_x_translation (&self->matrix);
*out_dy += graphene_matrix_get_y_translation (&self->matrix);
*out_dx += graphene_matrix_get_value (&self->matrix, 3, 0);
*out_dy += graphene_matrix_get_value (&self->matrix, 3, 1);
break;
case GSK_TRANSFORM_CATEGORY_IDENTITY:
@@ -419,10 +421,8 @@ gsk_matrix_transform_equal (GskTransform *first_transform,
GskMatrixTransform *first = (GskMatrixTransform *) first_transform;
GskMatrixTransform *second = (GskMatrixTransform *) second_transform;
if (graphene_matrix_equal_fast (&first->matrix, &second->matrix))
return TRUE;
return graphene_matrix_equal (&first->matrix, &second->matrix);
/* Crude, but better than just returning FALSE */
return memcmp (&first->matrix, &second->matrix, sizeof (graphene_matrix_t)) == 0;
}
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 G_APPROX_VALUE (first->angle, second->angle, 0.01f);
return first->angle == second->angle;
}
static void
@@ -837,8 +837,8 @@ gsk_rotate3d_transform_equal (GskTransform *first_transform,
GskRotate3dTransform *first = (GskRotate3dTransform *) first_transform;
GskRotate3dTransform *second = (GskRotate3dTransform *) second_transform;
return G_APPROX_VALUE (first->angle, second->angle, 0.01f) &&
graphene_vec3_equal (&first->axis, &second->axis);
return first->angle == second->angle
&& 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 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);
return first->factor_x == second->factor_x
&& first->factor_y == second->factor_y
&& first->factor_z == second->factor_z;
}
static void
@@ -1150,7 +1150,7 @@ gsk_perspective_transform_equal (GskTransform *first_transform,
GskPerspectiveTransform *first = (GskPerspectiveTransform *) first_transform;
GskPerspectiveTransform *second = (GskPerspectiveTransform *) second_transform;
return G_APPROX_VALUE (first->depth, second->depth, 0.001f);
return first->depth == second->depth;
}
static void
@@ -1217,6 +1217,8 @@ gsk_transform_finalize (GskTransform *self)
self->transform_class->finalize (self);
gsk_transform_unref (self->next);
g_free (self);
}
/**
@@ -1233,7 +1235,9 @@ gsk_transform_ref (GskTransform *self)
if (self == NULL)
return NULL;
return g_atomic_rc_box_acquire (self);
g_atomic_int_inc (&self->ref_count);
return self;
}
/**
@@ -1251,7 +1255,8 @@ gsk_transform_unref (GskTransform *self)
if (self == NULL)
return;
g_atomic_rc_box_release_full (self, (GDestroyNotify) gsk_transform_finalize);
if (g_atomic_int_dec_and_test (&self->ref_count))
gsk_transform_finalize (self);
}
/**
@@ -1690,6 +1695,7 @@ 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;
}
@@ -1897,6 +1903,7 @@ gsk_transform_parse (const char *string,
result = FALSE;
}
gtk_css_parser_unref (parser);
g_bytes_unref (bytes);
return result;
+5 -23
View File
@@ -22,23 +22,23 @@ gsk_private_gl_shaders = [
gsk_public_sources = files([
'gskdiff.c',
'gskcairorenderer.c',
'gskrenderer.c',
'gskrendernode.c',
'gskrendernodeimpl.c',
'gskroundedrect.c',
'gsktransform.c',
'gl/gskglrenderer.c',
])
gsk_private_sources = files([
'gskcairoblur.c',
'gskcairorenderer.c',
'gskdebug.c',
'gskprivate.c',
'gskprofiler.c',
'gskrendernodeparser.c',
'gl/gskshaderbuilder.c',
'gl/gskglprofiler.c',
'gl/gskglrenderer.c',
'gl/gskglglyphcache.c',
'gl/gskglimage.c',
'gl/gskgldriver.c',
@@ -48,35 +48,17 @@ gsk_private_sources = files([
])
gsk_public_headers = files([
'gskcairorenderer.h',
'gskenums.h',
'gskrenderer.h',
'gskrendernode.h',
'gskroundedrect.h',
'gsktransform.h',
'gsktypes.h',
'gsk-autocleanup.h',
'gsk-autocleanup.h'
])
install_headers(gsk_public_headers, 'gsk.h', subdir: 'gtk-4.0/gsk')
gsk_public_gl_headers = files([
'gl/gskglrenderer.h'
])
install_headers(gsk_public_gl_headers, subdir: 'gtk-4.0/gsk/gl')
gsk_public_headers += gsk_public_gl_headers
gsk_public_broadway_headers = files([
'broadway/gskbroadwayrenderer.h'
])
install_headers(gsk_public_broadway_headers, subdir: 'gtk-4.0/gsk/broadway')
gsk_public_headers += gsk_public_broadway_headers
gsk_public_vulkan_headers = files([
'vulkan/gskvulkanrenderer.h'
])
install_headers(gsk_public_vulkan_headers, subdir: 'gtk-4.0/gsk/vulkan')
gsk_public_headers += gsk_public_vulkan_headers
gsk_private_vulkan_shaders = []
# This is an odd split because we use configure_file() below to workaround
# a limitation in meson preventing using custom_target() with gnome.compile_resources()
@@ -116,7 +98,7 @@ if have_vulkan
endif # have_vulkan
if get_variable('broadway_enabled')
gsk_public_sources += files([
gsk_private_sources += files([
'broadway/gskbroadwayrenderer.c',
])
endif
+16 -16
View File
@@ -264,22 +264,22 @@ void main() {
vec4 result;
switch(u_mode) {
case 0: result = normal(top_color, bottom_color); break;
case 1: result = multiply(top_color, bottom_color); break;
case 2: result = screen(top_color, bottom_color); break;
case 3: result = overlay(top_color, bottom_color); break;
case 4: result = darken(top_color, bottom_color); break;
case 5: result = lighten(top_color, bottom_color); break;
case 6: result = color_dodge(top_color, bottom_color); break;
case 7: result = color_burn(top_color, bottom_color); break;
case 8: result = hard_light(top_color, bottom_color); break;
case 9: result = soft_light(top_color, bottom_color); break;
case 10: result = difference(top_color, bottom_color); break;
case 11: result = exclusion(top_color, bottom_color); break;
case 12: result = color(top_color, bottom_color); break;
case 13: result = hue(top_color, bottom_color); break;
case 14: result = saturation(top_color, bottom_color); break;
case 15: result = luminosity(top_color, bottom_color); break;
case 0: result = normal(bottom_color, top_color); break;
case 1: result = multiply(bottom_color, top_color); break;
case 2: result = screen(bottom_color, top_color); break;
case 3: result = overlay(bottom_color, top_color); break;
case 4: result = darken(bottom_color, top_color); break;
case 5: result = lighten(bottom_color, top_color); break;
case 6: result = color_dodge(bottom_color, top_color); break;
case 7: result = color_burn(bottom_color, top_color); break;
case 8: result = hard_light(bottom_color, top_color); break;
case 9: result = soft_light(bottom_color, top_color); break;
case 10: result = difference(bottom_color, top_color); break;
case 11: result = exclusion(bottom_color, top_color); break;
case 12: result = color(bottom_color, top_color); break;
case 13: result = hue(bottom_color, top_color); break;
case 14: result = saturation(bottom_color, top_color); break;
case 15: result = luminosity(bottom_color, top_color); break;
default: discard;
}
+1 -2
View File
@@ -8,8 +8,7 @@ void main() {
color.rgb *= color.a;
// u_source is drawn using cairo, so already pre-multiplied.
color = vec4(color.rgb * diffuse.a * u_alpha,
color.a * diffuse.a * u_alpha);
color = vec4(u_color.rgb * diffuse.a * u_alpha, diffuse.a * color.a * u_alpha);
setOutputColor(color);
}
+1 -43
View File
@@ -13,7 +13,6 @@
#include "gskvulkanglyphcacheprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkprofilerprivate.h"
#include <graphene.h>
@@ -39,9 +38,6 @@ typedef struct {
} ProfileTimers;
#endif
static guint texture_pixels_counter;
static guint fallback_pixels_counter;
struct _GskVulkanRenderer
{
GskRenderer parent_instance;
@@ -174,7 +170,7 @@ gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
GdkTexture *texture;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
gint64 cpu_time, start_time;
gint64 cpu_time;
#endif
#ifdef G_ENABLE_DEBUG
@@ -205,22 +201,10 @@ gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
gsk_vulkan_render_free (render);
#ifdef G_ENABLE_DEBUG
start_time = gsk_profiler_timer_get_start (profiler, self->profile_timers.cpu_time);
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
gsk_profiler_push_samples (profiler);
if (gdk_profiler_is_running ())
{
gdk_profiler_add_mark (start_time, cpu_time, "render", "");
gdk_profiler_set_int_counter (texture_pixels_counter,
start_time + cpu_time,
gsk_profiler_counter_get (profiler, self->profile_counters.texture_pixels));
gdk_profiler_set_int_counter (fallback_pixels_counter,
start_time + cpu_time,
gsk_profiler_counter_get (profiler, self->profile_counters.fallback_pixels));
}
#endif
return texture;
@@ -300,13 +284,6 @@ gsk_vulkan_renderer_init (GskVulkanRenderer *self)
self->profile_timers.cpu_time = gsk_profiler_add_timer (profiler, "cpu-time", "CPU time", FALSE, TRUE);
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), SYNC))
self->profile_timers.gpu_time = gsk_profiler_add_timer (profiler, "gpu-time", "GPU time", FALSE, TRUE);
if (texture_pixels_counter == 0)
{
texture_pixels_counter = gdk_profiler_define_int_counter ("texture-pixels", "Texture Pixels");
fallback_pixels_counter = gdk_profiler_define_int_counter ("fallback-pixels", "Fallback Pixels");
}
#endif
}
@@ -387,22 +364,3 @@ gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
{
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, scale);
}
/**
* gsk_vulkan_renderer_new:
*
* Creates a new Vulkan renderer.
*
* The Vulkan renderer is a renderer that uses the Vulkan library for
* rendering.
*
* This function is only available when GTK was compiled with Vulkan
* support.
*
* Returns: a new Vulkan renderer
**/
GskRenderer *
gsk_vulkan_renderer_new (void)
{
return g_object_new (GSK_TYPE_VULKAN_RENDERER, NULL);
}
-51
View File
@@ -1,51 +0,0 @@
/*
* Copyright © 2016 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/>.
*/
#ifndef __GSK_VULKAN_RENDERER_H__
#define __GSK_VULKAN_RENDERER_H__
#include <gdk/gdk.h>
#include <gsk/gskrenderer.h>
#ifdef GDK_RENDERING_VULKAN
#include <vulkan/vulkan.h>
G_BEGIN_DECLS
#define GSK_TYPE_VULKAN_RENDERER (gsk_vulkan_renderer_get_type ())
#define GSK_VULKAN_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_VULKAN_RENDERER, GskVulkanRenderer))
#define GSK_IS_VULKAN_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_VULKAN_RENDERER))
#define GSK_VULKAN_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_VULKAN_RENDERER, GskVulkanRendererClass))
#define GSK_IS_VULKAN_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_VULKAN_RENDERER))
#define GSK_VULKAN_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_VULKAN_RENDERER, GskVulkanRendererClass))
typedef struct _GskVulkanRenderer GskVulkanRenderer;
typedef struct _GskVulkanRendererClass GskVulkanRendererClass;
GDK_AVAILABLE_IN_ALL
GType gsk_vulkan_renderer_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GskRenderer * gsk_vulkan_renderer_new (void);
G_END_DECLS
#endif /* GDK_WINDOWING_VULKAN */
#endif /* __GSK_VULKAN_RENDERER_H__ */
+16 -1
View File
@@ -1,11 +1,26 @@
#ifndef __GSK_VULKAN_RENDERER_PRIVATE_H__
#define __GSK_VULKAN_RENDERER_PRIVATE_H__
#include "gskvulkanrenderer.h"
#include <vulkan/vulkan.h>
#include <gsk/gskrenderer.h>
#include "gskvulkanimageprivate.h"
G_BEGIN_DECLS
#define GSK_TYPE_VULKAN_RENDERER (gsk_vulkan_renderer_get_type ())
#define GSK_VULKAN_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_VULKAN_RENDERER, GskVulkanRenderer))
#define GSK_IS_VULKAN_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_VULKAN_RENDERER))
#define GSK_VULKAN_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_VULKAN_RENDERER, GskVulkanRendererClass))
#define GSK_IS_VULKAN_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_VULKAN_RENDERER))
#define GSK_VULKAN_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_VULKAN_RENDERER, GskVulkanRendererClass))
typedef struct _GskVulkanRenderer GskVulkanRenderer;
typedef struct _GskVulkanRendererClass GskVulkanRendererClass;
GType gsk_vulkan_renderer_get_type (void) G_GNUC_CONST;
GskVulkanImage * gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
GdkTexture *texture,
GskVulkanUploader *uploader);
-16
View File
@@ -42,13 +42,6 @@ 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,
@@ -68,10 +61,6 @@ 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,
@@ -199,11 +188,6 @@ 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,
+8
View File
@@ -614,6 +614,7 @@ 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);
@@ -623,6 +624,13 @@ 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;
}
+2 -4
View File
@@ -243,7 +243,6 @@ gtk_notebook_page_accessible_new (GtkNotebookAccessible *notebook,
GObject *object;
AtkObject *atk_object;
GtkNotebookPageAccessible *page;
GtkNotebook *nb;
g_return_val_if_fail (GTK_IS_NOTEBOOK_ACCESSIBLE (notebook), NULL);
g_return_val_if_fail (GTK_WIDGET (child), NULL);
@@ -259,10 +258,9 @@ gtk_notebook_page_accessible_new (GtkNotebookAccessible *notebook,
atk_object->layer = ATK_LAYER_WIDGET;
atk_object_set_parent (gtk_widget_get_accessible (child), atk_object);
nb = GTK_NOTEBOOK (gtk_accessible_get_widget (page->priv->notebook));
g_signal_connect (gtk_notebook_get_page (nb, child),
"notify::tab-label",
g_signal_connect (gtk_accessible_get_widget (page->priv->notebook),
"child-notify::tab-label",
G_CALLBACK (notify_tab_label), page);
return atk_object;
-9
View File
@@ -1000,15 +1000,6 @@ gtk_css_parser_consume_url (GtkCssParser *self)
return result;
}
gboolean
gtk_css_parser_has_number (GtkCssParser *self)
{
return gtk_css_parser_has_token (self, GTK_CSS_TOKEN_SIGNED_NUMBER)
|| gtk_css_parser_has_token (self, GTK_CSS_TOKEN_SIGNLESS_NUMBER)
|| gtk_css_parser_has_token (self, GTK_CSS_TOKEN_SIGNED_INTEGER)
|| gtk_css_parser_has_token (self, GTK_CSS_TOKEN_SIGNLESS_INTEGER);
}
gboolean
gtk_css_parser_consume_number (GtkCssParser *self,
double *number)
-1
View File
@@ -118,7 +118,6 @@ gboolean gtk_css_parser_has_token (GtkCssParser
GtkCssTokenType token_type);
gboolean gtk_css_parser_has_ident (GtkCssParser *self,
const char *ident);
gboolean gtk_css_parser_has_number (GtkCssParser *self);
gboolean gtk_css_parser_has_integer (GtkCssParser *self);
gboolean gtk_css_parser_has_function (GtkCssParser *self,
const char *name);
+17 -26
View File
@@ -633,6 +633,13 @@ is_name (char c)
|| c == '-';
}
static gboolean
is_valid_escape (char c1, char c2)
{
return c1 == '\\'
&& !is_newline (c2);
}
static gboolean
is_non_printable (char c)
{
@@ -643,25 +650,6 @@ is_non_printable (char c)
|| c == 0x7F;
}
static gboolean
is_valid_escape (const char *data,
const char *end)
{
switch (end - data)
{
default:
if (is_newline (data[1]))
return FALSE;
G_GNUC_FALLTHROUGH;
case 1:
return data[0] == '\\';
case 0:
return FALSE;
}
}
static inline gsize
gtk_css_tokenizer_remaining (GtkCssTokenizer *tokenizer)
{
@@ -671,7 +659,15 @@ gtk_css_tokenizer_remaining (GtkCssTokenizer *tokenizer)
static gboolean
gtk_css_tokenizer_has_valid_escape (GtkCssTokenizer *tokenizer)
{
return is_valid_escape (tokenizer->data, tokenizer->end);
switch (gtk_css_tokenizer_remaining (tokenizer))
{
case 0:
return FALSE;
case 1:
return *tokenizer->data == '\\';
default:
return is_valid_escape (tokenizer->data[0], tokenizer->data[1]);
}
}
static gboolean
@@ -818,11 +814,7 @@ gtk_css_tokenizer_read_escape (GtkCssTokenizer *tokenizer)
if (i == 0)
{
gsize remaining = gtk_css_tokenizer_remaining (tokenizer);
if (remaining == 0)
return 0xFFFD;
value = g_utf8_get_char_validated (tokenizer->data, remaining);
value = g_utf8_get_char_validated (tokenizer->data, gtk_css_tokenizer_remaining (tokenizer));
if (value == (gunichar) -1 || value == (gunichar) -2)
value = 0;
@@ -1384,7 +1376,6 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
else
{
gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, '\\');
gtk_css_tokenizer_consume_ascii (tokenizer);
gtk_css_tokenizer_parse_error (error, "Newline may not follow '\' escape character");
return FALSE;
}
+1 -2
View File
@@ -18,7 +18,7 @@ def get_files(subdir,extension):
xml += '''
<file>theme/Adwaita/gtk.css</file>
<file alias='theme/Adwaita-dark/gtk.css'>theme/Adwaita/gtk-dark.css</file>
<file>theme/Adwaita/gtk-dark.css</file>
<file>theme/Adwaita/gtk-contained.css</file>
<file>theme/Adwaita/gtk-contained-dark.css</file>
'''
@@ -70,7 +70,6 @@ for f in get_files('inspector', '.ui'):
xml += '''
<file>inspector/logo.png</file>
<file>inspector/inspector.css</file>
<file>emoji/emoji.data</file>
</gresource>
</gresources>'''
-149
View File
@@ -21,11 +21,6 @@
#include "config.h"
#include "gtkapplication.h"
#include "gdkprofilerprivate.h"
#ifdef G_OS_UNIX
#include <gio/gunixfdlist.h>
#endif
#include <stdlib.h>
@@ -608,148 +603,6 @@ gtk_application_finalize (GObject *object)
G_OBJECT_CLASS (gtk_application_parent_class)->finalize (object);
}
#ifdef G_OS_UNIX
static const gchar org_gnome_Sysprof3_Profiler_xml[] =
"<node>"
"<interface name='org.gnome.Sysprof3.Profiler'>"
"<method name='Start'>"
"<arg type='h' name='fd' direction='in'/>"
"</method>"
"<method name='Stop'>"
"</method>"
"</interface>"
"</node>";
static GDBusInterfaceInfo *org_gnome_Sysprof3_Profiler;
static void
sysprof_profiler_method_call (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
if (strcmp (method_name, "Start") == 0)
{
GDBusMessage *message;
GUnixFDList *fd_list;
int fd = -1;
int idx;
if (gdk_profiler_is_running ())
{
g_dbus_method_invocation_return_error (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_FAILED,
"Profiler already running");
return;
}
g_variant_get (parameters, "(h)", &idx);
message = g_dbus_method_invocation_get_message (invocation);
fd_list = g_dbus_message_get_unix_fd_list (message);
if (fd_list)
fd = g_unix_fd_list_get (fd_list, idx, NULL);
gdk_profiler_start (fd);
}
else if (strcmp (method_name, "Stop") == 0)
{
if (!gdk_profiler_is_running ())
{
g_dbus_method_invocation_return_error (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_FAILED,
"Profiler not running");
return;
}
gdk_profiler_stop ();
}
else
{
g_dbus_method_invocation_return_error (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_UNKNOWN_METHOD,
"Unknown method");
return;
}
g_dbus_method_invocation_return_value (invocation, NULL);
}
static gboolean
gtk_application_dbus_register (GApplication *application,
GDBusConnection *connection,
const char *obect_path,
GError **error)
{
GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) application;
GDBusInterfaceVTable vtable = {
sysprof_profiler_method_call,
NULL,
NULL
};
if (org_gnome_Sysprof3_Profiler == NULL)
{
GDBusNodeInfo *info;
info = g_dbus_node_info_new_for_xml (org_gnome_Sysprof3_Profiler_xml, error);
if (info == NULL)
return FALSE;
org_gnome_Sysprof3_Profiler = g_dbus_node_info_lookup_interface (info, "org.gnome.Sysprof3.Profiler");
g_dbus_interface_info_ref (org_gnome_Sysprof3_Profiler);
g_dbus_node_info_unref (info);
}
dbus->profiler_id = g_dbus_connection_register_object (connection,
"/org/gtk/Profiler",
org_gnome_Sysprof3_Profiler,
&vtable,
NULL,
NULL,
error);
return TRUE;
}
static void
gtk_application_dbus_unregister (GApplication *application,
GDBusConnection *connection,
const char *obect_path)
{
GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) application;
g_dbus_connection_unregister_object (connection, dbus->profiler_id);
}
#else
static gboolean
gtk_application_dbus_register (GApplication *application,
GDBusConnection *connection,
const char *obect_path,
GError **error)
{
return TRUE;
}
static void
gtk_application_dbus_unregister (GApplication *application,
GDBusConnection *connection,
const char *obect_path)
{
}
#endif
static void
gtk_application_class_init (GtkApplicationClass *class)
{
@@ -766,8 +619,6 @@ gtk_application_class_init (GtkApplicationClass *class)
application_class->after_emit = gtk_application_after_emit;
application_class->startup = gtk_application_startup;
application_class->shutdown = gtk_application_shutdown;
application_class->dbus_register = gtk_application_dbus_register;
application_class->dbus_unregister = gtk_application_dbus_unregister;
class->window_added = gtk_application_window_added;
class->window_removed = gtk_application_window_removed;
-1
View File
@@ -127,7 +127,6 @@ typedef struct
gchar *menubar_path;
guint menubar_id;
guint profiler_id;
/* Session management... */
GDBusProxy *sm_proxy;
+6 -6
View File
@@ -432,7 +432,7 @@ add_action_widgets (GtkAssistant *assistant)
if (has_default)
{
gtk_window_set_default_widget (GTK_WINDOW (assistant), child);
gtk_widget_grab_default (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_window_set_default_widget (GTK_WINDOW (assistant), priv->forward);
gtk_widget_grab_default (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_window_set_default_widget (GTK_WINDOW (assistant), priv->apply);
gtk_widget_grab_default (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_window_set_default_widget (GTK_WINDOW (assistant), priv->forward);
gtk_widget_grab_default (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_window_set_default_widget (GTK_WINDOW (assistant), priv->close);
gtk_widget_grab_default (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_window_set_default_widget (GTK_WINDOW (assistant), priv->forward);
gtk_widget_grab_default (priv->forward);
gtk_widget_show (priv->back);
gtk_widget_hide (priv->apply);
gtk_widget_hide (priv->close);
+3 -1
View File
@@ -161,7 +161,6 @@ gtk_box_class_init (GtkBoxClass *class)
g_object_class_install_properties (object_class, LAST_PROP, props);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_FILLER);
gtk_widget_class_set_css_name (widget_class, I_("box"));
}
@@ -345,9 +344,12 @@ static void
gtk_box_init (GtkBox *box)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkLayoutManager *box_layout = gtk_box_layout_new (GTK_ORIENTATION_HORIZONTAL);
gtk_widget_set_has_surface (GTK_WIDGET (box), FALSE);
gtk_widget_set_layout_manager (GTK_WIDGET (box), box_layout);
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (box));
}
-39
View File
@@ -766,14 +766,6 @@ 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)
{
@@ -782,14 +774,6 @@ 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)
@@ -806,14 +790,6 @@ 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)
{
@@ -822,13 +798,6 @@ 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)
@@ -844,14 +813,6 @@ 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
View File
@@ -1094,7 +1094,7 @@ gtk_builder_add_from_file (GtkBuilder *builder,
priv->resource_prefix = NULL;
_gtk_builder_parser_parse_buffer (builder, filename,
buffer, (gssize)length,
buffer, 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, (gssize)length,
buffer, length,
object_ids,
&tmp_error);
@@ -1198,7 +1198,7 @@ gtk_builder_extend_with_template (GtkBuilder *builder,
GtkWidget *widget,
GType template_type,
const gchar *buffer,
gssize length,
gsize 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 %FALSE will be returned and @error will be assigned a
* Upon errors 0 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,
gssize length,
gsize 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 %FALSE will be returned and @error will be assigned a
* Upon errors 0 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,
gssize length,
gsize length,
gchar **object_ids,
GError **error)
{
+3 -3
View File
@@ -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,
gssize length,
gsize 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,
gssize length,
gsize 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,
gssize length,
gsize length,
GError **error);
G_END_DECLS
+1 -1
View File
@@ -1230,7 +1230,7 @@ void
_gtk_builder_parser_parse_buffer (GtkBuilder *builder,
const gchar *filename,
const gchar *buffer,
gssize length,
gsize length,
gchar **requested_objs,
GError **error)
{
+1 -1
View File
@@ -135,7 +135,7 @@ typedef GType (*GTypeGetFunc) (void);
void _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
const gchar *filename,
const gchar *buffer,
gssize length,
gsize length,
gchar **requested_objs,
GError **error);
GObject * _gtk_builder_construct (GtkBuilder *builder,
+15
View File
@@ -129,6 +129,8 @@ 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);
@@ -202,6 +204,7 @@ 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;
@@ -920,6 +923,18 @@ 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)
+11
View File
@@ -153,6 +153,16 @@ 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,
@@ -183,6 +193,7 @@ 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;
+86 -62
View File
@@ -61,12 +61,11 @@
* In addition, certain files will be read when GTK+ is initialized. First, the
* file `$XDG_CONFIG_HOME/gtk-4.0/gtk.css` is loaded if it exists. Then, GTK+
* loads the first existing file among
* `XDG_DATA_HOME/themes/THEME/gtk-VERSION/gtk-VARIANT.css`,
* `$HOME/.themes/THEME/gtk-VERSION/gtk-VARIANT.css`,
* `$XDG_DATA_DIRS/themes/THEME/gtk-VERSION/gtk-VARIANT.css` and
* `DATADIR/share/themes/THEME/gtk-VERSION/gtk-VARIANT.css`, where `THEME` is the name of
* the current theme (see the #GtkSettings:gtk-theme-name setting),
* VARIANT is the variant to load (see the #GtkSettings:gtk-application-prefer-dark-theme setting), `DATADIR`
* `XDG_DATA_HOME/themes/THEME/gtk-VERSION/gtk.css`,
* `$HOME/.themes/THEME/gtk-VERSION/gtk.css`,
* `$XDG_DATA_DIRS/themes/THEME/gtk-VERSION/gtk.css` and
* `DATADIR/share/themes/THEME/gtk-VERSION/gtk.css`, where `THEME` is the name of
* the current theme (see the #GtkSettings:gtk-theme-name setting), `DATADIR`
* is the prefix configured when GTK+ was compiled (unless overridden by the
* `GTK_DATA_PREFIX` environment variable), and `VERSION` is the GTK+ version number.
* If no file is found for the current version, GTK+ tries older versions all the
@@ -117,6 +116,7 @@ struct _GtkCssProviderPrivate
GArray *rulesets;
GtkCssSelectorTree *tree;
GResource *resource;
gchar *path;
};
enum {
@@ -601,6 +601,8 @@ gtk_css_provider_finalize (GObject *object)
priv->resource = NULL;
}
g_free (priv->path);
G_OBJECT_CLASS (gtk_css_provider_parent_class)->finalize (object);
}
@@ -650,6 +652,12 @@ gtk_css_provider_reset (GtkCssProvider *css_provider)
priv->resource = NULL;
}
if (priv->path)
{
g_free (priv->path);
priv->path = NULL;
}
g_hash_table_remove_all (priv->symbolic_colors);
g_hash_table_remove_all (priv->keyframes);
@@ -1226,6 +1234,17 @@ _gtk_get_theme_dir (void)
return g_build_filename (var, "share", "themes", NULL);
}
/* Return the path that this providers gtk.css was loaded from,
* if it is part of a theme, otherwise NULL.
*/
const gchar *
_gtk_css_provider_get_theme_dir (GtkCssProvider *provider)
{
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (provider);
return priv->path;
}
#if (GTK_MINOR_VERSION % 2)
#define MINOR (GTK_MINOR_VERSION + 1)
#else
@@ -1234,16 +1253,17 @@ _gtk_get_theme_dir (void)
/*
* Look for
* $dir/$subdir/gtk-4.16/gtk.css
* $dir/$subdir/gtk-4.14/gtk.css
* $dir/$subdir/gtk-4.16/gtk-$variant.css
* $dir/$subdir/gtk-4.14/gtk-$variant.css
* ...
* $dir/$subdir/gtk-4.0/gtk.css
* $dir/$subdir/gtk-4.0/gtk-$variant.css
* and return the first found file.
*/
static gchar *
_gtk_css_find_theme_dir (const gchar *dir,
const gchar *subdir,
const gchar *name)
const gchar *name,
const gchar *variant)
{
gchar *file;
gchar *base;
@@ -1251,7 +1271,10 @@ _gtk_css_find_theme_dir (const gchar *dir,
gint i;
gchar *path;
file = g_strdup ("gtk.css");
if (variant)
file = g_strconcat ("gtk-", variant, ".css", NULL);
else
file = g_strdup ("gtk.css");
if (subdir)
base = g_build_filename (dir, subdir, name, NULL);
@@ -1260,6 +1283,9 @@ _gtk_css_find_theme_dir (const gchar *dir,
for (i = MINOR; i >= 0; i = i - 2)
{
if (i < 14)
i = 0;
subsubdir = g_strdup_printf ("gtk-4.%d", i);
path = g_build_filename (base, subsubdir, file, NULL);
g_free (subsubdir);
@@ -1280,7 +1306,8 @@ _gtk_css_find_theme_dir (const gchar *dir,
#undef MINOR
static gchar *
_gtk_css_find_theme (const gchar *name)
_gtk_css_find_theme (const gchar *name,
const gchar *variant)
{
gchar *path;
const char *const *dirs;
@@ -1288,12 +1315,12 @@ _gtk_css_find_theme (const gchar *name)
char *dir;
/* First look in the user's data directory */
path = _gtk_css_find_theme_dir (g_get_user_data_dir (), "themes", name);
path = _gtk_css_find_theme_dir (g_get_user_data_dir (), "themes", name, variant);
if (path)
return path;
/* Next look in the user's home directory */
path = _gtk_css_find_theme_dir (g_get_home_dir (), ".themes", name);
path = _gtk_css_find_theme_dir (g_get_home_dir (), ".themes", name, variant);
if (path)
return path;
@@ -1301,42 +1328,62 @@ _gtk_css_find_theme (const gchar *name)
dirs = g_get_system_data_dirs ();
for (i = 0; dirs[i]; i++)
{
path = _gtk_css_find_theme_dir (dirs[i], "themes", name);
path = _gtk_css_find_theme_dir (dirs[i], "themes", name, variant);
if (path)
return path;
}
/* Finally, try in the default theme directory */
dir = _gtk_get_theme_dir ();
path = _gtk_css_find_theme_dir (dir, NULL, name);
path = _gtk_css_find_theme_dir (dir, NULL, name, variant);
g_free (dir);
return path;
}
static gboolean
gtk_css_provider_load_theme (GtkCssProvider *provider,
const gchar *name)
/**
* gtk_css_provider_load_named:
* @provider: a #GtkCssProvider
* @name: A theme name
* @variant: (allow-none): variant to load, for example, "dark", or
* %NULL for the default
*
* Loads a theme from the usual theme paths. The actual process of
* finding the theme might change between releases, but it is
* guaranteed that this function uses the same mechanism to load the
* theme that GTK uses for loading its own theme.
**/
void
gtk_css_provider_load_named (GtkCssProvider *provider,
const gchar *name,
const gchar *variant)
{
gchar *path;
gchar *resource_path;
g_return_if_fail (GTK_IS_CSS_PROVIDER (provider));
g_return_if_fail (name != NULL);
gtk_css_provider_reset (provider);
/* try loading the resource for the theme. This is mostly meant for built-in
* themes.
*/
resource_path = g_strconcat ("/org/gtk/libgtk/theme/", name, "/gtk.css", NULL);
if (variant)
resource_path = g_strdup_printf ("/org/gtk/libgtk/theme/%s/gtk-%s.css", name, variant);
else
resource_path = g_strdup_printf ("/org/gtk/libgtk/theme/%s/gtk.css", name);
if (g_resources_get_info (resource_path, 0, NULL, NULL, NULL))
{
gtk_css_provider_load_from_resource (provider, resource_path);
g_free (resource_path);
return TRUE;
return;
}
g_free (resource_path);
/* Next try looking for files in the various theme directories. */
path = _gtk_css_find_theme (name);
path = _gtk_css_find_theme (name, variant);
if (path)
{
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (provider);
@@ -1355,49 +1402,26 @@ gtk_css_provider_load_theme (GtkCssProvider *provider,
/* Only set this after load, as load_from_path will clear it */
priv->resource = resource;
priv->path = dir;
g_free (dir);
g_free (path);
return TRUE;
}
else
{
/* Things failed! Fall back! Fall back! */
return FALSE;
}
/**
* gtk_css_provider_load_named:
* @provider: a #GtkCssProvider
* @name: A theme name
* @fallback: (allow-none): Fallback theme to load if @name is
* not available, or %NULL for the default
*
* Loads a theme from the usual theme paths. The actual process of
* finding the theme might change between releases, but it is
* guaranteed that this function uses the same mechanism to load the
* theme that GTK uses for loading its own theme.
*
* The @fallback can be used to try loading THEME-dark,
* falling back to THEME.
**/
void
gtk_css_provider_load_named (GtkCssProvider *provider,
const gchar *name,
const gchar *fallback)
{
g_return_if_fail (GTK_IS_CSS_PROVIDER (provider));
g_return_if_fail (name != NULL);
gtk_css_provider_reset (provider);
if (gtk_css_provider_load_theme (provider, name))
return;
if (fallback &&
gtk_css_provider_load_theme (provider, fallback))
return;
gtk_css_provider_load_theme (provider, DEFAULT_THEME_NAME);
if (variant)
{
/* If there was a variant, try without */
gtk_css_provider_load_named (provider, name, NULL);
}
else
{
/* Worst case, fall back to the default */
g_return_if_fail (!g_str_equal (name, DEFAULT_THEME_NAME)); /* infloop protection */
gtk_css_provider_load_named (provider, DEFAULT_THEME_NAME, NULL);
}
}
}
static int
+24 -1
View File
@@ -30,6 +30,29 @@ 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;
@@ -80,7 +103,7 @@ void gtk_css_provider_load_from_resource (GtkCssProvider *css_provid
GDK_AVAILABLE_IN_ALL
void gtk_css_provider_load_named (GtkCssProvider *provider,
const char *name,
const char *fallback);
const char *variant);
G_END_DECLS

Some files were not shown because too many files have changed in this diff Show More