Compare commits
114 Commits
4.1.1
..
path-stroke
| Author | SHA1 | Date | |
|---|---|---|---|
| 226f556cf8 | |||
| be7fead1fb | |||
| b871c2a3cb | |||
| 7c67a9c76a | |||
| 427e185bcf | |||
| 30552e9988 | |||
| 08d8d6c029 | |||
| 61a84956d4 | |||
| e44780923a | |||
| dd1a2e0396 | |||
| 0100c33b71 | |||
| 8b8197a662 | |||
| e293f10fa1 | |||
| 3a4c3c3d8c | |||
| 944735071e | |||
| 91356de96a | |||
| 3f29c50800 | |||
| 59b1f9e7b1 | |||
| dd3cf83a35 | |||
| 7f8a9e5543 | |||
| 8523c6cb2d | |||
| 49b25424c5 | |||
| db2046cb67 | |||
| 61264165ff | |||
| 7b3d283fc0 | |||
| 44ffed0283 | |||
| e91ec1f26f | |||
| eace55daa6 | |||
| 097e58558b | |||
| f0acb0f073 | |||
| b779ba19ca | |||
| aa0f1ce956 | |||
| e9d01c1a63 | |||
| e235392894 | |||
| 73904f3034 | |||
| c2ed71af7a | |||
| aa2f6345c8 | |||
| cef1bc9098 | |||
| 828ccc51d9 | |||
| 8397d10c20 | |||
| 78d06e58d0 | |||
| a5e13cc96b | |||
| 776dc54c8a | |||
| ee6879fba8 | |||
| 14f9395476 | |||
| 1349cf2454 | |||
| d47ebd388c | |||
| 61214221b3 | |||
| 7eb4ed8f86 | |||
| 92b472fec1 | |||
| 7a6b008479 | |||
| d8c26172a5 | |||
| da835321a5 | |||
| 30635d1cac | |||
| a60b72ba58 | |||
| 36347892d8 | |||
| 924f0bc2c5 | |||
| 23c5318de1 | |||
| 678405bd22 | |||
| 946b76881b | |||
| 061683344f | |||
| af9a85616d | |||
| 0f332de3d3 | |||
| 15e8f2bacc | |||
| 25f9eadb0d | |||
| ced2959cdd | |||
| 3c363f00d5 | |||
| a9ad37ed89 | |||
| acdf04287d | |||
| 34725c1207 | |||
| cb10cf07e6 | |||
| a7ba2bde86 | |||
| 87b3cb1df8 | |||
| 2478963cbb | |||
| abbbaef7e8 | |||
| 69177416a0 | |||
| ff47bfdbcf | |||
| 120e449bdd | |||
| 237c37f6c2 | |||
| 683729c388 | |||
| 9fe71e7dae | |||
| c74970e6c1 | |||
| 5225d01504 | |||
| 916d950069 | |||
| 76d6fed248 | |||
| 7ff6235ae6 | |||
| 9b957c26cb | |||
| 445b2382e6 | |||
| 790a4201c3 | |||
| 00b9af65b5 | |||
| f7c367338c | |||
| 5d69887618 | |||
| b658c26a3e | |||
| e4c147cf2f | |||
| fc2c6f1566 | |||
| b0d6130905 | |||
| a0b9238a15 | |||
| 801c63494c | |||
| d2cfe74140 | |||
| a3ac003546 | |||
| 483a4773cd | |||
| c82ad0214e | |||
| 207feeb7a9 | |||
| 9a2e4ac9a9 | |||
| 2bd3aa3cbe | |||
| 118e41f432 | |||
| 2d7897a769 | |||
| c279e1aa1e | |||
| 3c91d0be91 | |||
| e7bbed54b5 | |||
| 4eb7d68970 | |||
| 98337f7115 | |||
| 08ee6c7acf | |||
| c815496fe3 |
@@ -24,7 +24,7 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v28"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v25"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v25"
|
||||
|
||||
@@ -43,7 +43,6 @@ style-check-diff:
|
||||
- .gitlab-ci/run-style-check-diff.sh
|
||||
|
||||
.build-fedora-default:
|
||||
extends: .only-default
|
||||
image: $FEDORA_IMAGE
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -122,7 +121,6 @@ installed-tests:
|
||||
|
||||
|
||||
.mingw-defaults:
|
||||
extends: .only-default
|
||||
stage: build
|
||||
tags:
|
||||
- win32-ps
|
||||
@@ -146,32 +144,6 @@ msys2-mingw64:
|
||||
MSYSTEM: "MINGW64"
|
||||
CHERE_INVOKING: "yes"
|
||||
|
||||
macos:
|
||||
extends: .only-default
|
||||
only:
|
||||
- branches@GNOME/gtk
|
||||
stage: build
|
||||
tags:
|
||||
- macos
|
||||
needs: []
|
||||
before_script:
|
||||
- bash .gitlab-ci/show-execution-environment.sh
|
||||
- pip3 install --user meson==0.56
|
||||
- pip3 install --user ninja
|
||||
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
|
||||
- export MESON_FORCE_BACKTRACE=1
|
||||
script:
|
||||
- meson -Dx11-backend=false
|
||||
-Dintrospection=disabled
|
||||
-Dcpp_std=c++11
|
||||
-Dpixman:tests=disabled
|
||||
_build
|
||||
- ninja -C _build
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
|
||||
.flatpak-defaults:
|
||||
image: $FLATPAK_IMAGE
|
||||
stage: flatpak
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM fedora:33
|
||||
FROM fedora:31
|
||||
|
||||
RUN dnf -y install \
|
||||
adwaita-icon-theme \
|
||||
@@ -65,8 +65,7 @@ RUN dnf -y install \
|
||||
libxslt \
|
||||
mesa-dri-drivers \
|
||||
mesa-libEGL-devel \
|
||||
mesa-libGLES-devel \
|
||||
meson \
|
||||
mesa-libwayland-egl-devel \
|
||||
ninja-build \
|
||||
pango-devel \
|
||||
pcre-devel \
|
||||
@@ -87,3 +86,6 @@ RUN dnf -y install \
|
||||
which \
|
||||
xorg-x11-server-Xvfb \
|
||||
&& dnf clean all
|
||||
|
||||
RUN pip3 install meson==0.55.3
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v28
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v25
|
||||
|
||||
# Enable sudo for wheel users
|
||||
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers
|
||||
|
||||
@@ -8,8 +8,7 @@ builddir=$1
|
||||
backend=$2
|
||||
|
||||
# Ignore memory leaks lower in dependencies
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0
|
||||
export G_SLICE=always-malloc
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp
|
||||
|
||||
case "${backend}" in
|
||||
x11)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eux -o pipefail
|
||||
|
||||
xcodebuild -version || :
|
||||
xcodebuild -showsdks || :
|
||||
|
||||
system_profiler SPSoftwareDataType || :
|
||||
@@ -1,13 +1,4 @@
|
||||
<!--
|
||||
Please, read the CONTRIBUTING.md guide on how to file a new issue.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
|
||||
-->
|
||||
## Steps to reproduce
|
||||
<!--
|
||||
Please, explain the sequence of actions necessary to reproduce the
|
||||
bug
|
||||
-->
|
||||
|
||||
1. ...
|
||||
2. ...
|
||||
@@ -41,8 +32,5 @@
|
||||
## Additional information
|
||||
<!--
|
||||
- Screenshots or screen recordings are useful for visual errors
|
||||
- Attaching a screenshot or a video without explaining the current
|
||||
behavior and the actions necessary to reproduce the bug will lead
|
||||
to the bug being closed
|
||||
- Please report any warning or message printed on the terminal
|
||||
-->
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
<!--
|
||||
Please, read the CONTRIBUTING.md guide on how to file a new issue.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
## Steps to reproduce
|
||||
<!--
|
||||
Please, explain the sequence of actions necessary to reproduce the
|
||||
crash
|
||||
-->
|
||||
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
@@ -63,6 +63,36 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libsass",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/lazka/libsass.git",
|
||||
"branch" : "meson"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/lazka/sassc.git",
|
||||
"branch" : "meson"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
@@ -70,9 +100,7 @@
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Denable_vulkan=no",
|
||||
"-Dsassc=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Dprofile=devel"
|
||||
"-Dbuildtype=debugoptimized"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
|
||||
@@ -63,6 +63,36 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libsass",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/lazka/libsass.git",
|
||||
"branch" : "meson"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/lazka/sassc.git",
|
||||
"branch" : "meson"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
@@ -70,9 +100,7 @@
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Denable_vulkan=no",
|
||||
"-Dsassc=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Dprofile=devel"
|
||||
"-Dbuildtype=debugoptimized"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
|
||||
@@ -63,6 +63,36 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libsass",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/lazka/libsass.git",
|
||||
"branch" : "meson"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/lazka/sassc.git",
|
||||
"branch" : "meson"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
@@ -70,9 +100,7 @@
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Denable_vulkan=no",
|
||||
"-Dsassc=disabled",
|
||||
"-Dbuildtype=debugoptimized",
|
||||
"-Dprofile=devel"
|
||||
"-Dbuildtype=debugoptimized"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
from pathlib import PurePath
|
||||
import subprocess
|
||||
|
||||
stylesheets = [ 'gtk/theme/Adwaita/Adwaita.css',
|
||||
'gtk/theme/Adwaita/Adwaita-dark.css',
|
||||
'gtk/theme/HighContrast/HighContrast.css',
|
||||
'gtk/theme/HighContrast/HighContrast-dark.css' ]
|
||||
|
||||
sourceroot = os.environ.get('MESON_SOURCE_ROOT')
|
||||
distroot = os.environ.get('MESON_DIST_ROOT')
|
||||
|
||||
for stylesheet in stylesheets:
|
||||
stylesheet_path = PurePath(stylesheet)
|
||||
src = PurePath(sourceroot, stylesheet_path.with_suffix('.scss'))
|
||||
dst = PurePath(distroot, stylesheet_path)
|
||||
subprocess.call(['sassc', '-a', '-M', '-t', 'compact', src, dst])
|
||||
@@ -98,9 +98,6 @@ create_page1 (GtkWidget *assistant)
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
|
||||
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
|
||||
-1);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
|
||||
gtk_box_append (GTK_BOX (box), entry);
|
||||
|
||||
@@ -319,6 +319,9 @@
|
||||
<file>paintable_svg.c</file>
|
||||
<file>panes.c</file>
|
||||
<file>password_entry.c</file>
|
||||
<file>path_fill.c</file>
|
||||
<file>path_maze.c</file>
|
||||
<file>path_text.c</file>
|
||||
<file>peg_solitaire.c</file>
|
||||
<file>pickers.c</file>
|
||||
<file>printing.c</file>
|
||||
@@ -403,6 +406,9 @@
|
||||
<gresource prefix="/fontrendering">
|
||||
<file>fontrendering.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/path_text">
|
||||
<file>path_text.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/Demo4">
|
||||
<file>icons/16x16/actions/application-exit.png</file>
|
||||
<file>icons/16x16/actions/document-new.png</file>
|
||||
|
||||
@@ -119,12 +119,13 @@ create_label (void)
|
||||
static GtkWidget *
|
||||
create_video (void)
|
||||
{
|
||||
GtkWidget *w = gtk_video_new ();
|
||||
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
GtkWidget *w = gtk_picture_new_for_paintable (GDK_PAINTABLE (stream));
|
||||
|
||||
gtk_widget_set_size_request (w, 64, 64);
|
||||
gtk_video_set_loop (GTK_VIDEO (w), TRUE);
|
||||
gtk_video_set_autoplay (GTK_VIDEO (w), TRUE);
|
||||
gtk_video_set_resource (GTK_VIDEO (w), "/images/gtk-logo.webm");
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
g_object_unref (stream);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
@@ -787,8 +787,6 @@ gtk_gears_realize (GtkWidget *widget)
|
||||
glLinkProgram(program);
|
||||
glGetProgramInfoLog(program, sizeof msg, NULL, msg);
|
||||
g_debug ("program info: %s\n", msg);
|
||||
glDetachShader (program, v);
|
||||
glDetachShader (program, f);
|
||||
glDeleteShader (v);
|
||||
glDeleteShader (f);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ create_application_list (void)
|
||||
}
|
||||
|
||||
/* This is the function we use for setting up new listitems to display.
|
||||
* We add just an #GtkImage and a #GtkLabel here to display the application's
|
||||
* We add just an #GtkImage and a #GtkKabel here to display the application's
|
||||
* icon and name, as this is just a simple demo.
|
||||
*/
|
||||
static void
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include "demos.h"
|
||||
#include "fontify.h"
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
static GtkWidget *info_view;
|
||||
static GtkWidget *source_view;
|
||||
|
||||
@@ -198,20 +196,16 @@ activate_about (GSimpleAction *action,
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (s, "\nA link can appear here: <http://www.gtk.org>");
|
||||
|
||||
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
|
||||
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", g_strcmp0 (PROFILE, "devel") == 0
|
||||
? "GTK Demo (Development)"
|
||||
: "GTK Demo",
|
||||
"program-name", "GTK Demo",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2021 The GTK Team",
|
||||
"copyright", "© 1997—2020 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK widgets",
|
||||
@@ -907,9 +901,6 @@ activate (GApplication *app)
|
||||
window = (GtkWidget *)gtk_builder_get_object (builder, "window");
|
||||
gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (window));
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (window, "devel");
|
||||
|
||||
action = g_simple_action_new ("run", NULL);
|
||||
g_signal_connect (action, "activate", G_CALLBACK (activate_run), window);
|
||||
g_action_map_add_action (G_ACTION_MAP (window), G_ACTION (action));
|
||||
@@ -1052,10 +1043,10 @@ out:
|
||||
static void
|
||||
print_version (void)
|
||||
{
|
||||
g_print ("gtk4-demo %s%s%s\n",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "");
|
||||
g_print ("gtk4-demo %d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -68,6 +68,9 @@ demos = files([
|
||||
'paintable_mediastream.c',
|
||||
'panes.c',
|
||||
'password_entry.c',
|
||||
'path_fill.c',
|
||||
'path_maze.c',
|
||||
'path_text.c',
|
||||
'peg_solitaire.c',
|
||||
'pickers.c',
|
||||
'printing.c',
|
||||
@@ -167,8 +170,6 @@ foreach flag: common_cflags
|
||||
endif
|
||||
endforeach
|
||||
|
||||
gtkdemo_deps += [ demo_conf_h ]
|
||||
|
||||
executable('gtk4-demo',
|
||||
sources: [demos, demos_h, extra_demo_sources, gtkdemo_resources],
|
||||
c_args: gtkdemo_args + demo_cflags,
|
||||
|
||||
@@ -0,0 +1,359 @@
|
||||
/* Path/Fill
|
||||
*
|
||||
* This demo shows how to use PangoCairo to draw text with more than
|
||||
* just a single color.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "paintable.h"
|
||||
#include "gsk/gskpathdashprivate.h"
|
||||
|
||||
#define GTK_TYPE_PATH_PAINTABLE (gtk_path_paintable_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkPathPaintable, gtk_path_paintable, GTK, PATH_PAINTABLE, GObject)
|
||||
|
||||
struct _GtkPathPaintable
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
GskPath *path;
|
||||
GdkPaintable *background;
|
||||
};
|
||||
|
||||
struct _GtkPathPaintableClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static int
|
||||
gtk_path_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
|
||||
|
||||
if (self->background)
|
||||
return MAX (gdk_paintable_get_intrinsic_width (self->background), self->width);
|
||||
else
|
||||
return self->width;
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_path_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
|
||||
|
||||
if (self->background)
|
||||
return MAX (gdk_paintable_get_intrinsic_height (self->background), self->height);
|
||||
else
|
||||
return self->height;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
|
||||
|
||||
#if 0
|
||||
gtk_snapshot_push_fill (snapshot, self->path, GSK_FILL_RULE_WINDING);
|
||||
#else
|
||||
GskStroke *stroke = gsk_stroke_new (2.0);
|
||||
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
|
||||
gsk_stroke_free (stroke);
|
||||
#endif
|
||||
|
||||
if (self->background)
|
||||
{
|
||||
gdk_paintable_snapshot (self->background, snapshot, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_snapshot_append_linear_gradient (snapshot,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
&GRAPHENE_POINT_INIT (0, 0),
|
||||
&GRAPHENE_POINT_INIT (width, height),
|
||||
(GskColorStop[8]) {
|
||||
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
|
||||
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
|
||||
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
|
||||
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
|
||||
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
|
||||
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
|
||||
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
|
||||
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
|
||||
},
|
||||
8);
|
||||
}
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
gtk_path_paintable_get_flags (GdkPaintable *paintable)
|
||||
{
|
||||
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
|
||||
|
||||
if (self->background)
|
||||
return gdk_paintable_get_flags (self->background);
|
||||
else
|
||||
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_paintable_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->get_intrinsic_width = gtk_path_paintable_get_intrinsic_width;
|
||||
iface->get_intrinsic_height = gtk_path_paintable_get_intrinsic_height;
|
||||
iface->snapshot = gtk_path_paintable_snapshot;
|
||||
iface->get_flags = gtk_path_paintable_get_flags;
|
||||
}
|
||||
|
||||
/* When defining the GType, we need to implement the GdkPaintable interface */
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkPathPaintable, gtk_path_paintable, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gtk_path_paintable_paintable_init))
|
||||
|
||||
/* Here's the boilerplate for the GObject declaration.
|
||||
* We don't need to do anything special here, because we keep no
|
||||
* data of our own.
|
||||
*/
|
||||
static void
|
||||
gtk_path_paintable_class_init (GtkPathPaintableClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_paintable_init (GtkPathPaintable *self)
|
||||
{
|
||||
}
|
||||
|
||||
/* And finally, we add a simple constructor.
|
||||
* It is declared in the header so that the other examples
|
||||
* can use it.
|
||||
*/
|
||||
GdkPaintable *
|
||||
gtk_path_paintable_new (GskPath *path,
|
||||
GdkPaintable *background,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GtkPathPaintable *self;
|
||||
|
||||
self = g_object_new (GTK_TYPE_PATH_PAINTABLE, NULL);
|
||||
self->path = path;
|
||||
self->background = background;
|
||||
if (self->background)
|
||||
{
|
||||
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
|
||||
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
|
||||
}
|
||||
self->width = width;
|
||||
self->height = height;
|
||||
|
||||
return GDK_PAINTABLE (self);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_path_paintable_set_path (GtkPathPaintable *self,
|
||||
GskPath *path)
|
||||
{
|
||||
g_clear_pointer (&self->path, gsk_path_unref);
|
||||
self->path = gsk_path_ref (path);
|
||||
|
||||
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
|
||||
}
|
||||
|
||||
static GskPath *
|
||||
create_hexagon (GtkWidget *widget)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
|
||||
gsk_path_builder_move_to (builder, 120, 0);
|
||||
gsk_path_builder_line_to (builder, 360, 0);
|
||||
gsk_path_builder_line_to (builder, 480, 208);
|
||||
gsk_path_builder_line_to (builder, 360, 416);
|
||||
gsk_path_builder_line_to (builder, 120, 416);
|
||||
gsk_path_builder_line_to (builder, 0, 208);
|
||||
gsk_path_builder_close (builder);
|
||||
|
||||
return gsk_path_builder_free_to_path (builder);
|
||||
}
|
||||
|
||||
static GskPath *
|
||||
create_path_from_text (GtkWidget *widget)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
cairo_path_t *path;
|
||||
PangoLayout *layout;
|
||||
PangoFontDescription *desc;
|
||||
GskPath *result;
|
||||
|
||||
surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, "Pango power!\nPango power!\nPango power!");
|
||||
desc = pango_font_description_from_string ("sans bold 36");
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_font_description_free (desc);
|
||||
|
||||
pango_cairo_layout_path (cr, layout);
|
||||
path = cairo_copy_path_flat (cr);
|
||||
result = gsk_path_new_from_cairo (path);
|
||||
|
||||
cairo_path_destroy (path);
|
||||
g_object_unref (layout);
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
build_path (GskPathOperation op,
|
||||
const graphene_point_t *pts,
|
||||
gsize n_pts,
|
||||
float weight,
|
||||
gpointer user_data)
|
||||
{
|
||||
GskPathBuilder *builder = user_data;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case GSK_PATH_MOVE:
|
||||
gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
|
||||
break;
|
||||
|
||||
case GSK_PATH_CLOSE:
|
||||
gsk_path_builder_close (builder);
|
||||
break;
|
||||
|
||||
case GSK_PATH_LINE:
|
||||
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
|
||||
break;
|
||||
|
||||
case GSK_PATH_CURVE:
|
||||
gsk_path_builder_curve_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
|
||||
break;
|
||||
|
||||
case GSK_PATH_CONIC:
|
||||
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, weight);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
update_path (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer measure)
|
||||
{
|
||||
float progress = gdk_frame_clock_get_frame_time (frame_clock) % (60 * G_USEC_PER_SEC) / (float) (30 * G_USEC_PER_SEC);
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path;
|
||||
graphene_point_t pos;
|
||||
graphene_vec2_t tangent;
|
||||
GskStroke *stroke;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_segment (builder,
|
||||
measure,
|
||||
#if 1
|
||||
0.0, gsk_path_measure_get_length (measure));
|
||||
#else
|
||||
progress > 1 ? (progress - 1) * gsk_path_measure_get_length (measure) : 0.0,
|
||||
(progress < 1 ? progress : 1.0) * gsk_path_measure_get_length (measure));
|
||||
#endif
|
||||
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
stroke = gsk_stroke_new (1);
|
||||
gsk_stroke_set_dash (stroke, (float[2]) { 10, 5 }, 2);
|
||||
gsk_stroke_set_dash_offset (stroke, - (gdk_frame_clock_get_frame_time (frame_clock) % G_USEC_PER_SEC) * 15. / G_USEC_PER_SEC);
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_dash (path, stroke, 0.2, build_path, builder);
|
||||
gsk_path_unref (path);
|
||||
|
||||
gsk_path_measure_get_point (measure,
|
||||
(progress > 1 ? (progress - 1) : progress) * gsk_path_measure_get_length (measure),
|
||||
&pos,
|
||||
&tangent);
|
||||
gsk_path_builder_move_to (builder, pos.x + 5 * graphene_vec2_get_x (&tangent), pos.y + 5 * graphene_vec2_get_y (&tangent));
|
||||
gsk_path_builder_line_to (builder, pos.x + 3 * graphene_vec2_get_y (&tangent), pos.y + 3 * graphene_vec2_get_x (&tangent));
|
||||
gsk_path_builder_line_to (builder, pos.x - 3 * graphene_vec2_get_y (&tangent), pos.y - 3 * graphene_vec2_get_x (&tangent));
|
||||
gsk_path_builder_close (builder);
|
||||
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
gtk_path_paintable_set_path (GTK_PATH_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget))),
|
||||
path);
|
||||
gsk_path_unref (path);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_path_fill (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
GdkPaintable *paintable;
|
||||
GtkMediaStream *stream;
|
||||
GskPath *path;
|
||||
graphene_rect_t bounds;
|
||||
GskPathMeasure *measure;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Path Fill");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
#if 0
|
||||
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
#else
|
||||
stream = gtk_nuclear_media_stream_new ();
|
||||
#endif
|
||||
gtk_media_stream_play (stream);
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
|
||||
path = create_hexagon (window);
|
||||
path = create_path_from_text (window);
|
||||
gsk_path_get_bounds (path, &bounds);
|
||||
|
||||
paintable = gtk_path_paintable_new (path,
|
||||
GDK_PAINTABLE (stream),
|
||||
bounds.origin.x + bounds.size.width,
|
||||
bounds.origin.y + bounds.size.height);
|
||||
picture = gtk_picture_new_for_paintable (paintable);
|
||||
measure = gsk_path_measure_new (path);
|
||||
gtk_widget_add_tick_callback (picture, update_path, measure, (GDestroyNotify) gsk_path_measure_unref);
|
||||
gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (picture), FALSE);
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
|
||||
g_object_unref (paintable);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), picture);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
/* Path/Maze
|
||||
*
|
||||
* This demo shows how to use a GskPath to create a maze and use
|
||||
* gsk_path_measure_get_closest_point() to check the mouse stays
|
||||
* on the path.
|
||||
*
|
||||
* It also shows off the performance of GskPath (or not) as this
|
||||
* is a rather complex path.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "paintable.h"
|
||||
|
||||
#define MAZE_GRID_SIZE 20
|
||||
#define MAZE_STROKE_SIZE_ACTIVE (MAZE_GRID_SIZE - 4)
|
||||
#define MAZE_STROKE_SIZE_INACTIVE (MAZE_GRID_SIZE - 12)
|
||||
#define MAZE_WIDTH 31
|
||||
#define MAZE_HEIGHT 21
|
||||
|
||||
#define GTK_TYPE_MAZE (gtk_maze_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkMaze, gtk_maze, GTK, MAZE, GtkWidget)
|
||||
|
||||
struct _GtkMaze
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
GskPath *path;
|
||||
GskPathMeasure *measure;
|
||||
GdkPaintable *background;
|
||||
|
||||
gboolean active;
|
||||
};
|
||||
|
||||
struct _GtkMazeClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkMaze, gtk_maze, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
gtk_maze_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkMaze *self = GTK_MAZE (widget);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
*minimum = *natural = self->width;
|
||||
else
|
||||
*minimum = *natural = self->height;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_maze_snapshot (GtkWidget *widget,
|
||||
GdkSnapshot *snapshot)
|
||||
{
|
||||
GtkMaze *self = GTK_MAZE (widget);
|
||||
double width = gtk_widget_get_width (widget);
|
||||
double height = gtk_widget_get_height (widget);
|
||||
GskStroke *stroke;
|
||||
|
||||
stroke = gsk_stroke_new (MAZE_STROKE_SIZE_INACTIVE);
|
||||
if (self->active)
|
||||
gsk_stroke_set_line_width (stroke, MAZE_STROKE_SIZE_ACTIVE);
|
||||
gsk_stroke_set_line_join (stroke, GSK_LINE_JOIN_ROUND);
|
||||
gsk_stroke_set_line_cap (stroke, GSK_LINE_CAP_ROUND);
|
||||
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
|
||||
gsk_stroke_free (stroke);
|
||||
|
||||
if (self->background)
|
||||
{
|
||||
gdk_paintable_snapshot (self->background, snapshot, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_snapshot_append_linear_gradient (snapshot,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
&GRAPHENE_POINT_INIT (0, 0),
|
||||
&GRAPHENE_POINT_INIT (width, height),
|
||||
(GskColorStop[8]) {
|
||||
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
|
||||
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
|
||||
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
|
||||
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
|
||||
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
|
||||
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
|
||||
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
|
||||
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
|
||||
},
|
||||
8);
|
||||
}
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_maze_dispose (GObject *object)
|
||||
{
|
||||
GtkMaze *self = GTK_MAZE (object);
|
||||
|
||||
g_clear_pointer (&self->path, gsk_path_unref);
|
||||
g_clear_pointer (&self->measure, gsk_path_measure_unref);
|
||||
if (self->background)
|
||||
{
|
||||
g_signal_handlers_disconnect_matched (self->background, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
|
||||
g_clear_object (&self->background);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_maze_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_maze_class_init (GtkMazeClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_maze_dispose;
|
||||
|
||||
widget_class->measure = gtk_maze_measure;
|
||||
widget_class->snapshot = gtk_maze_snapshot;
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_motion (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
GtkMaze *self)
|
||||
{
|
||||
if (!self->active)
|
||||
return;
|
||||
|
||||
if (gsk_path_measure_get_closest_point (self->measure, &GRAPHENE_POINT_INIT (x, y), NULL) <= MAZE_STROKE_SIZE_ACTIVE / 2.0f)
|
||||
return;
|
||||
|
||||
self->active = FALSE;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_leave (GtkEventControllerMotion *controller,
|
||||
GtkMaze *self)
|
||||
{
|
||||
if (!self->active)
|
||||
{
|
||||
self->active = TRUE;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_maze_init (GtkMaze *self)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
|
||||
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
self->active = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_maze_set_path (GtkMaze *self,
|
||||
GskPath *path)
|
||||
{
|
||||
g_clear_pointer (&self->path, gsk_path_unref);
|
||||
g_clear_pointer (&self->measure, gsk_path_measure_unref);
|
||||
self->path = gsk_path_ref (path);
|
||||
self->measure = gsk_path_measure_new (path);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_maze_new (GskPath *path,
|
||||
GdkPaintable *background,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GtkMaze *self;
|
||||
|
||||
self = g_object_new (GTK_TYPE_MAZE, NULL);
|
||||
|
||||
gtk_maze_set_path (self, path);
|
||||
gsk_path_unref (path);
|
||||
self->background = background;
|
||||
if (self->background)
|
||||
{
|
||||
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gtk_widget_queue_draw), self);
|
||||
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gtk_widget_queue_resize), self);
|
||||
}
|
||||
self->width = width;
|
||||
self->height = height;
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
|
||||
static void
|
||||
add_point_to_maze (GtkBitset *maze,
|
||||
GskPathBuilder *builder,
|
||||
guint x,
|
||||
guint y)
|
||||
{
|
||||
gboolean set[4] = { };
|
||||
guint dir;
|
||||
|
||||
gtk_bitset_add (maze, y * MAZE_WIDTH + x);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
set[0] = set[0] || x == 0 || gtk_bitset_contains (maze, y * MAZE_WIDTH + x - 1);
|
||||
set[1] = set[1] || y == 0 || gtk_bitset_contains (maze, (y - 1) * MAZE_WIDTH + x);
|
||||
set[2] = set[2] || x + 1 == MAZE_WIDTH || gtk_bitset_contains (maze, y * MAZE_WIDTH + x + 1);
|
||||
set[3] = set[3] || y + 1 == MAZE_HEIGHT || gtk_bitset_contains (maze, (y + 1) * MAZE_WIDTH + x);
|
||||
|
||||
if (set[0] && set[1] && set[2] && set[3])
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
dir = g_random_int_range (0, 4);
|
||||
}
|
||||
while (set[dir]);
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case 0:
|
||||
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||
gsk_path_builder_line_to (builder, (x - 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||
add_point_to_maze (maze, builder, x - 1, y);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y - 0.5) * MAZE_GRID_SIZE);
|
||||
add_point_to_maze (maze, builder, x, y - 1);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||
gsk_path_builder_line_to (builder, (x + 1.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||
add_point_to_maze (maze, builder, x + 1, y);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
|
||||
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 1.5) * MAZE_GRID_SIZE);
|
||||
add_point_to_maze (maze, builder, x, y + 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GskPath *
|
||||
create_path_for_maze (GtkWidget *widget)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
GtkBitset *maze;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
maze = gtk_bitset_new_empty ();
|
||||
/* make sure the outer lines are unreachable:
|
||||
* Set the full range, then remove the center again. */
|
||||
gtk_bitset_add_range (maze, 0, MAZE_WIDTH * MAZE_HEIGHT);
|
||||
gtk_bitset_remove_rectangle (maze, MAZE_WIDTH + 1, MAZE_WIDTH - 2, MAZE_HEIGHT - 2, MAZE_WIDTH);
|
||||
|
||||
/* Fill the maze */
|
||||
add_point_to_maze (maze, builder, MAZE_WIDTH / 2, MAZE_HEIGHT / 2);
|
||||
|
||||
/* Add start and stop lines */
|
||||
gsk_path_builder_move_to (builder, 1.5 * MAZE_GRID_SIZE, -0.5 * MAZE_GRID_SIZE);
|
||||
gsk_path_builder_line_to (builder, 1.5 * MAZE_GRID_SIZE, 1.5 * MAZE_GRID_SIZE);
|
||||
gsk_path_builder_move_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT - 1.5) * MAZE_GRID_SIZE);
|
||||
gsk_path_builder_line_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT + 0.5) * MAZE_GRID_SIZE);
|
||||
|
||||
|
||||
gtk_bitset_unref (maze);
|
||||
|
||||
return gsk_path_builder_free_to_path (builder);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_path_maze (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *maze;
|
||||
GtkMediaStream *stream;
|
||||
GskPath *path;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Follow the maze with the mouse");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
#if 0
|
||||
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
#else
|
||||
stream = gtk_nuclear_media_stream_new ();
|
||||
#endif
|
||||
gtk_media_stream_play (stream);
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
|
||||
path = create_path_for_maze (window);
|
||||
|
||||
maze = gtk_maze_new (path,
|
||||
GDK_PAINTABLE (stream),
|
||||
MAZE_WIDTH * MAZE_GRID_SIZE,
|
||||
MAZE_HEIGHT * MAZE_GRID_SIZE);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), maze);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -0,0 +1,590 @@
|
||||
/* Path/Text
|
||||
*
|
||||
* This demo shows how to use GskPath to animate a path along another path.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GTK_TYPE_PATH_WIDGET (gtk_path_widget_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkPathWidget, gtk_path_widget, GTK, PATH_WIDGET, GtkWidget)
|
||||
|
||||
#define POINT_SIZE 8
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_TEXT,
|
||||
PROP_EDITABLE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
struct _GtkPathWidget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
char *text;
|
||||
gboolean editable;
|
||||
|
||||
graphene_point_t points[4];
|
||||
|
||||
guint active_point;
|
||||
float line_closest;
|
||||
|
||||
GskPath *line_path;
|
||||
GskPathMeasure *line_measure;
|
||||
GskPath *text_path;
|
||||
|
||||
GdkPaintable *background;
|
||||
};
|
||||
|
||||
struct _GtkPathWidgetClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE (GtkPathWidget, gtk_path_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
static GskPath *
|
||||
create_path_from_text (GtkWidget *widget,
|
||||
const char *text)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
cairo_path_t *path;
|
||||
PangoLayout *layout;
|
||||
PangoFontDescription *desc;
|
||||
GskPath *result;
|
||||
|
||||
surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, text);
|
||||
desc = pango_font_description_from_string ("sans bold 36");
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_font_description_free (desc);
|
||||
|
||||
cairo_move_to (cr, 0, - pango_layout_get_baseline (layout) / (double) PANGO_SCALE);
|
||||
pango_cairo_layout_path (cr, layout);
|
||||
path = cairo_copy_path_flat (cr);
|
||||
result = gsk_path_new_from_cairo (path);
|
||||
|
||||
cairo_path_destroy (path);
|
||||
g_object_unref (layout);
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GskPathMeasure *measure;
|
||||
GskPathBuilder *builder;
|
||||
double scale;
|
||||
} GtkPathTransform;
|
||||
|
||||
static void
|
||||
gtk_path_transform_point (GskPathMeasure *measure,
|
||||
const graphene_point_t *pt,
|
||||
float scale,
|
||||
graphene_point_t *res)
|
||||
{
|
||||
graphene_vec2_t tangent;
|
||||
|
||||
gsk_path_measure_get_point (measure, pt->x * scale, res, &tangent);
|
||||
|
||||
res->x -= pt->y * scale * graphene_vec2_get_y (&tangent);
|
||||
res->y += pt->y * scale * graphene_vec2_get_x (&tangent);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_path_transform_op (GskPathOperation op,
|
||||
const graphene_point_t *pts,
|
||||
gsize n_pts,
|
||||
float weight,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPathTransform *transform = data;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case GSK_PATH_MOVE:
|
||||
{
|
||||
graphene_point_t res;
|
||||
gtk_path_transform_point (transform->measure, &pts[0], transform->scale, &res);
|
||||
gsk_path_builder_move_to (transform->builder, res.x, res.y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_PATH_LINE:
|
||||
{
|
||||
graphene_point_t res;
|
||||
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res);
|
||||
gsk_path_builder_line_to (transform->builder, res.x, res.y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_PATH_CURVE:
|
||||
{
|
||||
graphene_point_t res[3];
|
||||
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res[0]);
|
||||
gtk_path_transform_point (transform->measure, &pts[2], transform->scale, &res[1]);
|
||||
gtk_path_transform_point (transform->measure, &pts[3], transform->scale, &res[2]);
|
||||
gsk_path_builder_curve_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_PATH_CONIC:
|
||||
{
|
||||
graphene_point_t res[2];
|
||||
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res[0]);
|
||||
gtk_path_transform_point (transform->measure, &pts[2], transform->scale, &res[1]);
|
||||
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, weight);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_PATH_CLOSE:
|
||||
gsk_path_builder_close (transform->builder);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GskPath *
|
||||
gtk_path_transform (GskPathMeasure *measure,
|
||||
GskPath *path)
|
||||
{
|
||||
GtkPathTransform transform = { measure, gsk_path_builder_new () };
|
||||
graphene_rect_t bounds;
|
||||
|
||||
gsk_path_get_bounds (path, &bounds);
|
||||
if (bounds.origin.x + bounds.size.width > 0)
|
||||
transform.scale = gsk_path_measure_get_length (measure) / (bounds.origin.x + bounds.size.width);
|
||||
else
|
||||
transform.scale = 1.0f;
|
||||
|
||||
gsk_path_foreach (path, GSK_PATH_FOREACH_ALLOW_CURVE, gtk_path_transform_op, &transform);
|
||||
|
||||
return gsk_path_builder_free_to_path (transform.builder);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_clear_text_path (GtkPathWidget *self)
|
||||
{
|
||||
g_clear_pointer (&self->text_path, gsk_path_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_clear_paths (GtkPathWidget *self)
|
||||
{
|
||||
gtk_path_widget_clear_text_path (self);
|
||||
|
||||
g_clear_pointer (&self->line_path, gsk_path_unref);
|
||||
g_clear_pointer (&self->line_measure, gsk_path_measure_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_create_text_path (GtkPathWidget *self)
|
||||
{
|
||||
GskPath *path;
|
||||
|
||||
gtk_path_widget_clear_text_path (self);
|
||||
|
||||
if (self->line_measure == NULL)
|
||||
return;
|
||||
|
||||
path = create_path_from_text (GTK_WIDGET (self), self->text);
|
||||
self->text_path = gtk_path_transform (self->line_measure, path);
|
||||
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_create_paths (GtkPathWidget *self)
|
||||
{
|
||||
double width = gtk_widget_get_width (GTK_WIDGET (self));
|
||||
double height = gtk_widget_get_height (GTK_WIDGET (self));
|
||||
GskPathBuilder *builder;
|
||||
|
||||
gtk_path_widget_clear_paths (self);
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_move_to (builder,
|
||||
self->points[0].x * width, self->points[0].y * height);
|
||||
gsk_path_builder_curve_to (builder,
|
||||
self->points[1].x * width, self->points[1].y * height,
|
||||
self->points[2].x * width, self->points[2].y * height,
|
||||
self->points[3].x * width, self->points[3].y * height);
|
||||
self->line_path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
self->line_measure = gsk_path_measure_new (self->line_path);
|
||||
|
||||
gtk_path_widget_create_text_path (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_path_widget_parent_class)->size_allocate (widget, width, height, baseline);
|
||||
|
||||
gtk_path_widget_create_paths (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
|
||||
double width = gtk_widget_get_width (widget);
|
||||
double height = gtk_widget_get_height (widget);
|
||||
GskPath *path;
|
||||
GskStroke *stroke;
|
||||
gsize i;
|
||||
|
||||
/* frosted glass the background */
|
||||
gtk_snapshot_push_blur (snapshot, 100);
|
||||
gdk_paintable_snapshot (self->background, snapshot, width, height);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 0.6 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
/* draw the text */
|
||||
if (self->text_path)
|
||||
{
|
||||
gtk_snapshot_push_fill (snapshot, self->text_path, GSK_FILL_RULE_WINDING);
|
||||
gdk_paintable_snapshot (self->background, snapshot, width, height);
|
||||
|
||||
/* ... with an emboss effect */
|
||||
stroke = gsk_stroke_new (2.0);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT(1, 1));
|
||||
gtk_snapshot_push_stroke (snapshot, self->text_path, stroke);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 0.2 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gsk_stroke_free (stroke);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
if (self->editable && self->line_path)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
|
||||
/* draw the control line */
|
||||
stroke = gsk_stroke_new (1.0);
|
||||
gtk_snapshot_push_stroke (snapshot, self->line_path, stroke);
|
||||
gsk_stroke_free (stroke);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
/* draw the points */
|
||||
builder = gsk_path_builder_new ();
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), POINT_SIZE);
|
||||
}
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
stroke = gsk_stroke_new (1.0);
|
||||
gtk_snapshot_push_stroke (snapshot, path, stroke);
|
||||
gsk_stroke_free (stroke);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
if (self->line_closest >= 0)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
graphene_point_t closest;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_measure_get_point (self->line_measure, self->line_closest, &closest, NULL);
|
||||
gsk_path_builder_add_circle (builder, &closest, POINT_SIZE);
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
|
||||
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_set_text (GtkPathWidget *self,
|
||||
const char *text)
|
||||
{
|
||||
if (g_strcmp0 (self->text, text) == 0)
|
||||
return;
|
||||
|
||||
g_free (self->text);
|
||||
self->text = g_strdup (text);
|
||||
|
||||
gtk_path_widget_create_paths (self);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_set_editable (GtkPathWidget *self,
|
||||
gboolean editable)
|
||||
{
|
||||
if (self->editable == editable)
|
||||
return;
|
||||
|
||||
self->editable = editable;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITABLE]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TEXT:
|
||||
gtk_path_widget_set_text (self, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_EDITABLE:
|
||||
gtk_path_widget_set_editable (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, self->text);
|
||||
break;
|
||||
|
||||
case PROP_EDITABLE:
|
||||
g_value_set_boolean (value, self->editable);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_dispose (GObject *object)
|
||||
{
|
||||
GtkPathWidget *self = GTK_PATH_WIDGET (object);
|
||||
|
||||
gtk_path_widget_clear_paths (self);
|
||||
|
||||
G_OBJECT_CLASS (gtk_path_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_class_init (GtkPathWidgetClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_path_widget_dispose;
|
||||
object_class->set_property = gtk_path_widget_set_property;
|
||||
object_class->get_property = gtk_path_widget_get_property;
|
||||
|
||||
widget_class->size_allocate = gtk_path_widget_allocate;
|
||||
widget_class->snapshot = gtk_path_widget_snapshot;
|
||||
|
||||
properties[PROP_TEXT] =
|
||||
g_param_spec_string ("text",
|
||||
"text",
|
||||
"Text transformed along a path",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_EDITABLE] =
|
||||
g_param_spec_boolean ("editable",
|
||||
"editable",
|
||||
"If the path can be edited by the user",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkGestureDrag *gesture,
|
||||
double x,
|
||||
double y,
|
||||
GtkPathWidget *self)
|
||||
{
|
||||
graphene_point_t mouse = GRAPHENE_POINT_INIT (x, y);
|
||||
double width = gtk_widget_get_width (GTK_WIDGET (self));
|
||||
double height = gtk_widget_get_height (GTK_WIDGET (self));
|
||||
gsize i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (graphene_point_distance (&GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), &mouse, NULL, NULL) <= POINT_SIZE)
|
||||
{
|
||||
self->active_point = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 4)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
drag_update (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
GtkPathWidget *self)
|
||||
{
|
||||
double width = gtk_widget_get_width (GTK_WIDGET (self));
|
||||
double height = gtk_widget_get_height (GTK_WIDGET (self));
|
||||
double start_x, start_y;
|
||||
|
||||
gtk_gesture_drag_get_start_point (drag, &start_x, &start_y);
|
||||
|
||||
self->points[self->active_point] = GRAPHENE_POINT_INIT ((start_x + offset_x) / width,
|
||||
(start_y + offset_y) / height);
|
||||
self->points[self->active_point].x = CLAMP (self->points[self->active_point].x, 0, 1);
|
||||
self->points[self->active_point].y = CLAMP (self->points[self->active_point].y, 0, 1);
|
||||
|
||||
gtk_path_widget_create_paths (self);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_motion (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
GtkPathWidget *self)
|
||||
{
|
||||
gsk_path_measure_get_closest_point_full (self->line_measure,
|
||||
&GRAPHENE_POINT_INIT (x, y),
|
||||
INFINITY,
|
||||
&self->line_closest,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_leave (GtkEventControllerMotion *controller,
|
||||
GtkPathWidget *self)
|
||||
{
|
||||
self->line_closest = -1;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_widget_init (GtkPathWidget *self)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
|
||||
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
|
||||
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
|
||||
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_update), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (pointer_motion), self);
|
||||
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
self->line_closest = -1;
|
||||
|
||||
self->points[0] = GRAPHENE_POINT_INIT (0.1, 0.9);
|
||||
self->points[1] = GRAPHENE_POINT_INIT (0.3, 0.1);
|
||||
self->points[2] = GRAPHENE_POINT_INIT (0.7, 0.1);
|
||||
self->points[3] = GRAPHENE_POINT_INIT (0.9, 0.9);
|
||||
|
||||
self->background = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
|
||||
|
||||
gtk_path_widget_set_text (self, "It's almost working");
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_path_widget_new (void)
|
||||
{
|
||||
GtkPathWidget *self;
|
||||
|
||||
self = g_object_new (GTK_TYPE_PATH_WIDGET, NULL);
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_path_text (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
g_type_ensure (GTK_TYPE_PATH_WIDGET);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/path_text/path_text.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="title" translatable="yes">Text along a Path</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="edit-toggle">
|
||||
<property name="icon-name">document-edit-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkRevealer">
|
||||
<property name="reveal-child" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="text">
|
||||
<property name="text">Through the looking glass</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPathWidget" id="view">
|
||||
<property name="editable" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
|
||||
<property name="text" bind-source="text" bind-property="text" bind-flags="sync-create"></property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "iconbrowserapp.h"
|
||||
#include "iconbrowserwin.h"
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
struct _IconBrowserApp
|
||||
{
|
||||
GtkApplication parent;
|
||||
@@ -77,25 +75,21 @@ about_activated (GSimpleAction *action,
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (s, "\nIcon theme\n\t%s", icon_theme);
|
||||
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
|
||||
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", g_strcmp0 (PROFILE, "devel") == 0
|
||||
? "GTK Icon Browser (Development)"
|
||||
: "GTK Icon Browser",
|
||||
"program-name", "GTK Icon Browser",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2021 The GTK Team",
|
||||
"copyright", "© 1997—2020 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to browse themed icons",
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.IconBrowser4",
|
||||
"logo-icon-name", "org.gtk.Demo4",
|
||||
"title", "About GTK Icon Browser",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
@@ -135,10 +129,6 @@ icon_browser_app_activate (GApplication *app)
|
||||
IconBrowserWindow *win;
|
||||
|
||||
win = icon_browser_window_new (ICON_BROWSER_APP (app));
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (win), "devel");
|
||||
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
|
||||
@@ -279,31 +279,11 @@ drag_prepare_texture (GtkDragSource *source,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
GtkSnapshot *snapshot;
|
||||
double width, height;
|
||||
GskRenderNode *node;
|
||||
GskRenderer *renderer;
|
||||
GdkTexture *texture;
|
||||
GdkContentProvider *ret;
|
||||
|
||||
if (!GDK_IS_PAINTABLE (paintable))
|
||||
return NULL;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
width = gdk_paintable_get_intrinsic_width (paintable);
|
||||
height = gdk_paintable_get_intrinsic_height (paintable);
|
||||
gdk_paintable_snapshot (paintable, snapshot, width, height);
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
|
||||
renderer = gtk_native_get_renderer (gtk_widget_get_native (widget));
|
||||
texture = gsk_renderer_render_texture (renderer, node, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
ret = gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, texture);
|
||||
|
||||
g_object_unref (texture);
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
return ret;
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
|
||||
@@ -14,7 +14,7 @@ iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
|
||||
executable('gtk4-icon-browser',
|
||||
sources: [iconbrowser_sources, iconbrowser_resources],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
demo_conf = configuration_data()
|
||||
demo_conf.set_quoted('PROFILE', get_option('profile'))
|
||||
demo_conf.set_quoted('VCS_TAG', '@VCS_TAG@')
|
||||
|
||||
demo_conf_h = declare_dependency(
|
||||
sources: vcs_tag(
|
||||
command: [ 'git', 'rev-parse', '--short', 'HEAD' ],
|
||||
fallback: get_option('profile') != 'default' ? 'devel' : '',
|
||||
input: configure_file(
|
||||
output: 'demo_conf.h.in',
|
||||
configuration: demo_conf
|
||||
),
|
||||
output: 'demo_conf.h'
|
||||
)
|
||||
)
|
||||
|
||||
subdir('constraint-editor')
|
||||
subdir('gtk-demo')
|
||||
subdir('icon-browser')
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
<property name="right-margin">20</property>
|
||||
<property name="top-margin">20</property>
|
||||
<property name="bottom-margin">20</property>
|
||||
<property name="monospace">1</property>
|
||||
<property name="buffer">
|
||||
<object class="GtkTextBuffer" id="buffer"/>
|
||||
</property>
|
||||
|
||||
@@ -12,7 +12,7 @@ node_editor_resources = gnome.compile_resources('node_editor_resources',
|
||||
|
||||
executable('gtk4-node-editor',
|
||||
sources: [node_editor_sources, node_editor_resources],
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
c_args: [
|
||||
'-DNODE_EDITOR_SOURCE_DIR="@0@/../../testsuite/gsk/compare/"'.format(meson.current_source_dir())
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
|
||||
#include "node-editor-window.h"
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
static const char *css =
|
||||
"textview.editor {"
|
||||
" color: rgb(192, 197, 206);"
|
||||
@@ -96,26 +94,22 @@ activate_about (GSimpleAction *action,
|
||||
|
||||
g_string_append_printf (s, "\nRenderer\n\t%s", renderer);
|
||||
|
||||
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
|
||||
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG,
|
||||
"transient-for", gtk_application_get_active_window (app),
|
||||
"program-name", g_strcmp0 (PROFILE, "devel") == 0
|
||||
? "GTK Node Editor (Development)"
|
||||
: "GTK Node Editor",
|
||||
"program-name", "GTK Node Editor",
|
||||
"version", version,
|
||||
"copyright", "© 2019—2021 The GTK Team",
|
||||
"copyright", "© 2019—2020 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to test GTK rendering",
|
||||
"authors", (const char *[]){ "Benjamin Otte", "Timm Bäder", NULL},
|
||||
"logo-icon-name", "org.gtk.gtk4.NodeEditor",
|
||||
"logo-icon-name", "org.gtk.gtk4.NodeEditor.Devel",
|
||||
"title", "About GTK Node Editor",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
@@ -213,10 +207,6 @@ node_editor_application_activate (GApplication *app)
|
||||
NodeEditorWindow *win;
|
||||
|
||||
win = node_editor_window_new (NODE_EDITOR_APPLICATION (app));
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (win), "devel");
|
||||
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include "gsk/gskrendernodeparserprivate.h"
|
||||
#include "gsk/gl/gskglrenderer.h"
|
||||
#include "gsk/ngl/gsknglrenderer.h"
|
||||
#ifdef GDK_WINDOWING_BROADWAY
|
||||
#include "gsk/broadway/gskbroadwayrenderer.h"
|
||||
#endif
|
||||
@@ -701,16 +700,6 @@ out:
|
||||
g_free (source_dir);
|
||||
}
|
||||
|
||||
static void
|
||||
dark_mode_cb (GtkToggleButton *button,
|
||||
GParamSpec *pspec,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
g_object_set (gtk_widget_get_settings (GTK_WIDGET (self)),
|
||||
"gtk-application-prefer-dark-theme", gtk_toggle_button_get_active (button),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_finalize (GObject *object)
|
||||
{
|
||||
@@ -763,9 +752,6 @@ node_editor_window_realize (GtkWidget *widget)
|
||||
node_editor_window_add_renderer (self,
|
||||
gsk_gl_renderer_new (),
|
||||
"OpenGL");
|
||||
node_editor_window_add_renderer (self,
|
||||
gsk_ngl_renderer_new (),
|
||||
"NGL");
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
node_editor_window_add_renderer (self,
|
||||
gsk_vulkan_renderer_new (),
|
||||
@@ -828,7 +814,6 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
gtk_widget_class_bind_template_callback (widget_class, export_image_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, testcase_save_clicked_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, testcase_name_entry_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, dark_mode_cb);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
@@ -925,26 +910,6 @@ node_editor_window_init (NodeEditorWindow *self)
|
||||
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);
|
||||
|
||||
/* Default */
|
||||
gtk_text_buffer_set_text (self->text_buffer,
|
||||
"shadow {\n"
|
||||
" child: texture {\n"
|
||||
" bounds: 0 0 128 128;\n"
|
||||
" texture: url(\"resource:///org/gtk/gtk4/node-editor/icons/apps/org.gtk.gtk4.NodeEditor.svg\");\n"
|
||||
" }\n"
|
||||
" shadows: rgba(0,0,0,0.5) 0 1 12;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"transform {\n"
|
||||
" child: text {\n"
|
||||
" color: rgb(46,52,54);\n"
|
||||
" font: \"Cantarell Bold 11\";\n"
|
||||
" glyphs: \"GTK Node Editor\";\n"
|
||||
" offset: 8 14.418;\n"
|
||||
" }\n"
|
||||
" transform: translate(0, 140);\n"
|
||||
"}", -1);
|
||||
}
|
||||
|
||||
NodeEditorWindow *
|
||||
|
||||
@@ -139,15 +139,6 @@
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="dark_bg_button">
|
||||
<property name="valign">center</property>
|
||||
<property name="has-frame">0</property>
|
||||
<property name="icon-name">display-brightness-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Use a dark background</property>
|
||||
<signal name="notify::active" handler="dark_mode_cb" swapped="0"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
<file preprocess="xml-stripblanks">node-editor-window.ui</file>
|
||||
<file preprocess="xml-stripblanks">help-window.ui</file>
|
||||
<file>node-format.md</file>
|
||||
<file alias='icons/apps/org.gtk.gtk4.NodeEditor.svg'>data/scalable/apps/org.gtk.gtk4.NodeEditor.svg</file>
|
||||
<file alias='icons/apps/org.gtk.gtk4.NodeEditor.Devel.svg'>data/scalable/apps/org.gtk.gtk4.NodeEditor.Devel.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
executable('gtk4-print-editor',
|
||||
sources: ['print-editor.c'],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Name=Print Editor
|
||||
Comment=A simple editor demonstrating GTK printing
|
||||
Exec=gtk4-print-editor %f
|
||||
Icon=org.gtk.PrintEditor4
|
||||
Icon=org.gtk.PrintEditor4.Devel
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
static GtkWidget *main_window;
|
||||
static GFile *filename = NULL;
|
||||
static GtkPageSetup *page_setup = NULL;
|
||||
@@ -643,26 +641,22 @@ activate_about (GSimpleAction *action,
|
||||
g_strfreev (backends);
|
||||
g_free (setting);
|
||||
|
||||
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
|
||||
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG,
|
||||
"transient-for", main_window,
|
||||
"program-name", g_strcmp0 (PROFILE, "devel") == 0
|
||||
? "GTK Print Editor (Development)"
|
||||
: "GTK Print Editor",
|
||||
"program-name", "GTK Print Editor",
|
||||
"version", version,
|
||||
"copyright", "© 2006-2021 Red Hat, Inc",
|
||||
"copyright", "© 2006-2020 Red Hat, Inc",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK printing",
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.PrintEditor4",
|
||||
"logo-icon-name", "org.gtk.PrintEditor4.Devel",
|
||||
"title", "About GTK Print Editor",
|
||||
"system-information", sysinfo->str,
|
||||
NULL);
|
||||
@@ -813,10 +807,6 @@ activate (GApplication *app)
|
||||
GtkWidget *contents;
|
||||
|
||||
main_window = gtk_application_window_new (GTK_APPLICATION (app));
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (main_window), "devel");
|
||||
|
||||
gtk_window_set_icon_name (GTK_WINDOW (main_window), "text-editor");
|
||||
gtk_window_set_default_size (GTK_WINDOW (main_window), 400, 600);
|
||||
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (main_window), TRUE);
|
||||
|
||||
@@ -8,7 +8,7 @@ widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
|
||||
executable('gtk4-widget-factory',
|
||||
sources: ['widget-factory.c', widgetfactory_resources],
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
static void
|
||||
change_dark_state (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
@@ -302,10 +300,8 @@ activate_about (GSimpleAction *action,
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (s, "\nA link can appear here: <http://www.gtk.org>");
|
||||
|
||||
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
|
||||
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
@@ -313,11 +309,9 @@ activate_about (GSimpleAction *action,
|
||||
dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG,
|
||||
"transient-for", gtk_application_get_active_window (app),
|
||||
"modal", TRUE,
|
||||
"program-name", g_strcmp0 (PROFILE, "devel") == 0
|
||||
? "GTK Widget Factory (Development)"
|
||||
: "GTK Widget Factory",
|
||||
"program-name", "GTK Widget Factory",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2021 The GTK Team",
|
||||
"copyright", "© 1997—2020 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK themes and widgets",
|
||||
@@ -2071,10 +2065,6 @@ activate (GApplication *app)
|
||||
}
|
||||
|
||||
window = (GtkWindow *)gtk_builder_get_object (builder, "window");
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (window), "devel");
|
||||
|
||||
gtk_application_add_window (GTK_APPLICATION (app), window);
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (window),
|
||||
win_entries, G_N_ELEMENTS (win_entries),
|
||||
@@ -2329,10 +2319,10 @@ activate (GApplication *app)
|
||||
static void
|
||||
print_version (void)
|
||||
{
|
||||
g_print ("gtk4-widget-factory %s%s%s\n",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "");
|
||||
g_print ("gtk4-widget-factory %d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -3298,6 +3298,7 @@ bad things might happen.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="basement-indicators"/>
|
||||
<menu id="new_style_menu_model">
|
||||
<section>
|
||||
<attribute name="display-hint">circular-buttons</attribute>
|
||||
|
||||
@@ -75,10 +75,6 @@
|
||||
<title>Index of all symbols</title>
|
||||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||
</index>
|
||||
<index id="api-index-4-2" role="4.2">
|
||||
<title>Index of new symbols in 4.2</title>
|
||||
<xi:include href="xml/api-index-4.2.xml"><xi:fallback /></xi:include>
|
||||
</index>
|
||||
<index id="api-index-deprecated" role="deprecated">
|
||||
<title>Index of deprecated symbols</title>
|
||||
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
|
||||
|
||||
@@ -627,8 +627,6 @@ gdk_popup_layout_set_anchor_hints
|
||||
gdk_popup_layout_get_anchor_hints
|
||||
gdk_popup_layout_set_offset
|
||||
gdk_popup_layout_get_offset
|
||||
gdk_popup_layout_set_shadow_width
|
||||
gdk_popup_layout_get_shadow_width
|
||||
<SUBSECTION Standard>
|
||||
GDK_TYPE_POPUP_LAYOUT
|
||||
gdk_popup_layout_get_type
|
||||
|
||||
@@ -146,9 +146,6 @@ images = [
|
||||
'images/nwse_resize_cursor.png',
|
||||
'images/zoom_in_cursor.png',
|
||||
'images/zoom_out_cursor.png',
|
||||
'images/popup-anchors.png',
|
||||
'images/popup-flip.png',
|
||||
'images/popup-slide.png',
|
||||
]
|
||||
|
||||
src_dir = [ gdkinc ]
|
||||
|
||||
@@ -23,6 +23,14 @@
|
||||
<xi:include href="xml/GskGLShader.xml" />
|
||||
</reference>
|
||||
|
||||
<part id="paths">
|
||||
<title>Paths</title>
|
||||
<xi:include href="xml/GskPath.xml" />
|
||||
<xi:include href="xml/GskPathBuilder.xml" />
|
||||
<xi:include href="xml/GskPathMeasure.xml" />
|
||||
<xi:include href="xml/GskStroke.xml" />
|
||||
</part>
|
||||
|
||||
<index id="api-index-full">
|
||||
<title>Index of all symbols</title>
|
||||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||
|
||||
@@ -182,6 +182,12 @@ gsk_rounded_clip_node_new
|
||||
gsk_rounded_clip_node_get_child
|
||||
gsk_rounded_clip_node_get_clip
|
||||
<SUBSECTION>
|
||||
GskFillRule
|
||||
gsk_fill_node_new
|
||||
gsk_fill_node_get_child
|
||||
gsk_fill_node_get_path
|
||||
gsk_fill_node_get_fill_rule
|
||||
<SUBSECTION>
|
||||
GskShadow
|
||||
gsk_shadow_node_new
|
||||
gsk_shadow_node_get_shadow
|
||||
@@ -235,6 +241,7 @@ GSK_TYPE_CONTAINER_NODE
|
||||
GSK_TYPE_CONIC_GRADIENT_NODE
|
||||
GSK_TYPE_CROSS_FADE_NODE
|
||||
GSK_TYPE_DEBUG_NODE
|
||||
GSK_TYPE_FILL_NODE
|
||||
GSK_TYPE_GL_SHADER_NODE
|
||||
GSK_TYPE_INSET_SHADOW_NODE
|
||||
GSK_TYPE_LINEAR_GRADIENT_NODE
|
||||
@@ -265,6 +272,7 @@ gsk_conic_gradient_node_get_type
|
||||
gsk_container_node_get_type
|
||||
gsk_cross_fade_node_get_type
|
||||
gsk_debug_node_get_type
|
||||
gsk_fill_node_get_type
|
||||
gsk_gl_shader_node_get_type
|
||||
gsk_inset_shadow_node_get_type
|
||||
gsk_linear_gradient_node_get_type
|
||||
@@ -306,6 +314,114 @@ gsk_rounded_rect_intersects_rect
|
||||
GSK_TYPE_CORNER
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>GskPath</FILE>
|
||||
<SUBSECTION>
|
||||
GskPath
|
||||
gsk_path_ref
|
||||
gsk_path_unref
|
||||
gsk_path_new_rect
|
||||
gsk_path_new_from_cairo
|
||||
gsk_path_parse
|
||||
<SUBSECTION>
|
||||
gsk_path_print
|
||||
gsk_path_to_string
|
||||
gsk_path_to_cairo
|
||||
<SUBSECTION>
|
||||
gsk_path_is_empty
|
||||
gsk_path_get_bounds
|
||||
gsk_path_get_stroke_bounds
|
||||
<SUBSECTION>
|
||||
GskPathOperation
|
||||
GskPathForeachFlags
|
||||
GskPathForeachFunc
|
||||
gsk_path_foreach
|
||||
<SUBSECTION Private>
|
||||
GSK_TYPE_PATH
|
||||
gsk_path_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>GskPathBuilder</FILE>
|
||||
GskPathBuilder
|
||||
gsk_path_builder_new
|
||||
gsk_path_builder_ref
|
||||
gsk_path_builder_unref
|
||||
gsk_path_builder_to_path
|
||||
gsk_path_builder_free_to_path
|
||||
<SUBSECTION>
|
||||
gsk_path_builder_get_current_point
|
||||
<SUBSECTION>
|
||||
gsk_path_builder_add_rect
|
||||
gsk_path_builder_add_rounded_rect
|
||||
gsk_path_builder_add_circle
|
||||
gsk_path_builder_add_ellipse
|
||||
gsk_path_builder_add_path
|
||||
gtk_path_builder_add_segment
|
||||
<SUBSECTION>
|
||||
gsk_path_builder_move_to
|
||||
gsk_path_builder_rel_move_to
|
||||
gsk_path_builder_line_to
|
||||
gsk_path_builder_rel_line_to
|
||||
gsk_path_builder_curve_to
|
||||
gsk_path_builder_rel_curve_to
|
||||
gsk_path_builder_conic_to
|
||||
gsk_path_builder_rel_conic_to
|
||||
gsk_path_builder_close
|
||||
<SUBSECTION Private>
|
||||
GSK_TYPE_PATH_BUILDER
|
||||
gsk_path_builder_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>GskPathMeasure</FILE>
|
||||
GskPathMeasure
|
||||
gsk_path_measure_new
|
||||
gsk_path_measure_new_with_tolerance
|
||||
gsk_path_measure_ref
|
||||
gsk_path_measure_unref
|
||||
<SUBSECTION>
|
||||
gsk_path_measure_get_path
|
||||
gsk_path_measure_get_tolerance
|
||||
gsk_path_measure_get_n_contours
|
||||
gsk_path_measure_restrict_to_contour
|
||||
<SUBSECTION>
|
||||
gsk_path_measure_get_length
|
||||
gsk_path_measure_is_closed
|
||||
gsk_path_measure_get_point
|
||||
gsk_path_measure_get_closest_point
|
||||
gsk_path_measure_get_closest_point_full
|
||||
gsk_path_measure_in_fill
|
||||
<SUBSECTION Private>
|
||||
GSK_TYPE_PATH_MEASURE
|
||||
gsk_path_measure_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>GskStroke</FILE>
|
||||
GskLineCap
|
||||
GskLineJoin
|
||||
gsk_stroke_new
|
||||
gsk_stroke_copy
|
||||
gsk_stroke_free
|
||||
gsk_stroke_equal
|
||||
gsk_stroke_set_line_width
|
||||
gsk_stroke_get_line_width
|
||||
gsk_stroke_set_line_join
|
||||
gsk_stroke_get_line_join
|
||||
gsk_stroke_set_line_cap
|
||||
gsk_stroke_get_line_cap
|
||||
gsk_stroke_set_miter_limit
|
||||
gsk_stroke_get_miter_limit
|
||||
gsk_stroke_set_dash
|
||||
gsk_stroke_get_dash
|
||||
gsk_stroke_set_dash_offset
|
||||
gsk_stroke_get_dash_offset
|
||||
<SUBSECTION Private>
|
||||
GSK_TYPE_STROKE
|
||||
gsk_stroke_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>GskTransform</FILE>
|
||||
GskTransform
|
||||
|
||||
@@ -18,9 +18,9 @@ Length
|
||||
Percentage
|
||||
: %, calc()
|
||||
Angle
|
||||
: deg, grad, turn, calc()
|
||||
: deg | grad | turn, calc()
|
||||
Time
|
||||
: s, ms, calc()
|
||||
: s | ms, calc()
|
||||
|
||||
Length values with the em or ex units are resolved using the font
|
||||
size value, unless they occur in setting the font-size itself, in
|
||||
@@ -32,7 +32,7 @@ not quite the same as the CSS definition of rem.
|
||||
The calc() notation adds considerable expressive power. There are limits
|
||||
on what types can be combined in such an expression (e.g. it does not make
|
||||
sense to add a number and a time). For the full details, see the
|
||||
[CSS3 Values and Units](https://www.w3.org/TR/css3-values/#calc-notation)
|
||||
[CSS3 VAlues and Units](https://www.w3.org/TR/css3-values/#calc-notation)
|
||||
spec.
|
||||
|
||||
A common pattern among shorthand properties (called 'four sides') is one
|
||||
@@ -151,7 +151,7 @@ done with
|
||||
|caret-color|[CSS Basic User Interface Level 3](https://www.w3.org/TR/css3-ui/#caret-color) | CSS allows an auto value |
|
||||
|-gtk-secondary-caret-color|[Color](https://www.w3.org/TR/css-color-3/#valuea-def-color) | used for the secondary caret in bidirectional text |
|
||||
|letter-spacing| [CSS Text Level 3](https://www.w3.org/TR/css3-text/#letter-spacing) | |
|
||||
|text-decoration-line| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-line-property) | |
|
||||
|text-decoration-line| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-line-property) | CSS allows overline |
|
||||
|text-decoration-color| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-color-property) | |
|
||||
|text-decoration-style| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-style-property) | CSS allows dashed and dotted |
|
||||
|text-shadow| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-shadow-property) | |
|
||||
@@ -159,12 +159,11 @@ done with
|
||||
|-gtk-icon-source| [Image](https://www.w3.org/TR/css-backgrounds-3/#typedef-image), `builtin` or `none` | used for builtin icons in buttons and expanders |
|
||||
|-gtk-icon-size| [Length](https://www.w3.org/TR/css3-values/#length-value) | size used for builtin icons in buttons and expanders |
|
||||
|-gtk-icon-style| `requested`, `regular` or `symbolic` | preferred style for application-loaded icons |
|
||||
|-gtk-icon-transform| [Transform list](https://www.w3.org/TR/css-transforms-1/#typedef-transform-list) or `none` | applied to builtin and application-loaded icons |
|
||||
|-gtk-icon-transform| [Transform list](https://drafts.csswg.org/css-transforms-1/#typedef-transform-list) or `none` | applied to builtin and application-loaded icons |
|
||||
|-gtk-icon-palette| Color palette, as explained above | used to recolor symbolic icons |
|
||||
|-gtk-icon-shadow| [Shadow](https://www.w3.org/TR/css-backgrounds-3/#typedef-shadow) or `none` | applied to builtin and application-loaded icons |
|
||||
|-gtk-icon-filter| [Filter value list](https://www.w3.org/TR/filter-effects-1/#typedef-filter-value-list) or `none` | applied to builtin and application-loaded icons |
|
||||
|transform| [CSS Transforms Level 1](https://www.w3.org/TR/css-transforms-1/#transform-property) | |
|
||||
|transform-origin| [CSS Transforms Level 1](https://www.w3.org/TR/css-transforms-1/#transform-origin-property) | CSS allows specifying a z component|
|
||||
|transform| [CSS Transforms Level 2](https://drafts.csswg.org/css-transforms-2/) | |
|
||||
|min-width| [CSS Box Model Level 3](https://www.w3.org/TR/css3-box/#min-width) | CSS allows percentages |
|
||||
|min-height| [CSS Box Model Level 3](https://www.w3.org/TR/css3-box/#min-height) | CSS allows percentages |
|
||||
|margin-top| [CSS Box Model Level 3](https://www.w3.org/TR/css3-box/#margin-top) | CSS allows percentages or auto |
|
||||
@@ -218,7 +217,7 @@ done with
|
||||
|background-size| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-size) | |
|
||||
|background-position| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-position) | |
|
||||
|background-repeat| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-repeat) | |
|
||||
|background-image| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-image) | not supported: urls without quotes |
|
||||
|background-image| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background-image) | not supported: urls without quotes, colors in crossfades |
|
||||
|box-shadow| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#box-shadow) | |
|
||||
|background-blend-mode| [CSS Compositing and Blending Level 1](https://www.w3.org/TR/compositing-1/#propdef-background-blend-mode) | only affects multiple backgrounds |
|
||||
|background| [CSS Backgrounds and Borders Level 3](https://www.w3.org/TR/css3-background/#background) | |
|
||||
@@ -236,4 +235,4 @@ done with
|
||||
|animation-delay| [CSS Animations Level 1](https://www.w3.org/TR/css3-animations/#animation-delay) | |
|
||||
|animation-fill-mode| [CSS Animations Level 1](https://www.w3.org/TR/css3-animations/#animation-fill-mode) | |
|
||||
|animation| [CSS Animations Level 1](https://www.w3.org/TR/css3-animations/#animation) | |
|
||||
|border-spacing| [CSS Table Level 3](https://www.w3.org/TR/css-tables-3/#border-spacing-property) | respected by GtkBoxLayout, GtkGridLayout, GtkCenterLayout |
|
||||
|border-spacing| [CSS Table Level 3](https://www.w3.org/TR/css-tables-3/#border-spacing-property) | respected by GtkBox and GtkGrid |
|
||||
|
||||
@@ -343,19 +343,20 @@ Many widgets, like buttons, do all their drawing themselves. You just tell
|
||||
them the label you want to see, and they figure out what font to use, draw
|
||||
the button outline and focus rectangle, etc. Sometimes, it is necessary to
|
||||
do some custom drawing. In that case, a GtkDrawingArea might be the right
|
||||
widget to use. It offers a canvas on which you can draw by setting its
|
||||
draw function.
|
||||
widget to use. It offers a canvas on which you can draw by connecting to
|
||||
the ::draw signal.
|
||||
|
||||
The contents of a widget often need to be partially or fully redrawn,
|
||||
e.g. when another window is moved and uncovers part of the widget, or
|
||||
when the window containing it is resized. It is also possible to explicitly
|
||||
cause a widget to be redrawn, by calling gtk_widget_queue_draw(). GTK takes
|
||||
care of most of the details by providing a ready-to-use cairo context to the
|
||||
draw function.
|
||||
cause part or all of the widget to be redrawn, by calling
|
||||
gtk_widget_queue_draw() or its variants. GTK takes care of most of the
|
||||
details by providing a ready-to-use cairo context to the ::draw signal
|
||||
handler.
|
||||
|
||||
The following example shows how to use a draw function with GtkDrawingArea.
|
||||
It is a bit more complicated than the previous examples, since it also
|
||||
demonstrates input event handling with event controllers.
|
||||
The following example shows a ::draw signal handler. It is a bit more
|
||||
complicated than the previous examples, since it also demonstrates
|
||||
input event handling by means of event controllers.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -41,41 +41,35 @@
|
||||
<command>gtk4-builder-tool</command> can perform various operations
|
||||
on GtkBuilder .ui files.
|
||||
</para>
|
||||
<para>
|
||||
The <option>validate</option> command validates the .ui file and reports
|
||||
errors to stderr.
|
||||
</para>
|
||||
<para>
|
||||
The <option>enumerate</option> command lists all the named objects that
|
||||
are created in the .ui file.
|
||||
</para>
|
||||
<para>
|
||||
The <option>preview</option> command displays the .ui file. This command
|
||||
accepts options to specify the ID of the toplevel object and a .css file
|
||||
to use.
|
||||
</para>
|
||||
<para>
|
||||
The <option>simplify</option> command simplifies the .ui file by removing
|
||||
properties that are set to their default values and writes the resulting XML
|
||||
to stdout, or back to the input file.
|
||||
</para>
|
||||
<para>
|
||||
When the <option>--3to4</option> is specified, <option>simplify</option>
|
||||
interprets the input as a GTK 3 ui file and attempts to convert it to GTK 4
|
||||
equivalents. It performs various conversions, such as renaming properties,
|
||||
translating child properties to layout properties, rewriting the setup for
|
||||
GtkNotebook, GtkStack, GtkAssistant or changing toolbars into boxes.
|
||||
</para>
|
||||
<para>
|
||||
You should always test the modified .ui files produced by gtk4-builder-tool
|
||||
before using them in production.
|
||||
</para>
|
||||
<para>
|
||||
Note in particular that the conversion
|
||||
done with <option>--3to4</option> is meant as a starting point for a port
|
||||
from GTK 3 to GTK 4. It is expected that you will have to do manual fixups
|
||||
after the initial conversion.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Commands</title>
|
||||
<para>The following commands are understood:</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>validate</option></term>
|
||||
<listitem><para>Validates the .ui file and report errors to stderr.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>simplify</option></term>
|
||||
<listitem><para>Simplifies the .ui file by removing properties that
|
||||
are set to their default values and write the resulting XML to stdout,
|
||||
or back to the input file.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>enumerate</option></term>
|
||||
<listitem><para>Lists all the named objects that are created in the .ui file.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>preview</option></term>
|
||||
<listitem><para>Preview the .ui file. This command accepts options
|
||||
to specify the ID of an object and a .css file to use.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Simplify Options</title>
|
||||
|
||||
@@ -61,13 +61,6 @@
|
||||
<listitem><para>Write png files to <replaceable>DIRECTORY</replaceable>
|
||||
instead of the current working directory.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--debug</term>
|
||||
<listitem><para>Generate png files of the various channels during
|
||||
the conversion. If these files are not monochrome green, they
|
||||
are often helpful in pinpointing the problematic parts of
|
||||
the source svg.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -1831,6 +1831,7 @@ GtkIMContextSimple
|
||||
gtk_im_context_simple_new
|
||||
gtk_im_context_simple_add_table
|
||||
gtk_im_context_simple_add_compose_file
|
||||
GTK_MAX_COMPOSE_LEN
|
||||
<SUBSECTION Standard>
|
||||
GTK_IM_CONTEXT_SIMPLE
|
||||
GTK_IS_IM_CONTEXT_SIMPLE
|
||||
@@ -4294,6 +4295,8 @@ gtk_snapshot_push_color_matrix
|
||||
gtk_snapshot_push_repeat
|
||||
gtk_snapshot_push_clip
|
||||
gtk_snapshot_push_rounded_clip
|
||||
gtk_snapshot_push_fill
|
||||
gtk_snapshot_push_stroke
|
||||
gtk_snapshot_push_cross_fade
|
||||
gtk_snapshot_push_blend
|
||||
gtk_snapshot_push_blur
|
||||
@@ -4667,6 +4670,7 @@ GTK_WINDOW_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkWindowPrivate
|
||||
gtk_window_get_type
|
||||
GtkWindowGeometryInfo
|
||||
gtk_window_remove_embedded_xid
|
||||
gtk_window_add_embedded_xid
|
||||
GtkWindowKeysForeachFunc
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
@@ -413,6 +413,10 @@ images = [
|
||||
'images/password-entry.png',
|
||||
'images/picture.png',
|
||||
'images/popover.png',
|
||||
'images/popup-anchors.png',
|
||||
'images/popup-at.svg',
|
||||
'images/popup-flip.png',
|
||||
'images/popup-slide.png',
|
||||
'images/printdialog.png',
|
||||
'images/progressbar.png',
|
||||
'images/right-center.png',
|
||||
|
||||
@@ -135,7 +135,7 @@ These functions are not supported in GTK 4. Instead, either use
|
||||
backend-specific APIs, or render your widgets using
|
||||
#GtkWidgetClass.snapshot() (once you are using GTK 4).
|
||||
|
||||
### Stop using GtkButton's image-related API
|
||||
Stop using GtkButton's image-related API
|
||||
|
||||
The functions and properties related to automatically add a GtkImage
|
||||
to a GtkButton, and using a GtkSetting to control its visibility, are
|
||||
@@ -165,11 +165,11 @@ for this change.
|
||||
| ::key-release-event | #GtkEventControllerKey |
|
||||
| ::enter-notify-event | #GtkEventControllerMotion |
|
||||
| ::leave-notify-event | #GtkEventControllerMotion |
|
||||
| ::configure-event | - |
|
||||
| ::configure-event | replaced by #GdkSurface::layout |
|
||||
| ::focus-in-event | #GtkEventControllerFocus |
|
||||
| ::focus-out-event | #GtkEventControllerFocus |
|
||||
| ::map-event | - |
|
||||
| ::unmap-event | - |
|
||||
| ::map-event | replaced by #GdkSurface:mapped |
|
||||
| ::unmap-event | replaced by #GdkSurface:mapped |
|
||||
| ::property-notify-event | replaced by #GdkClipboard |
|
||||
| ::selection-clear-event | replaced by #GdkClipboard |
|
||||
| ::selection-request-event | replaced by #GdkClipboard |
|
||||
@@ -178,17 +178,10 @@ for this change.
|
||||
| ::proximity-in-event | #GtkGestureStylus |
|
||||
| ::proximity-out-event | #GtkGestureStylus |
|
||||
| ::visibility-notify-event | - |
|
||||
| ::window-state-event | - |
|
||||
| ::window-state-event | replaced by #GdkToplevel:state |
|
||||
| ::damage-event | - |
|
||||
| ::grab-broken-event | - |
|
||||
|
||||
Event signals which are not directly related to input have to be dealt
|
||||
with on a one-by-one basis. If you were using ::configure-event and
|
||||
::window-state-event to save window state, you should use property
|
||||
notification for corresponding GtkWindow properties, such as
|
||||
#GtkWindow:default-width, #GtkWindow:default-height, #GtkWindow:maximized
|
||||
or #GtkWindow:fullscreened.
|
||||
|
||||
### Set a proper application ID
|
||||
|
||||
In GTK 4 we want the application's #GApplication 'application-id'
|
||||
@@ -271,6 +264,14 @@ therefore can no longer be used to break reference cycles. A typical sign
|
||||
of a reference cycle involving a toplevel window is when closing the window
|
||||
does not make the application quit.
|
||||
|
||||
A good rule to follow is: If you set a widget pointer with
|
||||
gtk_widget_class_bind_template_child() in class_init(), you need to
|
||||
unparent it in dispose(). The slight complication here is that you need
|
||||
to respect the widget hierarchy while doing so. Ie if you set both `field1`
|
||||
and `field2`, but `field1` is an ancestor of `field2`, then you only need
|
||||
to unparent `field1` — doing so will remove the the entire subtree below
|
||||
`field1`, including `field2`.
|
||||
|
||||
### Stop using GdkScreen
|
||||
|
||||
The GdkScreen object has been removed in GTK 4. Most of its APIs already
|
||||
@@ -406,7 +407,7 @@ and gdk_keymap_get_entries_for_keyval().
|
||||
GTK 3 has the idea that use of modifiers may differ between different
|
||||
platforms, and has a #GdkModifierIntent api to let platforms provide
|
||||
hint about how modifiers are expected to be used. It also promoted
|
||||
the use of `<Primary>` instead of `<Control>` to specify accelerators that
|
||||
the use of <Primary> instead of <Control> to specify accelerators that
|
||||
adapt to platform conventions.
|
||||
|
||||
In GTK 4, the meaning of modifiers has been fixed, and backends are
|
||||
@@ -425,88 +426,13 @@ GDK_CONTROL_MASK|GDK_ALT_MASK
|
||||
: Prevent text input
|
||||
|
||||
Consequently, #GdkModifierIntent and related APIs have been removed,
|
||||
and `<Control>` is preferred over `<Primary>` in accelerators.
|
||||
and <Control> is preferred over <Primary> in accelerators.
|
||||
|
||||
A related change is that GTK 4 no longer supports the use of archaic
|
||||
X11 'real' modifiers with the names Mod1,..., Mod5, and %GDK_MOD1_MASK
|
||||
has been renamed to %GDK_ALT_MASK.
|
||||
|
||||
### Replace GtkClipboard with GdkClipboard
|
||||
|
||||
The `GtkClipboard` API has been removed, and replaced by #GdkClipboard.
|
||||
There is not direct 1:1 mapping between the old an the new API, so it cannot
|
||||
be a mechanical replacement; the new API is based on object types and #GValue
|
||||
like object properties, instead of opaque identifiers, so it should be easier
|
||||
to use.
|
||||
|
||||
For instance, the example below copies the contents of an entry into the
|
||||
clipboard:
|
||||
|
||||
```
|
||||
static void
|
||||
copy_text (GtkWidget *widget)
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (widget);
|
||||
|
||||
// Initialize a GValue with the contents of the widget
|
||||
GValue value = G_VALUE_INIT;
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_value_set_string (&value, gtk_editable_get_text (editable));
|
||||
|
||||
// Store the value in the clipboard object
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
||||
gdk_clipboard_set_value (clipboard, &value);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
```
|
||||
|
||||
whereas the example below pastes the contents into the entry:
|
||||
|
||||
```
|
||||
static void
|
||||
paste_text (GtkWidget *widget)
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (widget);
|
||||
|
||||
// Initialize a GValue to receive text
|
||||
GValue value = G_VALUE_INIT;
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
|
||||
// Get the content provider for the clipboard, and ask it for text
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
||||
GdkContentProvider *provider = gdk_clipboard_get_content (clipboard);
|
||||
|
||||
// If the content provider does not contain text, we are not interested
|
||||
if (!gdk_content_provider_get_value (provider, &value, NULL))
|
||||
return;
|
||||
|
||||
const char *str = g_value_get_string (&value);
|
||||
|
||||
gtk_editable_set_text (editable, str);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
```
|
||||
|
||||
The convenience API for specific target types in `GtkClipboard` has been
|
||||
replaced by their corresponding GType:
|
||||
|
||||
| GtkClipboard | GType |
|
||||
| ----------------------------------- | ---------------------- |
|
||||
| `gtk_clipboard_request_text()` | `G_TYPE_STRING` |
|
||||
| `gtk_clipboard_request_rich_text()` | `GTK_TYPE_TEXT_BUFFER` |
|
||||
| `gtk_clipboard_request_image()` | `GDK_TYPE_PIXBUF` |
|
||||
| `gtk_clipboard_request_uris()` |` GDK_TYPE_FILE_LIST` |
|
||||
|
||||
**Note**: Support for rich text serialization across different processes
|
||||
for #GtkTextBuffer is not available any more.
|
||||
|
||||
If you are copying the contents of an image, it is recommended to use
|
||||
GDK_TYPE_PAINTABLE instead of GDK_TYPE_PIXBUF, to minimize the amount of
|
||||
potential copies.
|
||||
|
||||
### Stop using `gtk_get_current_...` APIs
|
||||
### Stop using gtk_get_current_... APIs
|
||||
|
||||
The function gtk_get_current_event() and its variants have been
|
||||
replaced by equivalent event controller APIs:
|
||||
@@ -522,25 +448,6 @@ option. You should always review the resulting changes.
|
||||
The <requires> tag now supports for the 'lib' attribute the
|
||||
'gtk' value only, instead of the 'gtk+' one previously.
|
||||
|
||||
### Adapt to GtkBuilder API changes
|
||||
|
||||
gtk_builder_connect_signals() no longer exists. Instead, signals are
|
||||
always connected automatically. If you need to add user data to your
|
||||
signals, gtk_builder_set_current_object() must be called. An important
|
||||
caveat is that you have to do this before loading any XML. This means if
|
||||
you need to use gtk_builder_set_current_object(), you can no longer use
|
||||
gtk_builder_new_from_file(), gtk_builder_new_from_resource(), or
|
||||
gtk_builder_new_from_string(). Instead, you must use vanilla gtk_builder_new(),
|
||||
then call gtk_builder_set_current_object(), then load the XML using
|
||||
gtk_builder_add_from_file(), gtk_builder_add_from_resource(), or
|
||||
gtk_builder_add_from_string(). You must check the return value for
|
||||
failure and manually abort with g_error() if something went wrong.
|
||||
|
||||
You only have to worry about this if you were previously using
|
||||
gtk_builder_connect_signals(). If you are using templates, then
|
||||
gtk_widget_init_template() will call gtk_builder_set_current_object()
|
||||
for you, so templates work like before.
|
||||
|
||||
### Adapt to event controller API changes
|
||||
|
||||
A few changes to the event controller and #GtkGesture APIs
|
||||
@@ -551,23 +458,6 @@ Another is that #GtkGestureMultiPress has been renamed to #GtkGestureClick,
|
||||
and has lost its area property. A #GtkEventControllerFocus has been
|
||||
split off from #GtkEventcontrollerKey.
|
||||
|
||||
In GTK 3, #GtkEventController:widget was a construct-only property, so
|
||||
a #GtkWidget was provided whenever constructing a #GtkEventController.
|
||||
In GTK 4, #GtkEventController:widget is now read-only. Use
|
||||
gtk_widget_add_controller() to add an event controller to a widget.
|
||||
|
||||
In GTK 3, widgets did not own their event controllers, and event
|
||||
controllers did not own their widgets, so developers were responsible
|
||||
for manually keeping event controllers alive for the lifetime of their
|
||||
associated widgets. In GTK 4, widgets own their event controllers.
|
||||
gtk_widget_add_controller() takes ownership of the event controller, so
|
||||
there is no longer any need to store a reference to the event controller
|
||||
after it has been added to a widget.
|
||||
|
||||
Although not normally needed, an event controller could be removed from
|
||||
a widget in GTK 3 by destroying the event controller with g_object_unref().
|
||||
In GTK 4, you must use gtk_widget_remove_controller().
|
||||
|
||||
### Focus handling changes
|
||||
|
||||
The semantics of the #GtkWidget:can-focus property have changed.
|
||||
@@ -861,8 +751,7 @@ to get it.
|
||||
The ::size-allocate signal has been removed, since it is easy
|
||||
to misuse. If you need to learn about sizing changes of custom
|
||||
drawing widgets, use the #GtkDrawingArea::resize or #GtkGLArea::resize
|
||||
signals. If you want to track the size of toplevel windows, use
|
||||
property notification for #GtkWindow:default-width and #GtkWindow:default-height.
|
||||
signals.
|
||||
|
||||
### Switch to GtkWidget's children APIs
|
||||
|
||||
@@ -1079,11 +968,6 @@ that wants to override the default handling, you can provide an
|
||||
implementation of the default.activate action in your widgets' action
|
||||
groups.
|
||||
|
||||
### Stop using gtk_widget_grab_default()
|
||||
|
||||
The function gtk_widget_grab_default() has been removed. If you need
|
||||
to mark a widget as default, use gtk_window_set_default_widget() directly.
|
||||
|
||||
### Stop setting ::has-default and ::has-focus in .ui files
|
||||
|
||||
The special handling for the ::has-default and ::has-focus properties
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "exampleapp.h"
|
||||
#include "exampleappwin.h"
|
||||
|
||||
struct _ExampleAppWindow
|
||||
{
|
||||
GtkApplicationWindow parent;
|
||||
|
||||
GSettings *settings;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *search;
|
||||
GtkWidget *searchbar;
|
||||
GtkWidget *searchentry;
|
||||
GtkWidget *gears;
|
||||
GtkWidget *sidebar;
|
||||
GtkWidget *words;
|
||||
GtkWidget *lines;
|
||||
GtkWidget *lines_label;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||
|
||||
static void
|
||||
search_text_changed (GtkEntry *entry,
|
||||
ExampleAppWindow *win)
|
||||
{
|
||||
const char *text;
|
||||
GtkWidget *tab;
|
||||
GtkWidget *view;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter start, match_start, match_end;
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
|
||||
if (text[0] == '\0')
|
||||
return;
|
||||
|
||||
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
|
||||
view = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (tab));
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
/* Very simple-minded search implementation */
|
||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
||||
if (gtk_text_iter_forward_search (&start, text, GTK_TEXT_SEARCH_CASE_INSENSITIVE,
|
||||
&match_start, &match_end, NULL))
|
||||
{
|
||||
gtk_text_buffer_select_range (buffer, &match_start, &match_end);
|
||||
gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match_start,
|
||||
0.0, FALSE, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
find_word (GtkButton *button,
|
||||
ExampleAppWindow *win)
|
||||
{
|
||||
const char *word;
|
||||
|
||||
word = gtk_button_get_label (button);
|
||||
gtk_editable_set_text (GTK_EDITABLE (win->searchentry), word);
|
||||
}
|
||||
|
||||
static void
|
||||
update_words (ExampleAppWindow *win)
|
||||
{
|
||||
GHashTable *strings;
|
||||
GHashTableIter iter;
|
||||
GtkWidget *tab, *view, *row;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter start, end;
|
||||
char *word, *key;
|
||||
GtkWidget *child;
|
||||
|
||||
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
|
||||
|
||||
if (tab == NULL)
|
||||
return;
|
||||
|
||||
view = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (tab));
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
||||
while (!gtk_text_iter_is_end (&start))
|
||||
{
|
||||
while (!gtk_text_iter_starts_word (&start))
|
||||
{
|
||||
if (!gtk_text_iter_forward_char (&start))
|
||||
goto done;
|
||||
}
|
||||
end = start;
|
||||
if (!gtk_text_iter_forward_word_end (&end))
|
||||
goto done;
|
||||
word = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
g_hash_table_add (strings, g_utf8_strdown (word, -1));
|
||||
g_free (word);
|
||||
start = end;
|
||||
}
|
||||
|
||||
done:
|
||||
while ((child = gtk_widget_get_first_child (win->words)))
|
||||
gtk_list_box_remove (GTK_LIST_BOX (win->words), child);
|
||||
|
||||
g_hash_table_iter_init (&iter, strings);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL))
|
||||
{
|
||||
row = gtk_button_new_with_label (key);
|
||||
g_signal_connect (row, "clicked",
|
||||
G_CALLBACK (find_word), win);
|
||||
gtk_box_append (GTK_BOX (win->words), row);
|
||||
}
|
||||
|
||||
g_hash_table_unref (strings);
|
||||
}
|
||||
|
||||
static void
|
||||
update_lines (ExampleAppWindow *win)
|
||||
{
|
||||
GtkWidget *tab, *view;
|
||||
GtkTextBuffer *buffer;
|
||||
int count;
|
||||
char *lines;
|
||||
|
||||
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
|
||||
|
||||
if (tab == NULL)
|
||||
return;
|
||||
|
||||
view = gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (tab));
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
count = gtk_text_buffer_get_line_count (buffer);
|
||||
lines = g_strdup_printf ("%d", count);
|
||||
gtk_label_set_text (GTK_LABEL (win->lines), lines);
|
||||
g_free (lines);
|
||||
}
|
||||
|
||||
static void
|
||||
visible_child_changed (GObject *stack,
|
||||
GParamSpec *pspec,
|
||||
ExampleAppWindow *win)
|
||||
{
|
||||
if (gtk_widget_in_destruction (GTK_WIDGET (stack)))
|
||||
return;
|
||||
|
||||
gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (win->searchbar), FALSE);
|
||||
update_words (win);
|
||||
update_lines (win);
|
||||
}
|
||||
|
||||
static void
|
||||
words_changed (GObject *sidebar,
|
||||
GParamSpec *pspec,
|
||||
ExampleAppWindow *win)
|
||||
{
|
||||
update_words (win);
|
||||
}
|
||||
|
||||
static void
|
||||
example_app_window_init (ExampleAppWindow *win)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GMenuModel *menu;
|
||||
GAction *action;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (win));
|
||||
win->settings = g_settings_new ("org.gtk.exampleapp");
|
||||
|
||||
g_settings_bind (win->settings, "transition",
|
||||
win->stack, "transition-type",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
g_settings_bind (win->settings, "show-words",
|
||||
win->sidebar, "reveal-child",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
g_object_bind_property (win->search, "active",
|
||||
win->searchbar, "search-mode-enabled",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
|
||||
g_signal_connect (win->sidebar, "notify::reveal-child",
|
||||
G_CALLBACK (words_changed), win);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
|
||||
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
|
||||
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
|
||||
g_object_unref (builder);
|
||||
|
||||
action = g_settings_create_action (win->settings, "show-words");
|
||||
g_action_map_add_action (G_ACTION_MAP (win), action);
|
||||
g_object_unref (action);
|
||||
|
||||
action = (GAction*) g_property_action_new ("show-lines", win->lines, "visible");
|
||||
g_action_map_add_action (G_ACTION_MAP (win), action);
|
||||
g_object_unref (action);
|
||||
|
||||
g_object_bind_property (win->lines, "visible",
|
||||
win->lines_label, "visible",
|
||||
G_BINDING_DEFAULT);
|
||||
|
||||
g_object_set (gtk_settings_get_default (), "gtk-shell-shows-app-menu", FALSE, NULL);
|
||||
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
example_app_window_dispose (GObject *object)
|
||||
{
|
||||
ExampleAppWindow *win;
|
||||
|
||||
win = EXAMPLE_APP_WINDOW (object);
|
||||
|
||||
g_clear_object (&win->settings);
|
||||
|
||||
G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
{
|
||||
G_OBJECT_CLASS (class)->dispose = example_app_window_dispose;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/exampleapp/window.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, search);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchbar);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchentry);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, words);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, sidebar);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, lines);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, lines_label);
|
||||
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), visible_child_changed);
|
||||
}
|
||||
|
||||
ExampleAppWindow *
|
||||
example_app_window_new (ExampleApp *app)
|
||||
{
|
||||
return g_object_new (EXAMPLE_APP_WINDOW_TYPE, "application", app, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
example_app_window_open (ExampleAppWindow *win,
|
||||
GFile *file)
|
||||
{
|
||||
char *basename;
|
||||
GtkWidget *scrolled, *view;
|
||||
char *contents;
|
||||
gsize length;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextTag *tag;
|
||||
GtkTextIter start_iter, end_iter;
|
||||
|
||||
basename = g_file_get_basename (file);
|
||||
|
||||
scrolled = gtk_scrolled_window_new ();
|
||||
gtk_widget_set_hexpand (scrolled, TRUE);
|
||||
gtk_widget_set_vexpand (scrolled, TRUE);
|
||||
view = gtk_text_view_new ();
|
||||
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
|
||||
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled), view);
|
||||
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
|
||||
{
|
||||
gtk_text_buffer_set_text (buffer, contents, length);
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
|
||||
g_settings_bind (win->settings, "font",
|
||||
tag, "font",
|
||||
G_SETTINGS_BIND_DEFAULT);
|
||||
|
||||
gtk_text_buffer_get_start_iter (buffer, &start_iter);
|
||||
gtk_text_buffer_get_end_iter (buffer, &end_iter);
|
||||
gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);
|
||||
|
||||
g_free (basename);
|
||||
|
||||
gtk_widget_set_sensitive (win->search, TRUE);
|
||||
|
||||
update_words (win);
|
||||
update_lines (win);
|
||||
}
|
||||
@@ -36,10 +36,6 @@
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#if !GLIB_CHECK_VERSION (2, 67, 3)
|
||||
# define g_memdup2(mem,size) g_memdup((mem), (size))
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
guint32 tag;
|
||||
@@ -609,7 +605,7 @@ update_future_pointer_info (BroadwayServer *server, BroadwayInputPointerMsg *dat
|
||||
static void
|
||||
queue_input_message (BroadwayServer *server, BroadwayInputMsg *msg)
|
||||
{
|
||||
server->input_messages = g_list_append (server->input_messages, g_memdup2 (msg, sizeof (BroadwayInputMsg)));
|
||||
server->input_messages = g_list_append (server->input_messages, g_memdup (msg, sizeof (BroadwayInputMsg)));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "gdkbroadway-server.h"
|
||||
|
||||
#include "gdkprivate-broadway.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
|
||||
#include <glib.h>
|
||||
@@ -235,7 +233,7 @@ static void
|
||||
parse_all_input (GdkBroadwayServer *server)
|
||||
{
|
||||
guint8 *p, *end;
|
||||
size_t size;
|
||||
guint32 size;
|
||||
BroadwayReply *reply;
|
||||
|
||||
p = server->recv_buffer;
|
||||
@@ -247,7 +245,7 @@ parse_all_input (GdkBroadwayServer *server)
|
||||
if (p + size > end)
|
||||
break;
|
||||
|
||||
reply = g_memdup2 (p, size);
|
||||
reply = g_memdup (p, size);
|
||||
p += size;
|
||||
|
||||
server->incoming = g_list_append (server->incoming, reply);
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <graphene.h>
|
||||
#include <stdlib.h>
|
||||
@@ -1026,7 +1025,7 @@ _gdk_broadway_moveresize_handle_event (GdkDisplay *display,
|
||||
*mv_resize->moveresize_pending_event = *event;
|
||||
else
|
||||
mv_resize->moveresize_pending_event =
|
||||
g_memdup2 (event, sizeof (BroadwayInputMsg));
|
||||
g_memdup (event, sizeof (BroadwayInputMsg));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1044,7 +1043,7 @@ _gdk_broadway_moveresize_handle_event (GdkDisplay *display,
|
||||
*mv_resize->moveresize_pending_event = *event;
|
||||
else
|
||||
mv_resize->moveresize_pending_event =
|
||||
g_memdup2 (event, sizeof (BroadwayInputMsg));
|
||||
g_memdup (event, sizeof (BroadwayInputMsg));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -49,12 +49,4 @@ guint gdk_parse_debug_var (const char *variable,
|
||||
const GdkDebugKey *keys,
|
||||
guint nkeys);
|
||||
|
||||
/* Backward compatibility shim, to avoid bumping up the minimum
|
||||
* required version of GLib; most of our uses of g_memdup() are
|
||||
* safe, and those that aren't have been fixed
|
||||
*/
|
||||
#if !GLIB_CHECK_VERSION (2, 67, 3)
|
||||
# define g_memdup2(mem,size) g_memdup((mem),(size))
|
||||
#endif
|
||||
|
||||
#endif /* __GDK__PRIVATE_H__ */
|
||||
|
||||
@@ -173,7 +173,7 @@ stash_desktop_startup_notification_id (void)
|
||||
if (!g_utf8_validate (desktop_startup_id, -1, NULL))
|
||||
g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
|
||||
else
|
||||
startup_notification_id = g_strdup (desktop_startup_id);
|
||||
startup_notification_id = g_strdup (desktop_startup_id ? desktop_startup_id : "");
|
||||
}
|
||||
|
||||
/* Clear the environment variable so it won't be inherited by
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
#include "gdkintl.h"
|
||||
#include "gdkcontentproviderimpl.h"
|
||||
|
||||
#include "gdk-private.h"
|
||||
|
||||
#define GDK_TYPE_CONTENT_PROVIDER_VALUE (gdk_content_provider_value_get_type ())
|
||||
#define GDK_CONTENT_PROVIDER_VALUE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_VALUE, GdkContentProviderValue))
|
||||
#define GDK_IS_CONTENT_PROVIDER_VALUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CONTENT_PROVIDER_VALUE))
|
||||
@@ -428,7 +426,7 @@ gdk_content_provider_new_union (GdkContentProvider **providers,
|
||||
result = g_object_new (GDK_TYPE_CONTENT_PROVIDER_UNION, NULL);
|
||||
|
||||
result->n_providers = n_providers;
|
||||
result->providers = g_memdup2 (providers, sizeof (GdkContentProvider *) * n_providers);
|
||||
result->providers = g_memdup (providers, sizeof (GdkContentProvider *) * n_providers);
|
||||
|
||||
for (i = 0; i < n_providers; i++)
|
||||
{
|
||||
|
||||
@@ -611,7 +611,17 @@ _gdk_device_set_associated_device (GdkDevice *device,
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
g_return_if_fail (associated == NULL || GDK_IS_DEVICE (associated));
|
||||
|
||||
g_set_object (&device->associated, associated);
|
||||
if (device->associated == associated)
|
||||
return;
|
||||
|
||||
if (device->associated)
|
||||
{
|
||||
g_object_unref (device->associated);
|
||||
device->associated = NULL;
|
||||
}
|
||||
|
||||
if (associated)
|
||||
device->associated = g_object_ref (associated);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -280,7 +280,7 @@ gdk_draw_context_get_surface (GdkDrawContext *context)
|
||||
* implementation must use gdk_draw_context_get_frame_region() to query the
|
||||
* region that must be drawn.
|
||||
*
|
||||
* When using GTK, the widget system automatically places calls to
|
||||
* When using GTK+, the widget system automatically places calls to
|
||||
* gdk_draw_context_begin_frame() and gdk_draw_context_end_frame() via the
|
||||
* use of #GskRenderers, so application code does not need to call these
|
||||
* functions explicitly.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static gsize g_define_type_id__volatile = 0;
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
|
||||
@@ -210,7 +210,7 @@ gdk_event_init (GdkEvent *self)
|
||||
GType
|
||||
gdk_event_get_type (void)
|
||||
{
|
||||
static gsize event_type__volatile;
|
||||
static volatile gsize event_type__volatile;
|
||||
|
||||
if (g_once_init_enter (&event_type__volatile))
|
||||
{
|
||||
@@ -332,7 +332,7 @@ gdk_event_type_register_static (const char *type_name,
|
||||
info.base_finalize = NULL;
|
||||
info.class_init = gdk_event_generic_class_init;
|
||||
info.class_finalize = NULL;
|
||||
info.class_data = g_memdup2 (type_info, sizeof (GdkEventTypeInfo));
|
||||
info.class_data = g_memdup (type_info, sizeof (GdkEventTypeInfo));
|
||||
|
||||
info.instance_size = type_info->instance_size;
|
||||
info.n_preallocs = 0;
|
||||
@@ -374,7 +374,7 @@ static GType gdk_event_types[GDK_EVENT_LAST];
|
||||
GType \
|
||||
type_name ## _get_type (void) \
|
||||
{ \
|
||||
static gsize gdk_define_event_type_id__volatile; \
|
||||
static volatile gsize gdk_define_event_type_id__volatile; \
|
||||
if (g_once_init_enter (&gdk_define_event_type_id__volatile)) \
|
||||
{ \
|
||||
GType gdk_define_event_type_id = \
|
||||
@@ -452,7 +452,7 @@ gdk_event_init_types_once (void)
|
||||
void
|
||||
gdk_event_init_types (void)
|
||||
{
|
||||
static gsize event_types__volatile;
|
||||
static volatile gsize event_types__volatile;
|
||||
|
||||
if (g_once_init_enter (&event_types__volatile))
|
||||
{
|
||||
@@ -1146,7 +1146,7 @@ gdk_event_dup_axes (GdkEvent *event)
|
||||
|
||||
if (gdk_event_get_axes (event, &axes, &n_axes))
|
||||
{
|
||||
double *axes_copy = g_memdup2 (axes, n_axes * sizeof (double));
|
||||
double *axes_copy = g_memdup (axes, n_axes * sizeof (double));
|
||||
|
||||
return axes_copy;
|
||||
}
|
||||
|
||||
@@ -107,9 +107,6 @@ make_program (GdkGLContextProgram *program,
|
||||
|
||||
glLinkProgram (program->program);
|
||||
|
||||
glDetachShader (program->program, vertex_shader);
|
||||
glDetachShader (program->program, fragment_shader);
|
||||
|
||||
glDeleteShader (vertex_shader);
|
||||
glDeleteShader (fragment_shader);
|
||||
|
||||
|
||||
@@ -271,12 +271,6 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
bpp = 3;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_B8G8R8)
|
||||
{
|
||||
gl_format = GL_BGR;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
bpp = 3;
|
||||
}
|
||||
else /* Fall-back, convert to cairo-surface-format */
|
||||
{
|
||||
copy = g_malloc (width * height * 4);
|
||||
|
||||
@@ -30,37 +30,6 @@
|
||||
* Popups are positioned relative to their parent surface.
|
||||
* The GdkPopupLayout struct contains information that is
|
||||
* necessary to do so.
|
||||
*
|
||||
* The positioning requires a negotiation with the windowing system,
|
||||
* since it depends on external constraints, such as the position of
|
||||
* the parent surface, and the screen dimensions.
|
||||
*
|
||||
* The basic ingredients are a rectangle on the parent surface,
|
||||
* and the anchor on both that rectangle and the popup. The anchors
|
||||
* specify a side or corner to place next to each other.
|
||||
*
|
||||
* 
|
||||
*
|
||||
* For cases where placing the anchors next to each other would make
|
||||
* the popup extend offscreen, the layout includes some hints for how
|
||||
* to resolve this problem. The hints may suggest to flip the anchor
|
||||
* position to the other side, or to 'slide' the popup along a side,
|
||||
* or to resize it.
|
||||
*
|
||||
* 
|
||||
*
|
||||
* 
|
||||
*
|
||||
* These hints may be combined.
|
||||
*
|
||||
* Ultimatively, it is up to the windowing system to determine the position
|
||||
* and size of the popup. You can learn about the result by calling
|
||||
* gdk_popup_get_position_x(), gdk_popup_get_position_y(),
|
||||
* gdk_popup_get_rect_anchor() and gdk_popup_get_surface_anchor() after the
|
||||
* popup has been presented. This can be used to adjust the rendering. For
|
||||
* example, GtkPopover changes its arrow position accordingly. But you have
|
||||
* to be careful avoid changing the size of the popover, or it has to be
|
||||
* presented again.
|
||||
*/
|
||||
|
||||
struct _GdkPopupLayout
|
||||
@@ -74,10 +43,6 @@ struct _GdkPopupLayout
|
||||
GdkAnchorHints anchor_hints;
|
||||
int dx;
|
||||
int dy;
|
||||
int shadow_left;
|
||||
int shadow_right;
|
||||
int shadow_top;
|
||||
int shadow_bottom;
|
||||
};
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GdkPopupLayout, gdk_popup_layout,
|
||||
@@ -169,10 +134,6 @@ gdk_popup_layout_copy (GdkPopupLayout *layout)
|
||||
new_layout->anchor_hints = layout->anchor_hints;
|
||||
new_layout->dx = layout->dx;
|
||||
new_layout->dy = layout->dy;
|
||||
new_layout->shadow_left = layout->shadow_left;
|
||||
new_layout->shadow_right = layout->shadow_right;
|
||||
new_layout->shadow_top = layout->shadow_top;
|
||||
new_layout->shadow_bottom = layout->shadow_bottom;
|
||||
|
||||
return new_layout;
|
||||
}
|
||||
@@ -199,11 +160,7 @@ gdk_popup_layout_equal (GdkPopupLayout *layout,
|
||||
layout->surface_anchor == other->surface_anchor &&
|
||||
layout->anchor_hints == other->anchor_hints &&
|
||||
layout->dx == other->dx &&
|
||||
layout->dy == other->dy &&
|
||||
layout->shadow_left == other->shadow_left &&
|
||||
layout->shadow_right == other->shadow_right &&
|
||||
layout->shadow_top == other->shadow_top &&
|
||||
layout->shadow_bottom == other->shadow_bottom);
|
||||
layout->dy == other->dy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,59 +315,3 @@ gdk_popup_layout_get_offset (GdkPopupLayout *layout,
|
||||
if (dy)
|
||||
*dy = layout->dy;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_popup_layout_set_shadow_width:
|
||||
* @layout: a #GdkPopupLayout
|
||||
* @left: width of the left part of the shadow
|
||||
* @right: width of the right part of the shadow
|
||||
* @top: height of the top part of the shadow
|
||||
* @bottom: height of the bottom part of the shadow
|
||||
*
|
||||
* The shadow width corresponds to the part of the computed surface size
|
||||
* that would consist of the shadow margin surrounding the window, would
|
||||
* there be any.
|
||||
*
|
||||
* Since: 4.2
|
||||
*/
|
||||
void
|
||||
gdk_popup_layout_set_shadow_width (GdkPopupLayout *layout,
|
||||
int left,
|
||||
int right,
|
||||
int top,
|
||||
int bottom)
|
||||
{
|
||||
layout->shadow_left = left;
|
||||
layout->shadow_right = right;
|
||||
layout->shadow_top = top;
|
||||
layout->shadow_bottom = bottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_popup_layout_get_shadow_width:
|
||||
* @layout: a #GdkPopupLayout
|
||||
* @left: (out): return location for the left shadow width
|
||||
* @right: (out): return location for the right shadow width
|
||||
* @top: (out): return location for the top shadow width
|
||||
* @bottom: (out): return location for the bottom shadow width
|
||||
*
|
||||
* Obtains the shadow widths of this layout.
|
||||
*
|
||||
* Since: 4.2
|
||||
*/
|
||||
void
|
||||
gdk_popup_layout_get_shadow_width (GdkPopupLayout *layout,
|
||||
int *left,
|
||||
int *right,
|
||||
int *top,
|
||||
int *bottom)
|
||||
{
|
||||
if (left)
|
||||
*left = layout->shadow_left;
|
||||
if (right)
|
||||
*right = layout->shadow_right;
|
||||
if (top)
|
||||
*top = layout->shadow_top;
|
||||
if (bottom)
|
||||
*bottom = layout->shadow_bottom;
|
||||
}
|
||||
|
||||
@@ -137,20 +137,6 @@ void gdk_popup_layout_get_offset (GdkPopupLayout
|
||||
int *dx,
|
||||
int *dy);
|
||||
|
||||
GDK_AVAILABLE_IN_4_2
|
||||
void gdk_popup_layout_set_shadow_width (GdkPopupLayout *layout,
|
||||
int left,
|
||||
int right,
|
||||
int top,
|
||||
int bottom);
|
||||
GDK_AVAILABLE_IN_4_2
|
||||
void gdk_popup_layout_get_shadow_width (GdkPopupLayout *layout,
|
||||
int *left,
|
||||
int *right,
|
||||
int *top,
|
||||
int *bottom);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_POPUP_LAYOUT_H__ */
|
||||
|
||||
@@ -73,23 +73,23 @@ void gdk_profiler_set_int_counter (guint id,
|
||||
gint64 value);
|
||||
|
||||
#ifndef HAVE_SYSPROF
|
||||
#define gdk_profiler_add_mark(b, d, n, m) G_STMT_START {} G_STMT_END
|
||||
#define gdk_profiler_end_mark(b, n, m) G_STMT_START {} G_STMT_END
|
||||
#define gdk_profiler_add_mark(b, d, n, m)
|
||||
#define gdk_profiler_end_mark(b, n, m)
|
||||
/* Optimise the whole call out */
|
||||
#if defined(G_HAVE_ISO_VARARGS)
|
||||
#define gdk_profiler_add_markf(b, d, n, m, ...) G_STMT_START {} G_STMT_END
|
||||
#define gdk_profiler_end_markf(b, n, m, ...) G_STMT_START {} G_STMT_END
|
||||
#define gdk_profiler_add_markf(b, d, n, m, ...)
|
||||
#define gdk_profiler_end_markf(b, n, m, ...)
|
||||
#elif defined(G_HAVE_GNUC_VARARGS)
|
||||
#define gdk_profiler_add_markf(b, d, n, m...) G_STMT_START {} G_STMT_END
|
||||
#define gdk_profiler_end_markf(b, n, m...) G_STMT_START {} G_STMT_END
|
||||
#define gdk_profiler_add_markf(b, d, n, m...)
|
||||
#define gdk_profiler_end_markf(b, n, m...)
|
||||
#else
|
||||
/* no varargs macro support; the call will have to be optimised out by the compiler */
|
||||
#endif
|
||||
|
||||
#define gdk_profiler_define_counter(n, d) 0
|
||||
#define gdk_profiler_define_int_counter(n, d) 0
|
||||
#define gdk_profiler_set_counter(i, v) G_STMT_START {} G_STMT_END
|
||||
#define gdk_profiler_set_int_counter(i, v) G_STMT_START {} G_STMT_END
|
||||
#define gdk_profiler_set_counter(i, v)
|
||||
#define gdk_profiler_set_int_counter(i, v)
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -436,10 +436,9 @@ gdk_seat_tool_removed (GdkSeat *seat,
|
||||
}
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id,
|
||||
GdkDeviceToolType type)
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id)
|
||||
{
|
||||
GdkDeviceTool *match = NULL;
|
||||
GList *tools, *l;
|
||||
@@ -450,7 +449,7 @@ gdk_seat_get_tool (GdkSeat *seat,
|
||||
{
|
||||
GdkDeviceTool *tool = l->data;
|
||||
|
||||
if (tool->serial == serial && tool->hw_id == hw_id && tool->type == type)
|
||||
if (tool->serial == serial && tool->hw_id == hw_id)
|
||||
{
|
||||
match = tool;
|
||||
break;
|
||||
|
||||
@@ -49,7 +49,7 @@ struct _GdkSeatDefaultPrivate
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkSeatDefault, gdk_seat_default, GDK_TYPE_SEAT)
|
||||
|
||||
static void
|
||||
gdk_seat_default_dispose (GObject *object)
|
||||
gdk_seat_dispose (GObject *object)
|
||||
{
|
||||
GdkSeatDefault *seat = GDK_SEAT_DEFAULT (object);
|
||||
GdkSeatDefaultPrivate *priv = gdk_seat_default_get_instance_private (seat);
|
||||
@@ -79,7 +79,11 @@ gdk_seat_default_dispose (GObject *object)
|
||||
g_object_unref (l->data);
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->tools, g_ptr_array_unref);
|
||||
if (priv->tools)
|
||||
{
|
||||
g_ptr_array_unref (priv->tools);
|
||||
priv->tools = NULL;
|
||||
}
|
||||
|
||||
g_list_free (priv->physical_pointers);
|
||||
g_list_free (priv->physical_keyboards);
|
||||
@@ -303,7 +307,7 @@ gdk_seat_default_class_init (GdkSeatDefaultClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_seat_default_dispose;
|
||||
object_class->dispose = gdk_seat_dispose;
|
||||
|
||||
seat_class->get_capabilities = gdk_seat_default_get_capabilities;
|
||||
|
||||
@@ -438,7 +442,7 @@ gdk_seat_default_remove_tool (GdkSeatDefault *seat,
|
||||
|
||||
priv = gdk_seat_default_get_instance_private (seat);
|
||||
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat), tool->serial, tool->hw_id, tool->type))
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat), tool->serial, tool->hw_id))
|
||||
return;
|
||||
|
||||
g_signal_emit_by_name (seat, "tool-removed", tool);
|
||||
|
||||
@@ -75,10 +75,9 @@ void gdk_seat_tool_removed (GdkSeat *seat,
|
||||
GdkDeviceTool *tool);
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id,
|
||||
GdkDeviceToolType type);
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id);
|
||||
|
||||
GdkGrabStatus gdk_seat_grab (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
|
||||
@@ -92,7 +92,6 @@ enum {
|
||||
PROP_MAPPED,
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_SCALE_FACTOR,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -552,13 +551,6 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor",
|
||||
P_("Scale factor"),
|
||||
P_("Scale factor"),
|
||||
1, G_MAXINT, 1,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, properties);
|
||||
|
||||
/**
|
||||
@@ -790,10 +782,6 @@ gdk_surface_get_property (GObject *object,
|
||||
g_value_set_int (value, surface->height);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
g_value_set_int (value, gdk_surface_get_scale_factor (surface));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -2557,7 +2545,8 @@ gdk_surface_get_frame_clock (GdkSurface *surface)
|
||||
* value can be used to determine whether to use a pixel resource
|
||||
* with higher resolution data.
|
||||
*
|
||||
* The scale of a surface may change during runtime.
|
||||
* The scale of a surface may change during runtime, if this happens
|
||||
* a configure event will be sent to the toplevel surface.
|
||||
*
|
||||
* Returns: the scale factor
|
||||
*/
|
||||
@@ -2960,8 +2949,8 @@ gdk_surface_request_motion (GdkSurface *surface)
|
||||
* gdk_surface_translate_coordinates:
|
||||
* @from: the origin surface
|
||||
* @to: the target surface
|
||||
* @x: (inout): coordinates to translate
|
||||
* @y: (inout): coordinates to translate
|
||||
* @x: coordinates to translate
|
||||
* @y: coordinates to translate
|
||||
*
|
||||
* Translates the given coordinates from being
|
||||
* relative to the @from surface to being relative
|
||||
@@ -2980,18 +2969,9 @@ gdk_surface_translate_coordinates (GdkSurface *from,
|
||||
double *x,
|
||||
double *y)
|
||||
{
|
||||
double in_x, in_y, out_x, out_y;
|
||||
int x1, y1, x2, y2;
|
||||
GdkSurface *f, *t;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (from), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (to), FALSE);
|
||||
g_return_val_if_fail (x != NULL, FALSE);
|
||||
g_return_val_if_fail (y != NULL, FALSE);
|
||||
|
||||
in_x = *x;
|
||||
in_y = *y;
|
||||
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
f = from;
|
||||
@@ -3015,11 +2995,8 @@ gdk_surface_translate_coordinates (GdkSurface *from,
|
||||
if (f != t)
|
||||
return FALSE;
|
||||
|
||||
out_x = in_x + (x1 - x2);
|
||||
out_y = in_y + (y1 - y2);
|
||||
|
||||
*x = out_x;
|
||||
*y = out_y;
|
||||
*x += x1 - x2;
|
||||
*y += y1 - y2;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -316,9 +316,9 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
* @resource_path: the path of the resource file
|
||||
*
|
||||
* Creates a new texture by loading an image from a resource.
|
||||
* The file format is detected automatically.
|
||||
* The supported formats are PNG and JPEG, though more formats might be
|
||||
* available.
|
||||
* The file format is detected automatically, and can be any
|
||||
* format that is supported by the gdk-pixbuf library, such as
|
||||
* JPEG or PNG.
|
||||
*
|
||||
* It is a fatal error if @resource_path does not specify a valid
|
||||
* image resource and the program will abort if that happens.
|
||||
@@ -352,9 +352,9 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
* @error: Return location for an error
|
||||
*
|
||||
* Creates a new texture by loading an image from a file.
|
||||
* The file format is detected automatically.
|
||||
* The supported formats are PNG and JPEG, though more formats might be
|
||||
* available.
|
||||
* The file format is detected automatically, and can be any
|
||||
* format that is supported by the gdk-pixbuf library, such as
|
||||
* JPEG or PNG.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
|
||||
@@ -149,6 +149,12 @@ gdk_toplevel_size_validate (GdkToplevelSize *size)
|
||||
{
|
||||
int geometry_width, geometry_height;
|
||||
|
||||
if (size->min_width > size->bounds_width ||
|
||||
size->min_height > size->bounds_height)
|
||||
g_warning ("GdkToplevelSize: min_size (%d, %d) exceeds bounds (%d, %d)",
|
||||
size->min_width, size->min_height,
|
||||
size->bounds_width, size->bounds_height);
|
||||
|
||||
geometry_width = size->width;
|
||||
geometry_height = size->height;
|
||||
if (size->shadow.is_valid)
|
||||
@@ -156,4 +162,15 @@ gdk_toplevel_size_validate (GdkToplevelSize *size)
|
||||
geometry_width -= size->shadow.left + size->shadow.right;
|
||||
geometry_height -= size->shadow.top + size->shadow.bottom;
|
||||
}
|
||||
if (geometry_width > size->bounds_width ||
|
||||
geometry_height > size->bounds_height)
|
||||
g_warning ("GdkToplevelSize: geometry size (%d, %d) exceeds bounds (%d, %d)",
|
||||
size->width, size->height,
|
||||
size->bounds_width, size->bounds_height);
|
||||
|
||||
if (size->min_width > size->width ||
|
||||
size->min_height > size->height)
|
||||
g_warning ("GdkToplevelSize: min_size (%d, %d) exceeds size (%d, %d)",
|
||||
size->min_width, size->min_height,
|
||||
size->width, size->height);
|
||||
}
|
||||
|
||||
@@ -78,14 +78,6 @@
|
||||
*/
|
||||
#define GDK_VERSION_4_0 (G_ENCODE_VERSION (4, 0))
|
||||
|
||||
/**
|
||||
* GDK_VERSION_4_2:
|
||||
*
|
||||
* A macro that evaluates to the 4.2 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*/
|
||||
#define GDK_VERSION_4_2 (G_ENCODE_VERSION (4, 2))
|
||||
|
||||
|
||||
/* evaluates to the current stable version; for development cycles,
|
||||
* this means the next stable target, with a hard backstop to the
|
||||
@@ -183,19 +175,4 @@
|
||||
# define GDK_DEPRECATED_IN_4_0_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
|
||||
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_4_2
|
||||
# define GDK_AVAILABLE_IN_4_2 GDK_UNAVAILABLE(4, 2)
|
||||
#else
|
||||
# define GDK_AVAILABLE_IN_4_2 _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_2
|
||||
# define GDK_DEPRECATED_IN_4_2 GDK_DEPRECATED
|
||||
# define GDK_DEPRECATED_IN_4_2_FOR(f) GDK_DEPRECATED_FOR(f)
|
||||
#else
|
||||
# define GDK_DEPRECATED_IN_4_2 _GDK_EXTERN
|
||||
# define GDK_DEPRECATED_IN_4_2_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#endif /* __GDK_VERSION_MACROS_H__ */
|
||||
|
||||
@@ -225,7 +225,7 @@ gdk_vulkan_strerror (VkResult result)
|
||||
case VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT:
|
||||
return "A requested pipeline creation would have required compilation, but the application requested compilation to not be performed.";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION < 140
|
||||
#if VK_HEADER_VERSION < 142
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
#endif
|
||||
case VK_RESULT_MAX_ENUM:
|
||||
|
||||
@@ -38,10 +38,6 @@
|
||||
#include "gdkmonitorprivate.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
|
||||
#ifndef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
typedef NSString *CALayerContentsGravity;
|
||||
#endif
|
||||
|
||||
@implementation GdkMacosWindow
|
||||
|
||||
-(BOOL)windowShouldClose:(id)sender
|
||||
@@ -470,7 +466,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
inTrackManualResize = YES;
|
||||
|
||||
mouse_location = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
mouse_location = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
mdx = initialResizeLocation.x - mouse_location.x;
|
||||
mdy = initialResizeLocation.y - mouse_location.y;
|
||||
|
||||
@@ -592,7 +588,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
}
|
||||
|
||||
initialResizeFrame = [self frame];
|
||||
initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
initialResizeLocation = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
}
|
||||
|
||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
|
||||
@@ -27,10 +27,6 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifndef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
|
||||
typedef NSString *NSPasteboardType;
|
||||
#endif
|
||||
|
||||
#define GDK_TYPE_MACOS_CLIPBOARD (_gdk_macos_clipboard_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK, MACOS_CLIPBOARD, GdkClipboard)
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
struct _GdkMacosClipboard
|
||||
{
|
||||
@@ -41,56 +40,8 @@ typedef struct
|
||||
guint done : 1;
|
||||
} WriteRequest;
|
||||
|
||||
enum {
|
||||
TYPE_STRING,
|
||||
TYPE_PBOARD,
|
||||
TYPE_URL,
|
||||
TYPE_FILE_URL,
|
||||
TYPE_COLOR,
|
||||
TYPE_TIFF,
|
||||
TYPE_PNG,
|
||||
TYPE_LAST
|
||||
};
|
||||
|
||||
#define PTYPE(k) (get_pasteboard_type(TYPE_##k))
|
||||
|
||||
static NSPasteboardType pasteboard_types[TYPE_LAST];
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK_TYPE_CLIPBOARD)
|
||||
|
||||
static NSPasteboardType
|
||||
get_pasteboard_type (int type)
|
||||
{
|
||||
static gsize initialized = FALSE;
|
||||
|
||||
g_assert (type >= 0);
|
||||
g_assert (type < TYPE_LAST);
|
||||
|
||||
if (g_once_init_enter (&initialized))
|
||||
{
|
||||
pasteboard_types[TYPE_PNG] = NSPasteboardTypePNG;
|
||||
pasteboard_types[TYPE_STRING] = NSPasteboardTypeString;
|
||||
pasteboard_types[TYPE_TIFF] = NSPasteboardTypeTIFF;
|
||||
pasteboard_types[TYPE_COLOR] = NSPasteboardTypeColor;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
pasteboard_types[TYPE_PBOARD] = NSStringPboardType;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
|
||||
pasteboard_types[TYPE_URL] = NSPasteboardTypeURL;
|
||||
pasteboard_types[TYPE_FILE_URL] = NSPasteboardTypeFileURL;
|
||||
#else
|
||||
pasteboard_types[TYPE_URL] = [[NSString alloc] initWithUTF8String:"public.url"];
|
||||
pasteboard_types[TYPE_FILE_URL] = [[NSString alloc] initWithUTF8String:"public.file-url"];
|
||||
#endif
|
||||
|
||||
g_once_init_leave (&initialized, TRUE);
|
||||
}
|
||||
|
||||
return pasteboard_types[type];
|
||||
}
|
||||
|
||||
static void
|
||||
write_request_free (WriteRequest *wr)
|
||||
{
|
||||
@@ -105,17 +56,17 @@ _gdk_macos_clipboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:PTYPE(STRING)] ||
|
||||
[type isEqualToString:PTYPE(PBOARD)])
|
||||
if ([type isEqualToString:NSPasteboardTypeString] ||
|
||||
[type isEqualToString:NSStringPboardType])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:PTYPE(URL)] ||
|
||||
[type isEqualToString:PTYPE(FILE_URL)])
|
||||
else if ([type isEqualToString:NSPasteboardTypeURL] ||
|
||||
[type isEqualToString:NSPasteboardTypeFileURL])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:PTYPE(COLOR)])
|
||||
else if ([type isEqualToString:NSPasteboardTypeColor])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:PTYPE(TIFF)])
|
||||
else if ([type isEqualToString:NSPasteboardTypeTIFF])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:PTYPE(PNG)])
|
||||
else if ([type isEqualToString:NSPasteboardTypePNG])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
@@ -132,25 +83,25 @@ _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return PTYPE(STRING);
|
||||
return NSPasteboardTypeString;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = PTYPE(URL);
|
||||
return PTYPE(FILE_URL);
|
||||
*alternate = NSPasteboardTypeURL;
|
||||
return NSPasteboardTypeFileURL;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return PTYPE(COLOR);
|
||||
return NSPasteboardTypeColor;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return PTYPE(TIFF);
|
||||
return NSPasteboardTypeTIFF;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return PTYPE(PNG);
|
||||
return NSPasteboardTypePNG;
|
||||
}
|
||||
|
||||
return nil;
|
||||
@@ -214,7 +165,7 @@ create_stream_from_nsdata (NSData *data)
|
||||
const guint8 *bytes = [data bytes];
|
||||
gsize len = [data length];
|
||||
|
||||
return g_memory_input_stream_new_from_data (g_memdup2 (bytes, len), len, g_free);
|
||||
return g_memory_input_stream_new_from_data (g_memdup (bytes, len), len, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -269,7 +220,7 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[self->pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
if ([[self->pasteboard types] containsObject:NSPasteboardTypeFileURL])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [self->pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
@@ -310,18 +261,18 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
color[2] = 0xffff * [nscolor blueComponent];
|
||||
color[3] = 0xffff * [nscolor alphaComponent];
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
|
||||
stream = g_memory_input_stream_new_from_data (g_memdup (&color, sizeof color),
|
||||
sizeof color,
|
||||
g_free);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(TIFF)];
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypeTIFF];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(PNG)];
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypePNG];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacoskeymap-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacosseat-private.h"
|
||||
|
||||
#define GDK_MOD2_MASK (1 << 4)
|
||||
#define GRIP_WIDTH 15
|
||||
@@ -206,9 +205,6 @@ fill_button_event (GdkMacosDisplay *display,
|
||||
GdkSeat *seat;
|
||||
GdkEventType type;
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer = NULL;
|
||||
GdkDeviceTool *tool = NULL;
|
||||
double *axes = NULL;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (display));
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
@@ -245,22 +241,16 @@ fill_button_event (GdkMacosDisplay *display,
|
||||
y < 0 || y > GDK_SURFACE (surface)->height))
|
||||
return NULL;
|
||||
|
||||
if (([nsevent subtype] == NSEventSubtypeTabletPoint) &&
|
||||
_gdk_macos_seat_get_tablet (GDK_MACOS_SEAT (seat), &pointer, &tool))
|
||||
axes = _gdk_macos_seat_get_tablet_axes_from_nsevent (GDK_MACOS_SEAT (seat), nsevent);
|
||||
else
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
|
||||
return gdk_button_event_new (type,
|
||||
GDK_SURFACE (surface),
|
||||
pointer,
|
||||
tool,
|
||||
gdk_seat_get_pointer (seat),
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
get_mouse_button_from_ns_event (nsevent),
|
||||
x,
|
||||
y,
|
||||
axes);
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
@@ -567,9 +557,6 @@ fill_motion_event (GdkMacosDisplay *display,
|
||||
{
|
||||
GdkSeat *seat;
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer = NULL;
|
||||
GdkDeviceTool *tool = NULL;
|
||||
double *axes = NULL;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_assert (nsevent != NULL);
|
||||
@@ -579,20 +566,14 @@ fill_motion_event (GdkMacosDisplay *display,
|
||||
state = get_keyboard_modifiers_from_ns_event (nsevent) |
|
||||
_gdk_macos_display_get_current_mouse_modifiers (display);
|
||||
|
||||
if (([nsevent subtype] == NSEventSubtypeTabletPoint) &&
|
||||
_gdk_macos_seat_get_tablet (GDK_MACOS_SEAT (seat), &pointer, &tool))
|
||||
axes = _gdk_macos_seat_get_tablet_axes_from_nsevent (GDK_MACOS_SEAT (seat), nsevent);
|
||||
else
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
|
||||
return gdk_motion_event_new (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
tool,
|
||||
gdk_seat_get_pointer (seat),
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
x,
|
||||
y,
|
||||
axes);
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
@@ -719,7 +700,7 @@ get_surface_point_from_screen_point (GdkSurface *surface,
|
||||
NSPoint point;
|
||||
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
point = convert_nspoint_from_screen (nswindow, screen_point);
|
||||
point = [nswindow convertPointFromScreen:screen_point];
|
||||
|
||||
*x = point.x;
|
||||
*y = surface->height - point.y;
|
||||
@@ -781,7 +762,7 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
GdkSurface *surface = NULL;
|
||||
NSWindow *nswindow = [nsevent window];
|
||||
|
||||
if (GDK_IS_MACOS_WINDOW (nswindow))
|
||||
if (nswindow)
|
||||
{
|
||||
GdkMacosBaseView *view;
|
||||
NSPoint point, view_point;
|
||||
@@ -840,7 +821,7 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
*screen_point = convert_nspoint_to_screen ([nsevent window], point);
|
||||
*screen_point = [(GdkMacosWindow *)[nsevent window] convertPointToScreen:point];
|
||||
*x = point.x;
|
||||
*y = surface->height - point.y;
|
||||
}
|
||||
@@ -993,11 +974,11 @@ find_surface_for_ns_event (GdkMacosDisplay *self,
|
||||
g_assert (x != NULL);
|
||||
g_assert (y != NULL);
|
||||
|
||||
view = (GdkMacosBaseView *)[[nsevent window] contentView];
|
||||
|
||||
if (!(surface = get_surface_from_ns_event (self, nsevent, &point, x, y)))
|
||||
return NULL;
|
||||
|
||||
view = (GdkMacosBaseView *)[GDK_MACOS_SURFACE (surface)->window contentView];
|
||||
|
||||
_gdk_macos_display_from_display_coords (self, point.x, point.y, &x_tmp, &y_tmp);
|
||||
|
||||
switch ((int)[nsevent type])
|
||||
@@ -1070,23 +1051,6 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We need to register the proximity event from any point on the screen
|
||||
* to properly register the devices
|
||||
* FIXME: is there a better way to detect if a tablet has been plugged?
|
||||
*/
|
||||
if (event_type == NSEventTypeTabletProximity)
|
||||
{
|
||||
GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
|
||||
_gdk_macos_seat_handle_tablet_tool_event (GDK_MACOS_SEAT (seat), nsevent);
|
||||
|
||||
/* FIXME: we might want to cache this proximity event and propagate it
|
||||
* but proximity events in gdk work at a window level while on macos
|
||||
* works at a screen level. For now we just skip them.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(surface = find_surface_for_ns_event (self, nsevent, &x, &y)))
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -547,20 +547,6 @@ _gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
|
||||
/* Raises a transient window.
|
||||
*/
|
||||
static void
|
||||
raise_transient (GdkMacosSurface *surface)
|
||||
{
|
||||
GdkMacosSurface *parent_surface = GDK_MACOS_SURFACE (GDK_SURFACE (surface)->transient_for);
|
||||
|
||||
NSWindow *parent = _gdk_macos_surface_get_native (parent_surface);
|
||||
NSWindow *window = _gdk_macos_surface_get_native (surface);
|
||||
|
||||
[parent removeChildWindow:window];
|
||||
[parent addChildWindow:window ordered:NSWindowAbove];
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_surface_became_main (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
@@ -573,9 +559,6 @@ _gdk_macos_display_surface_became_main (GdkMacosDisplay *self,
|
||||
|
||||
g_queue_push_head_link (&self->main_surfaces, &surface->main);
|
||||
|
||||
if (GDK_SURFACE (surface)->transient_for)
|
||||
raise_transient (surface);
|
||||
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ struct _GdkMacosGLContext
|
||||
NSView *dummy_view;
|
||||
|
||||
cairo_region_t *damage;
|
||||
cairo_rectangle_int_t flush_rect;
|
||||
|
||||
guint is_attached : 1;
|
||||
guint needs_resize : 1;
|
||||
|
||||
@@ -136,7 +136,7 @@ ensure_gl_view (GdkMacosGLContext *self)
|
||||
nsview = _gdk_macos_surface_get_view (surface);
|
||||
nswindow = _gdk_macos_surface_get_native (surface);
|
||||
|
||||
if G_UNLIKELY (!GDK_IS_MACOS_GL_VIEW (nsview))
|
||||
if (!GDK_IS_MACOS_GL_VIEW (nsview))
|
||||
{
|
||||
NSRect frame;
|
||||
|
||||
@@ -267,34 +267,6 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
opaque_region_covers_surface (GdkMacosGLContext *self)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
cairo_region_t *region;
|
||||
|
||||
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
|
||||
|
||||
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
|
||||
region = GDK_MACOS_SURFACE (surface)->opaque_region;
|
||||
|
||||
if (region != NULL &&
|
||||
cairo_region_num_rectangles (region) == 1)
|
||||
{
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
cairo_region_get_extents (region, &extents);
|
||||
|
||||
if (extents.x == 0 &&
|
||||
extents.y == 0 &&
|
||||
extents.width == surface->width &&
|
||||
extents.height == surface->height)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
cairo_region_t *painted)
|
||||
@@ -306,9 +278,6 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
|
||||
surface = gdk_draw_context_get_surface (context);
|
||||
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
self->damage = cairo_region_copy (painted);
|
||||
|
||||
/* If begin frame is called, that means we are trying to draw to
|
||||
* the NSWindow using our view. That might be a GdkMacosCairoView
|
||||
* but we need it to be a GL view. Also, only in this case do we
|
||||
@@ -317,7 +286,28 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
*/
|
||||
if (!self->is_attached &&
|
||||
gdk_gl_context_get_shared_context (GDK_GL_CONTEXT (context)))
|
||||
ensure_gl_view (self);
|
||||
{
|
||||
CGLContextObj glctx = [self->gl_context CGLContextObj];
|
||||
GLint swapRect[4];
|
||||
|
||||
ensure_gl_view (self);
|
||||
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
self->damage = cairo_region_copy (painted);
|
||||
|
||||
cairo_region_get_extents (painted, &self->flush_rect);
|
||||
|
||||
/* Coordinates are in display coordinates, where as flush_rect is
|
||||
* in GDK coordinates. Must flip Y to match display coordinates where
|
||||
* 0,0 is the bottom-left corner.
|
||||
*/
|
||||
swapRect[0] = self->flush_rect.x; /* left */
|
||||
swapRect[1] = surface->height - self->flush_rect.y; /* bottom */
|
||||
swapRect[2] = self->flush_rect.width; /* width */
|
||||
swapRect[3] = self->flush_rect.height; /* height */
|
||||
|
||||
CGLSetParameter (glctx, kCGLCPSwapRectangle, swapRect);
|
||||
}
|
||||
|
||||
if (self->needs_resize)
|
||||
{
|
||||
@@ -343,10 +333,6 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
else
|
||||
opaque = FALSE;
|
||||
|
||||
/* If we are maximized, we might be able to make it opaque */
|
||||
if (opaque == FALSE)
|
||||
opaque = opaque_region_covers_surface (self);
|
||||
|
||||
CGLSetParameter (cgl_context, kCGLCPSurfaceOpacity, &opaque);
|
||||
|
||||
[self->gl_context update];
|
||||
@@ -376,26 +362,7 @@ gdk_macos_gl_context_end_frame (GdkDrawContext *context,
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->end_frame (context, painted);
|
||||
|
||||
if (!self->is_attached)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (context);
|
||||
CGLContextObj glctx = [self->gl_context CGLContextObj];
|
||||
cairo_rectangle_int_t flush_rect;
|
||||
GLint swapRect[4];
|
||||
|
||||
/* Coordinates are in display coordinates, where as flush_rect is
|
||||
* in GDK coordinates. Must flip Y to match display coordinates where
|
||||
* 0,0 is the bottom-left corner.
|
||||
*/
|
||||
cairo_region_get_extents (painted, &flush_rect);
|
||||
swapRect[0] = flush_rect.x; /* left */
|
||||
swapRect[1] = surface->height - flush_rect.y; /* bottom */
|
||||
swapRect[2] = flush_rect.width; /* width */
|
||||
swapRect[3] = flush_rect.height; /* height */
|
||||
CGLSetParameter (glctx, kCGLCPSwapRectangle, swapRect);
|
||||
|
||||
[self->gl_context flushBuffer];
|
||||
}
|
||||
[self->gl_context flushBuffer];
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -145,7 +145,6 @@ GetSubpixelLayout (CGDirectDisplayID screen_id)
|
||||
static char *
|
||||
GetLocalizedName (NSScreen *screen)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
NSString *str;
|
||||
@@ -159,9 +158,6 @@ GetLocalizedName (NSScreen *screen)
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&name);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *
|
||||
|
||||
@@ -66,12 +66,6 @@ gdk_macos_popup_surface_layout (GdkMacosPopupSurface *self,
|
||||
monitor = _gdk_macos_surface_get_best_monitor (GDK_MACOS_SURFACE (self));
|
||||
gdk_macos_monitor_get_workarea (monitor, &bounds);
|
||||
|
||||
gdk_popup_layout_get_shadow_width (layout,
|
||||
&self->parent_instance.shadow_left,
|
||||
&self->parent_instance.shadow_right,
|
||||
&self->parent_instance.shadow_top,
|
||||
&self->parent_instance.shadow_bottom);
|
||||
|
||||
gdk_surface_layout_popup_helper (GDK_SURFACE (self),
|
||||
width,
|
||||
height,
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacosseat.h"
|
||||
|
||||
#include "gdkseatprivate.h"
|
||||
|
||||
@@ -31,16 +30,6 @@ G_BEGIN_DECLS
|
||||
|
||||
GdkSeat *_gdk_macos_seat_new (GdkMacosDisplay *display);
|
||||
|
||||
void _gdk_macos_seat_handle_tablet_tool_event (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent);
|
||||
|
||||
gboolean _gdk_macos_seat_get_tablet (GdkMacosSeat *seat,
|
||||
GdkDevice **device,
|
||||
GdkDeviceTool **tool);
|
||||
|
||||
double *_gdk_macos_seat_get_tablet_axes_from_nsevent (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_SEAT_PRIVATE_H__ */
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2021 Amazon.com, Inc. and its affiliates. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,606 +22,42 @@
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevicetoolprivate.h"
|
||||
#include "gdkseatdefaultprivate.h"
|
||||
|
||||
#include "gdkmacosdevice.h"
|
||||
#include "gdkmacosseat-private.h"
|
||||
|
||||
#include "gdk-private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NSUInteger device_id;
|
||||
char *name;
|
||||
|
||||
GdkDevice *logical_device;
|
||||
GdkDevice *stylus_device;
|
||||
GdkSeat *seat;
|
||||
|
||||
GdkDeviceTool *current_tool;
|
||||
|
||||
int axis_indices[GDK_AXIS_LAST];
|
||||
double axes[GDK_AXIS_LAST];
|
||||
} GdkMacosTabletData;
|
||||
|
||||
struct _GdkMacosSeat
|
||||
{
|
||||
GdkSeat parent_instance;
|
||||
|
||||
GdkMacosDisplay *display;
|
||||
|
||||
GdkDevice *logical_pointer;
|
||||
GdkDevice *logical_keyboard;
|
||||
|
||||
GdkMacosTabletData *current_tablet;
|
||||
GPtrArray *tablets;
|
||||
GPtrArray *tools;
|
||||
};
|
||||
|
||||
struct _GdkMacosSeatClass
|
||||
{
|
||||
GdkSeatClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosSeat, gdk_macos_seat, GDK_TYPE_SEAT)
|
||||
|
||||
#define KEYBOARD_EVENTS (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | \
|
||||
GDK_FOCUS_CHANGE_MASK)
|
||||
#define TOUCH_EVENTS (GDK_TOUCH_MASK)
|
||||
#define POINTER_EVENTS (GDK_POINTER_MOTION_MASK | \
|
||||
GDK_BUTTON_PRESS_MASK | \
|
||||
GDK_BUTTON_RELEASE_MASK | \
|
||||
GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK | \
|
||||
GDK_ENTER_NOTIFY_MASK | \
|
||||
GDK_LEAVE_NOTIFY_MASK | \
|
||||
GDK_PROXIMITY_IN_MASK | \
|
||||
GDK_PROXIMITY_OUT_MASK)
|
||||
|
||||
static void
|
||||
gdk_macos_tablet_data_free (gpointer user_data)
|
||||
{
|
||||
GdkMacosTabletData *tablet = user_data;
|
||||
|
||||
gdk_seat_device_removed (GDK_SEAT (tablet->seat), tablet->stylus_device);
|
||||
gdk_seat_device_removed (GDK_SEAT (tablet->seat), tablet->logical_device);
|
||||
|
||||
_gdk_device_set_associated_device (tablet->logical_device, NULL);
|
||||
_gdk_device_set_associated_device (tablet->stylus_device, NULL);
|
||||
|
||||
g_object_unref (tablet->logical_device);
|
||||
g_object_unref (tablet->stylus_device);
|
||||
|
||||
g_free (tablet->name);
|
||||
g_free (tablet);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_dispose (GObject *object)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (object);
|
||||
|
||||
if (self->logical_pointer)
|
||||
{
|
||||
gdk_seat_device_removed (GDK_SEAT (self), self->logical_pointer);
|
||||
g_clear_object (&self->logical_pointer);
|
||||
}
|
||||
|
||||
if (self->logical_keyboard)
|
||||
{
|
||||
gdk_seat_device_removed (GDK_SEAT (self), self->logical_keyboard);
|
||||
g_clear_object (&self->logical_pointer);
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->tablets, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->tools, g_ptr_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_seat_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static GdkSeatCapabilities
|
||||
gdk_macos_seat_get_capabilities (GdkSeat *seat)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
GdkSeatCapabilities caps = 0;
|
||||
|
||||
if (self->logical_pointer)
|
||||
caps |= GDK_SEAT_CAPABILITY_POINTER;
|
||||
if (self->logical_keyboard)
|
||||
caps |= GDK_SEAT_CAPABILITY_KEYBOARD;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_macos_seat_grab (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
GdkSeatCapabilities capabilities,
|
||||
gboolean owner_events,
|
||||
GdkCursor *cursor,
|
||||
GdkEvent *event,
|
||||
GdkSeatGrabPrepareFunc prepare_func,
|
||||
gpointer prepare_func_data)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
guint32 evtime = event ? gdk_event_get_time (event) : GDK_CURRENT_TIME;
|
||||
GdkGrabStatus status = GDK_GRAB_SUCCESS;
|
||||
gboolean was_visible;
|
||||
|
||||
was_visible = gdk_surface_get_mapped (surface);
|
||||
|
||||
if (prepare_func)
|
||||
(prepare_func) (seat, surface, prepare_func_data);
|
||||
|
||||
if (!gdk_surface_get_mapped (surface))
|
||||
{
|
||||
g_critical ("Surface %p has not been mapped in GdkSeatGrabPrepareFunc",
|
||||
surface);
|
||||
return GDK_GRAB_NOT_VIEWABLE;
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_ALL_POINTING)
|
||||
{
|
||||
/* ALL_POINTING spans 3 capabilities; get the mask for the ones we have */
|
||||
GdkEventMask pointer_evmask = 0;
|
||||
|
||||
/* We let tablet styli take over the pointer cursor */
|
||||
if (capabilities & (GDK_SEAT_CAPABILITY_POINTER |
|
||||
GDK_SEAT_CAPABILITY_TABLET_STYLUS))
|
||||
{
|
||||
pointer_evmask |= POINTER_EVENTS;
|
||||
}
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_TOUCH)
|
||||
pointer_evmask |= TOUCH_EVENTS;
|
||||
|
||||
status = gdk_device_grab (self->logical_pointer, surface,
|
||||
owner_events,
|
||||
pointer_evmask, cursor,
|
||||
evtime);
|
||||
}
|
||||
|
||||
if (status == GDK_GRAB_SUCCESS &&
|
||||
capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
|
||||
{
|
||||
status = gdk_device_grab (self->logical_keyboard, surface,
|
||||
owner_events,
|
||||
KEYBOARD_EVENTS, cursor,
|
||||
evtime);
|
||||
|
||||
if (status != GDK_GRAB_SUCCESS)
|
||||
{
|
||||
if (capabilities & ~GDK_SEAT_CAPABILITY_KEYBOARD)
|
||||
gdk_device_ungrab (self->logical_pointer, evtime);
|
||||
}
|
||||
}
|
||||
|
||||
if (status != GDK_GRAB_SUCCESS && !was_visible)
|
||||
gdk_surface_hide (surface);
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_ungrab (GdkSeat *seat)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
gdk_device_ungrab (self->logical_pointer, GDK_CURRENT_TIME);
|
||||
gdk_device_ungrab (self->logical_keyboard, GDK_CURRENT_TIME);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
gdk_macos_seat_get_logical_device (GdkSeat *seat,
|
||||
GdkSeatCapabilities capability)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
|
||||
/* There must be only one flag set */
|
||||
switch ((guint) capability)
|
||||
{
|
||||
case GDK_SEAT_CAPABILITY_POINTER:
|
||||
case GDK_SEAT_CAPABILITY_TOUCH:
|
||||
return self->logical_pointer;
|
||||
case GDK_SEAT_CAPABILITY_KEYBOARD:
|
||||
return self->logical_keyboard;
|
||||
default:
|
||||
g_warning ("Unhandled capability %x", capability);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GList *
|
||||
gdk_macos_seat_get_devices (GdkSeat *seat,
|
||||
GdkSeatCapabilities capabilities)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
GList *physical_devices = NULL;
|
||||
|
||||
if (self->logical_pointer && (capabilities & GDK_SEAT_CAPABILITY_POINTER))
|
||||
physical_devices = g_list_prepend (physical_devices, self->logical_pointer);
|
||||
|
||||
if (self->logical_keyboard && (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD))
|
||||
physical_devices = g_list_prepend (physical_devices, self->logical_keyboard);
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_TABLET_STYLUS)
|
||||
{
|
||||
for (guint i = 0; i < self->tablets->len; i++)
|
||||
{
|
||||
GdkMacosTabletData *tablet = g_ptr_array_index (self->tablets, i);
|
||||
|
||||
physical_devices = g_list_prepend (physical_devices, tablet->stylus_device);
|
||||
}
|
||||
}
|
||||
|
||||
return physical_devices;
|
||||
}
|
||||
|
||||
static GList *
|
||||
gdk_macos_seat_get_tools (GdkSeat *seat)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
GdkDeviceTool *tool;
|
||||
GList *tools = NULL;
|
||||
|
||||
for (guint i = 0; i < self->tools->len; i++)
|
||||
{
|
||||
tool = g_ptr_array_index (self->tools, i);
|
||||
tools = g_list_prepend (tools, tool);
|
||||
}
|
||||
|
||||
return tools;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_class_init (GdkMacosSeatClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_macos_seat_dispose;
|
||||
|
||||
seat_class->get_capabilities = gdk_macos_seat_get_capabilities;
|
||||
seat_class->grab = gdk_macos_seat_grab;
|
||||
seat_class->ungrab = gdk_macos_seat_ungrab;
|
||||
seat_class->get_logical_device = gdk_macos_seat_get_logical_device;
|
||||
seat_class->get_devices = gdk_macos_seat_get_devices;
|
||||
seat_class->get_tools = gdk_macos_seat_get_tools;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_init (GdkMacosSeat *self)
|
||||
{
|
||||
self->tablets = g_ptr_array_new_with_free_func (gdk_macos_tablet_data_free);
|
||||
self->tools = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
init_devices (GdkMacosSeat *self)
|
||||
{
|
||||
/* pointer */
|
||||
self->logical_pointer = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Pointer",
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", self->display,
|
||||
"seat", self,
|
||||
NULL);
|
||||
|
||||
/* keyboard */
|
||||
self->logical_keyboard = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Keyboard",
|
||||
"source", GDK_SOURCE_KEYBOARD,
|
||||
"has-cursor", FALSE,
|
||||
"display", self->display,
|
||||
"seat", self,
|
||||
NULL);
|
||||
|
||||
/* link both */
|
||||
_gdk_device_set_associated_device (self->logical_pointer, self->logical_keyboard);
|
||||
_gdk_device_set_associated_device (self->logical_keyboard, self->logical_pointer);
|
||||
|
||||
gdk_seat_device_added (GDK_SEAT (self), self->logical_pointer);
|
||||
gdk_seat_device_added (GDK_SEAT (self), self->logical_keyboard);
|
||||
}
|
||||
|
||||
GdkSeat *
|
||||
_gdk_macos_seat_new (GdkMacosDisplay *display)
|
||||
{
|
||||
GdkMacosSeat *self;
|
||||
GdkDevice *core_keyboard;
|
||||
GdkDevice *core_pointer;
|
||||
GdkSeat *seat;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_SEAT,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
self->display = display;
|
||||
|
||||
init_devices (self);
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
static GdkDeviceToolType
|
||||
get_device_tool_type_from_nsevent (NSEvent *nsevent)
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
|
||||
switch ([nsevent pointingDeviceType])
|
||||
{
|
||||
case NSPointingDeviceTypePen:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_PEN;
|
||||
break;
|
||||
case NSPointingDeviceTypeEraser:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_ERASER;
|
||||
break;
|
||||
case NSPointingDeviceTypeCursor:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_MOUSE;
|
||||
break;
|
||||
case NSPointingDeviceTypeUnknown:
|
||||
default:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
return tool_type;
|
||||
}
|
||||
|
||||
static GdkAxisFlags
|
||||
get_device_tool_axes_from_nsevent (NSEvent *nsevent)
|
||||
{
|
||||
/* TODO: do we need to be smarter about the capabilities? */
|
||||
return GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT | GDK_AXIS_FLAG_PRESSURE |
|
||||
GDK_AXIS_FLAG_ROTATION;
|
||||
}
|
||||
|
||||
static GdkMacosTabletData *
|
||||
create_tablet_data_from_nsevent (GdkMacosSeat *self,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosTabletData *tablet;
|
||||
GdkDisplay *display = gdk_seat_get_display (GDK_SEAT (self));
|
||||
GdkDevice *logical_device, *stylus_device;
|
||||
char *logical_name;
|
||||
char *vid, *pid;
|
||||
|
||||
tablet = g_new0 (GdkMacosTabletData, 1);
|
||||
tablet->seat = GDK_SEAT (self);
|
||||
tablet->device_id = [nsevent deviceID];
|
||||
/* FIXME: find a better name */
|
||||
tablet->name = g_strdup_printf ("Tablet %lu", [nsevent deviceID]);
|
||||
|
||||
vid = g_strdup_printf ("%.4lx", [nsevent vendorID]);
|
||||
pid = g_strdup_printf ("%.4lx", [nsevent tabletID]);
|
||||
|
||||
logical_name = g_strdup_printf ("Logical pointer for %s", tablet->name);
|
||||
logical_device = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", logical_name,
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
"seat", self,
|
||||
NULL);
|
||||
|
||||
stylus_device = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", tablet->name,
|
||||
"source", GDK_SOURCE_PEN,
|
||||
core_pointer = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Pointer",
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
NULL);
|
||||
core_keyboard = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Keyboard",
|
||||
"source", GDK_SOURCE_KEYBOARD,
|
||||
"has-cursor", FALSE,
|
||||
"display", display,
|
||||
"seat", self,
|
||||
"vendor-id", vid,
|
||||
"product-id", pid,
|
||||
NULL);
|
||||
|
||||
tablet->logical_device = logical_device;
|
||||
tablet->stylus_device = stylus_device;
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (core_pointer),
|
||||
GDK_DEVICE (core_keyboard));
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (core_keyboard),
|
||||
GDK_DEVICE (core_pointer));
|
||||
|
||||
_gdk_device_set_associated_device (logical_device, self->logical_keyboard);
|
||||
_gdk_device_set_associated_device (stylus_device, logical_device);
|
||||
seat = gdk_seat_default_new_for_logical_pair (core_pointer, core_keyboard);
|
||||
|
||||
gdk_seat_device_added (GDK_SEAT (self), logical_device);
|
||||
gdk_seat_device_added (GDK_SEAT (self), stylus_device);
|
||||
g_object_unref (core_pointer);
|
||||
g_object_unref (core_keyboard);
|
||||
|
||||
g_free (logical_name);
|
||||
g_free (vid);
|
||||
g_free (pid);
|
||||
|
||||
return tablet;
|
||||
}
|
||||
|
||||
static GdkMacosTabletData *
|
||||
get_tablet_data_from_nsevent (GdkMacosSeat *self,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosTabletData *tablet = NULL;
|
||||
|
||||
for (guint i = 0; i < self->tablets->len; i++)
|
||||
{
|
||||
GdkMacosTabletData *t = g_ptr_array_index (self->tablets, i);
|
||||
|
||||
if (t->device_id == [nsevent deviceID])
|
||||
{
|
||||
tablet = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tablet)
|
||||
tablet = create_tablet_data_from_nsevent (self, nsevent);
|
||||
|
||||
return tablet;
|
||||
}
|
||||
|
||||
static void
|
||||
device_tablet_clone_tool_axes (GdkMacosTabletData *tablet,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
int axis_pos;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (tablet->stylus_device));
|
||||
_gdk_device_reset_axes (tablet->stylus_device);
|
||||
|
||||
_gdk_device_add_axis (tablet->stylus_device, GDK_AXIS_X, 0, 0, 0);
|
||||
_gdk_device_add_axis (tablet->stylus_device, GDK_AXIS_Y, 0, 0, 0);
|
||||
|
||||
if (tool->tool_axes & (GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT))
|
||||
{
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_XTILT, -1.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_XTILT] = axis_pos;
|
||||
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_YTILT, -1.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_YTILT] = axis_pos;
|
||||
}
|
||||
|
||||
if (tool->tool_axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_PRESSURE, 0.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_PRESSURE] = axis_pos;
|
||||
}
|
||||
|
||||
if (tool->tool_axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_ROTATION, 0.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_ROTATION] = axis_pos;
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (tablet->stylus_device));
|
||||
}
|
||||
|
||||
static void
|
||||
mimic_device_axes (GdkDevice *logical,
|
||||
GdkDevice *physical)
|
||||
{
|
||||
double axis_min, axis_max, axis_resolution;
|
||||
GdkAxisUse axis_use;
|
||||
int axis_count;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (logical));
|
||||
_gdk_device_reset_axes (logical);
|
||||
axis_count = gdk_device_get_n_axes (physical);
|
||||
|
||||
for (int i = 0; i < axis_count; i++)
|
||||
{
|
||||
_gdk_device_get_axis_info (physical, i, &axis_use, &axis_min,
|
||||
&axis_max, &axis_resolution);
|
||||
_gdk_device_add_axis (logical, axis_use, axis_min,
|
||||
axis_max, axis_resolution);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (logical));
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_seat_handle_tablet_tool_event (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
GdkMacosTabletData *tablet;
|
||||
GdkDeviceTool *tool;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_SEAT (seat));
|
||||
g_return_if_fail (nsevent != NULL);
|
||||
|
||||
tablet = get_tablet_data_from_nsevent (seat, nsevent);
|
||||
|
||||
tool_type = get_device_tool_type_from_nsevent (nsevent);
|
||||
|
||||
if (tool_type == GDK_DEVICE_TOOL_TYPE_UNKNOWN)
|
||||
{
|
||||
g_warning ("Unknown device tool detected");
|
||||
return;
|
||||
}
|
||||
|
||||
tool = gdk_seat_get_tool (GDK_SEAT (seat), [nsevent tabletID], [nsevent deviceID], tool_type);
|
||||
|
||||
if ([nsevent isEnteringProximity])
|
||||
{
|
||||
if (!tool)
|
||||
{
|
||||
tool = gdk_device_tool_new ([nsevent tabletID], [nsevent vendorID], tool_type,
|
||||
get_device_tool_axes_from_nsevent (nsevent));
|
||||
g_ptr_array_add (seat->tools, tool);
|
||||
}
|
||||
|
||||
gdk_device_update_tool (tablet->stylus_device, tool);
|
||||
tablet->current_tool = tool;
|
||||
device_tablet_clone_tool_axes (tablet, tool);
|
||||
mimic_device_axes (tablet->logical_device, tablet->stylus_device);
|
||||
seat->current_tablet = tablet;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_device_update_tool (tablet->stylus_device, NULL);
|
||||
tablet->current_tool = NULL;
|
||||
seat->current_tablet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_seat_get_tablet (GdkMacosSeat *seat,
|
||||
GdkDevice **logical_device,
|
||||
GdkDeviceTool **tool)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SEAT (seat), FALSE);
|
||||
|
||||
if (!seat->current_tablet)
|
||||
return FALSE;
|
||||
|
||||
*logical_device = seat->current_tablet->logical_device;
|
||||
*tool = seat->current_tablet->current_tool;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
double *
|
||||
_gdk_macos_seat_get_tablet_axes_from_nsevent (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosTabletData *tablet;
|
||||
int axis_index;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SEAT (seat), NULL);
|
||||
g_return_val_if_fail (nsevent != NULL, NULL);
|
||||
|
||||
tablet = seat->current_tablet;
|
||||
if (!tablet || !tablet->current_tool)
|
||||
return NULL;
|
||||
|
||||
if (tablet->current_tool->tool_axes & (GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT))
|
||||
{
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent tilt].x, &tablet->axes[GDK_AXIS_XTILT]);
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent tilt].y, &tablet->axes[GDK_AXIS_YTILT]);
|
||||
}
|
||||
|
||||
if (tablet->current_tool->tool_axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent pressure], &tablet->axes[GDK_AXIS_PRESSURE]);
|
||||
}
|
||||
|
||||
if (tablet->current_tool->tool_axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent rotation], &tablet->axes[GDK_AXIS_ROTATION]);
|
||||
}
|
||||
|
||||
return g_memdup2 (tablet->axes, sizeof (double) * GDK_AXIS_LAST);
|
||||
return g_steal_pointer (&seat);
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2021 Amazon.com, Inc. and its affiliates. All Rights Reserved.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GDKMACOS_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/macos/gdkmacos.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_SEAT (gdk_macos_seat_get_type ())
|
||||
#define GDK_MACOS_SEAT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_MACOS_SEAT, GdkMacosSeat))
|
||||
#define GDK_IS_MACOS_SEAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_MACOS_SEAT))
|
||||
|
||||
typedef struct _GdkMacosSeat GdkMacosSeat;
|
||||
typedef struct _GdkMacosSeatClass GdkMacosSeatClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_seat_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
@@ -48,7 +48,6 @@ struct _GdkMacosSurface
|
||||
GdkMacosWindow *window;
|
||||
GPtrArray *monitors;
|
||||
cairo_region_t *input_region;
|
||||
cairo_region_t *opaque_region;
|
||||
char *title;
|
||||
|
||||
int root_x;
|
||||
@@ -62,7 +61,6 @@ struct _GdkMacosSurface
|
||||
gint64 pending_frame_counter;
|
||||
|
||||
guint did_initial_present : 1;
|
||||
guint geometry_dirty : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosSurfaceClass
|
||||
|
||||
@@ -98,16 +98,9 @@ static void
|
||||
gdk_macos_surface_set_opaque_region (GdkSurface *surface,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GdkMacosSurface *self = (GdkMacosSurface *)surface;
|
||||
NSView *nsview;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (region != self->opaque_region)
|
||||
{
|
||||
g_clear_pointer (&self->opaque_region, cairo_region_destroy);
|
||||
self->opaque_region = cairo_region_copy (region);
|
||||
}
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
if ((nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface))) &&
|
||||
GDK_IS_MACOS_CAIRO_VIEW (nsview))
|
||||
@@ -157,12 +150,6 @@ _gdk_macos_surface_set_shadow (GdkMacosSurface *surface,
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (self->shadow_top == top &&
|
||||
self->shadow_right == right &&
|
||||
self->shadow_bottom == bottom &&
|
||||
self->shadow_left == left)
|
||||
return;
|
||||
|
||||
self->shadow_top = top;
|
||||
self->shadow_right = right;
|
||||
self->shadow_bottom = bottom;
|
||||
@@ -393,7 +380,6 @@ gdk_macos_surface_destroy (GdkSurface *surface,
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->title, g_free);
|
||||
g_clear_pointer (&self->opaque_region, cairo_region_destroy);
|
||||
|
||||
if (window != NULL)
|
||||
[window close];
|
||||
|
||||
@@ -33,9 +33,8 @@ typedef struct _GdkMacosToplevelSurfaceClass GdkMacosToplevelSurfaceClass;
|
||||
|
||||
struct _GdkMacosToplevelSurface
|
||||
{
|
||||
GdkMacosSurface parent_instance;
|
||||
GdkToplevelLayout *layout;
|
||||
guint decorated : 1;
|
||||
GdkMacosSurface parent_instance;
|
||||
guint decorated : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosToplevelSurfaceClass
|
||||
|
||||
@@ -81,7 +81,7 @@ _gdk_macos_toplevel_surface_unmaximize (GdkMacosToplevelSurface *self)
|
||||
[window zoom:window];
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
@@ -102,18 +102,11 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
g_assert (GDK_IS_MACOS_WINDOW (nswindow));
|
||||
|
||||
if (layout != self->layout)
|
||||
{
|
||||
g_clear_pointer (&self->layout, gdk_toplevel_layout_unref);
|
||||
self->layout = gdk_toplevel_layout_copy (layout);
|
||||
}
|
||||
|
||||
_gdk_macos_toplevel_surface_attach_to_parent (self);
|
||||
|
||||
style_mask = [nswindow styleMask];
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
@@ -165,11 +158,13 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
[nswindow setStyleMask:style_mask];
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
|
||||
size.shadow.top,
|
||||
size.shadow.right,
|
||||
size.shadow.bottom,
|
||||
size.shadow.left);
|
||||
{
|
||||
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
|
||||
size.shadow.top,
|
||||
size.shadow.right,
|
||||
size.shadow.bottom,
|
||||
size.shadow.left);
|
||||
}
|
||||
|
||||
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
@@ -235,6 +230,8 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self));
|
||||
|
||||
GDK_MACOS_SURFACE (self)->did_initial_present = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -376,86 +373,6 @@ _gdk_macos_toplevel_surface_hide (GdkSurface *surface)
|
||||
GDK_SURFACE_CLASS (_gdk_macos_toplevel_surface_parent_class)->hide (surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
|
||||
GdkToplevelSize size;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
int bounds_width, bounds_height;
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
if (!GDK_MACOS_SURFACE (surface)->geometry_dirty)
|
||||
return FALSE;
|
||||
|
||||
GDK_MACOS_SURFACE (surface)->geometry_dirty = FALSE;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_macos_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
|
||||
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
|
||||
width = surface->width;
|
||||
height = surface->height;
|
||||
|
||||
if (self->layout != NULL &&
|
||||
gdk_toplevel_layout_get_resizable (self->layout))
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry.max_width = geometry.min_width = size.width;
|
||||
geometry.max_height = geometry.min_height = size.height;
|
||||
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
|
||||
}
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
|
||||
size.shadow.top,
|
||||
size.shadow.right,
|
||||
size.shadow.bottom,
|
||||
size.shadow.left);
|
||||
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
|
||||
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
|
||||
_gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_request_layout (GdkSurface *surface)
|
||||
{
|
||||
GDK_MACOS_SURFACE (surface)->geometry_dirty = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_destroy (GdkSurface *surface,
|
||||
gboolean foreign_destroy)
|
||||
@@ -463,7 +380,6 @@ _gdk_macos_toplevel_surface_destroy (GdkSurface *surface,
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
|
||||
|
||||
g_clear_object (&GDK_SURFACE (self)->transient_for);
|
||||
g_clear_pointer (&self->layout, gdk_toplevel_layout_unref);
|
||||
|
||||
GDK_SURFACE_CLASS (_gdk_macos_toplevel_surface_parent_class)->destroy (surface, foreign_destroy);
|
||||
}
|
||||
@@ -590,8 +506,6 @@ _gdk_macos_toplevel_surface_class_init (GdkMacosToplevelSurfaceClass *klass)
|
||||
|
||||
surface_class->destroy = _gdk_macos_toplevel_surface_destroy;
|
||||
surface_class->hide = _gdk_macos_toplevel_surface_hide;
|
||||
surface_class->compute_size = _gdk_macos_toplevel_surface_compute_size;
|
||||
surface_class->request_layout = _gdk_macos_toplevel_surface_request_layout;
|
||||
|
||||
gdk_toplevel_install_properties (object_class, LAST_PROP);
|
||||
}
|
||||
|
||||
@@ -40,36 +40,5 @@ struct _GdkPoint
|
||||
};
|
||||
typedef struct _GdkPoint GdkPoint;
|
||||
|
||||
static inline NSPoint
|
||||
convert_nspoint_from_screen (NSWindow *window,
|
||||
NSPoint point)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
return [window convertPointFromScreen:point];
|
||||
#else
|
||||
/* Apple documentation claims that convertPointFromScreen is available
|
||||
* on 10.12+. However, that doesn't seem to be the case when using it.
|
||||
* Instead, we'll just use it on modern 10.15 systems and fallback to
|
||||
* converting using rects on older systems.
|
||||
*/
|
||||
return [window convertRectFromScreen:NSMakeRect (point.x, point.y, 0, 0)].origin;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline NSPoint
|
||||
convert_nspoint_to_screen (NSWindow *window,
|
||||
NSPoint point)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
return [window convertPointToScreen:point];
|
||||
#else
|
||||
/* Apple documentation claims that convertPointToScreen is available
|
||||
* on 10.12+. However, that doesn't seem to be the case when using it.
|
||||
* Instead, we'll just use it on modern 10.15 systems and fallback to
|
||||
* converting using rects on older systems.
|
||||
*/
|
||||
return [window convertRectToScreen:NSMakeRect (point.x, point.y, 0, 0)].origin;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __GDK_MACOS_UTILS_PRIVATE_H__ */
|
||||
|
||||
@@ -33,7 +33,6 @@ gdk_macos_public_headers = files([
|
||||
'gdkmacosglcontext.h',
|
||||
'gdkmacoskeymap.h',
|
||||
'gdkmacosmonitor.h',
|
||||
'gdkmacosseat.h',
|
||||
'gdkmacossurface.h',
|
||||
])
|
||||
|
||||
|
||||
@@ -39,8 +39,6 @@
|
||||
#include "gdkdropprivate.h"
|
||||
#include "gdkprimary-wayland.h"
|
||||
#include "gdkseatprivate.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
|
||||
@@ -2359,9 +2357,6 @@ touch_handle_down (void *data,
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
if (!wl_surface)
|
||||
return;
|
||||
|
||||
touch = gdk_wayland_seat_add_touch (seat, id, wl_surface);
|
||||
touch->x = wl_fixed_to_double (x);
|
||||
touch->y = wl_fixed_to_double (y);
|
||||
@@ -2409,9 +2404,6 @@ touch_handle_up (void *data,
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
touch = gdk_wayland_seat_get_touch (seat, id);
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
event = gdk_touch_event_new (GDK_TOUCH_END,
|
||||
GDK_SLOT_TO_EVENT_SEQUENCE (touch->id),
|
||||
touch->surface,
|
||||
@@ -2450,9 +2442,6 @@ touch_handle_motion (void *data,
|
||||
GdkEvent *event;
|
||||
|
||||
touch = gdk_wayland_seat_get_touch (seat, id);
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
touch->x = wl_fixed_to_double (x);
|
||||
touch->y = wl_fixed_to_double (y);
|
||||
|
||||
@@ -3392,14 +3381,9 @@ tablet_tool_handle_proximity_in (void *data,
|
||||
GdkWaylandTabletData *tablet = zwp_tablet_v2_get_user_data (wp_tablet);
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkSurface *surface;
|
||||
GdkSurface *surface = wl_surface_get_user_data (wsurface);
|
||||
GdkEvent *event;
|
||||
|
||||
if (!wsurface)
|
||||
return;
|
||||
|
||||
surface = wl_surface_get_user_data (wsurface);
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
if (!GDK_IS_SURFACE (surface))
|
||||
@@ -3443,9 +3427,6 @@ tablet_tool_handle_proximity_out (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
GDK_SEAT_NOTE (tool->seat, EVENTS,
|
||||
g_message ("proximity out, seat %p, tool %d", tool->seat,
|
||||
gdk_device_tool_get_tool_type (tool->tool)));
|
||||
@@ -3474,7 +3455,8 @@ tablet_tool_handle_proximity_out (void *data,
|
||||
static double *
|
||||
tablet_copy_axes (GdkWaylandTabletData *tablet)
|
||||
{
|
||||
return g_memdup2 (tablet->axes, sizeof (double) * GDK_AXIS_LAST);
|
||||
return g_memdup (tablet->axes,
|
||||
sizeof (double) * GDK_AXIS_LAST);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3508,7 +3490,7 @@ tablet_tool_handle_down (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
if (!tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
_gdk_wayland_display_update_serial (display_wayland, serial);
|
||||
@@ -3525,7 +3507,7 @@ tablet_tool_handle_up (void *data,
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
if (!tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet_create_button_event_frame (tablet, GDK_BUTTON_RELEASE, GDK_BUTTON_PRIMARY);
|
||||
@@ -3542,9 +3524,6 @@ tablet_tool_handle_motion (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
tablet->pointer_info.surface_x = wl_fixed_to_double (sx);
|
||||
tablet->pointer_info.surface_y = wl_fixed_to_double (sy);
|
||||
|
||||
@@ -3572,12 +3551,7 @@ tablet_tool_handle_pressure (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
pressure, &tablet->axes[GDK_AXIS_PRESSURE]);
|
||||
@@ -3594,12 +3568,7 @@ tablet_tool_handle_distance (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
distance, &tablet->axes[GDK_AXIS_DISTANCE]);
|
||||
@@ -3617,14 +3586,8 @@ tablet_tool_handle_tilt (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int xtilt_axis_index;
|
||||
int ytilt_axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
int xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
int ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, xtilt_axis_index,
|
||||
wl_fixed_to_double (xtilt),
|
||||
@@ -3651,7 +3614,7 @@ tablet_tool_handle_button (void *data,
|
||||
GdkEventType evtype;
|
||||
guint n_button;
|
||||
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
if (!tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet->pointer_info.press_serial = serial;
|
||||
@@ -3682,12 +3645,7 @@ tablet_tool_handle_rotation (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
wl_fixed_to_double (degrees),
|
||||
@@ -3706,12 +3664,7 @@ tablet_tool_handle_slider (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
position, &tablet->axes[GDK_AXIS_SLIDER]);
|
||||
@@ -3729,14 +3682,9 @@ tablet_tool_handle_wheel (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkWaylandSeat *seat;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("tablet tool %d wheel %d/%d",
|
||||
gdk_device_tool_get_tool_type (tool->tool), degrees, clicks));
|
||||
@@ -3776,9 +3724,6 @@ tablet_tool_handle_frame (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *frame_event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
GDK_SEAT_NOTE (tablet->seat, EVENTS,
|
||||
g_message ("tablet frame, time %d", time));
|
||||
|
||||
@@ -4367,9 +4312,6 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pointer->pointer_surface_outputs)
|
||||
return;
|
||||
|
||||
scale = 1;
|
||||
for (l = pointer->pointer_surface_outputs; l != NULL; l = l->next)
|
||||
{
|
||||
@@ -4377,8 +4319,6 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
|
||||
if (pointer->current_output_scale == scale)
|
||||
return;
|
||||
pointer->current_output_scale = scale;
|
||||
|
||||
gdk_wayland_device_update_surface_cursor (device);
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
#define MIN_SYSTEM_BELL_DELAY_MS 20
|
||||
|
||||
#define GTK_SHELL1_VERSION 4
|
||||
#define GTK_SHELL1_VERSION 3
|
||||
#define OUTPUT_VERSION_WITH_DONE 2
|
||||
#define NO_XDG_OUTPUT_DONE_SINCE_VERSION 3
|
||||
|
||||
@@ -339,48 +339,6 @@ get_format_name (enum wl_shm_format format)
|
||||
FORMAT(YVU422),
|
||||
FORMAT(YUV444),
|
||||
FORMAT(YVU444),
|
||||
FORMAT(R8),
|
||||
FORMAT(R16),
|
||||
FORMAT(RG88),
|
||||
FORMAT(GR88),
|
||||
FORMAT(RG1616),
|
||||
FORMAT(GR1616),
|
||||
FORMAT(XRGB16161616F),
|
||||
FORMAT(XBGR16161616F),
|
||||
FORMAT(ARGB16161616F),
|
||||
FORMAT(ABGR16161616F),
|
||||
FORMAT(XYUV8888),
|
||||
FORMAT(VUY888),
|
||||
FORMAT(VUY101010),
|
||||
FORMAT(Y210),
|
||||
FORMAT(Y212),
|
||||
FORMAT(Y216),
|
||||
FORMAT(Y410),
|
||||
FORMAT(Y412),
|
||||
FORMAT(Y416),
|
||||
FORMAT(XVYU12_16161616),
|
||||
FORMAT(XVYU16161616),
|
||||
FORMAT(Y0L0),
|
||||
FORMAT(X0L0),
|
||||
FORMAT(Y0L2),
|
||||
FORMAT(X0L2),
|
||||
FORMAT(YUV420_8BIT),
|
||||
FORMAT(YUV420_10BIT),
|
||||
FORMAT(XRGB8888_A8),
|
||||
FORMAT(XBGR8888_A8),
|
||||
FORMAT(RGBX8888_A8),
|
||||
FORMAT(BGRX8888_A8),
|
||||
FORMAT(RGB888_A8),
|
||||
FORMAT(BGR888_A8),
|
||||
FORMAT(RGB565_A8),
|
||||
FORMAT(BGR565_A8),
|
||||
FORMAT(NV24),
|
||||
FORMAT(NV42),
|
||||
FORMAT(P210),
|
||||
FORMAT(P010),
|
||||
FORMAT(P012),
|
||||
FORMAT(P016),
|
||||
|
||||
{ 0xffffffff, NULL }
|
||||
};
|
||||
#undef FORMAT
|
||||
@@ -1392,23 +1350,21 @@ _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
|
||||
data->buffer = NULL;
|
||||
data->scale = scale;
|
||||
|
||||
stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width * scale);
|
||||
stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width*scale);
|
||||
|
||||
data->pool = create_shm_pool (display->shm,
|
||||
height * scale * stride,
|
||||
height*scale*stride,
|
||||
&data->buf_length,
|
||||
&data->buf);
|
||||
if (G_UNLIKELY (data->pool == NULL))
|
||||
g_error ("Unable to create shared memory pool");
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data->buf,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width * scale,
|
||||
height * scale,
|
||||
width*scale,
|
||||
height*scale,
|
||||
stride);
|
||||
|
||||
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
||||
width * scale, height * scale,
|
||||
width*scale, height*scale,
|
||||
stride, WL_SHM_FORMAT_ARGB8888);
|
||||
|
||||
cairo_surface_set_user_data (surface, &gdk_wayland_shm_surface_cairo_key,
|
||||
@@ -1590,11 +1546,15 @@ update_xft_settings (GdkDisplay *display)
|
||||
}
|
||||
else
|
||||
{
|
||||
TranslationEntry *entry;
|
||||
GSettingsSchemaSource *source;
|
||||
GSettingsSchema *schema;
|
||||
|
||||
entry = find_translation_entry_by_schema ("org.gnome.desktop.interface", "font-antialiasing");
|
||||
source = g_settings_schema_source_get_default ();
|
||||
schema = g_settings_schema_source_lookup (source,
|
||||
"org.gnome.desktop.interface",
|
||||
FALSE);
|
||||
|
||||
if (entry && entry->valid)
|
||||
if (schema && g_settings_schema_has_key (schema, "font-antialiasing"))
|
||||
{
|
||||
settings = g_hash_table_lookup (display_wayland->settings,
|
||||
"org.gnome.desktop.interface");
|
||||
@@ -1618,6 +1578,9 @@ update_xft_settings (GdkDisplay *display)
|
||||
order = GSD_FONT_RGBA_ORDER_RGB;
|
||||
}
|
||||
|
||||
if (schema)
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
dpi = get_dpi_from_gsettings (display_wayland) * 1024;
|
||||
}
|
||||
|
||||
@@ -1873,7 +1836,6 @@ settings_portal_changed (GDBusProxy *proxy,
|
||||
char *a = g_variant_print (value, FALSE);
|
||||
g_debug ("Using changed portal setting %s %s: %s", namespace, name, a);
|
||||
g_free (a);
|
||||
entry->valid = TRUE;
|
||||
apply_portal_setting (entry, value, display);
|
||||
gdk_display_setting_changed (display, entry->setting);
|
||||
}
|
||||
|
||||