Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d233b10559 | |||
| b4f9f252d7 | |||
| 373c06b148 | |||
| c84cd97fbc | |||
| 6b7d295cfe | |||
| 481d438380 | |||
| f4e1057431 | |||
| fa0166180e | |||
| 13d84c202b | |||
| 5846794075 | |||
| 201da90e23 | |||
| 8d4fcabf01 | |||
| 3f8735a488 | |||
| a4dc248512 | |||
| ef451b056a | |||
| 59aaabb161 | |||
| 663ca21328 | |||
| 77435d31fa | |||
| 6edb8f096f | |||
| c4dfee8860 | |||
| 8ac1e77c9a | |||
| 65ceb6c15a | |||
| f70d10f6ac | |||
| 0bbd083d79 | |||
| 102d2986c6 | |||
| c74201ca87 | |||
| b09019a5b4 | |||
| 1dd08ad8db | |||
| eb0704855f | |||
| c4c1d4a1b3 | |||
| e6756f605e | |||
| 1f4b8e089e | |||
| c0e08db739 | |||
| 1c337d350d | |||
| 81e675dfbf | |||
| 8556221429 | |||
| 1b4109a7fd | |||
| df0786be7a | |||
| 3f545da08d |
+2
-18
@@ -19,8 +19,8 @@ variables:
|
||||
COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true -Dvulkan=yes"
|
||||
FEATURE_FLAGS: "-Dcloudproviders=true"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v20"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 2
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v17"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
|
||||
|
||||
@@ -180,22 +180,6 @@ static-scan:
|
||||
- _scan_build/meson-logs
|
||||
allow_failure: true
|
||||
|
||||
# Run tests with the address sanitizer. We need to turn off introspection,
|
||||
# since it is incompatible with asan
|
||||
asan-build:
|
||||
image: $FEDORA_IMAGE
|
||||
tags: [ asan ]
|
||||
stage: analysis
|
||||
variables:
|
||||
script:
|
||||
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=false _build
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/meson-logs
|
||||
allow_failure: true
|
||||
|
||||
reference:
|
||||
image: $DOCS_IMAGE
|
||||
stage: docs
|
||||
|
||||
@@ -35,13 +35,4 @@ branch, as well as their available versions.
|
||||
- [ ] Add the new job to `.gitlab-ci.yml` referencing the image
|
||||
- [ ] Open a merge request with your changes and let it run
|
||||
|
||||
### Checklist for Adding a new dependency to a CI image
|
||||
|
||||
Our images are layered, and the base (called fedora-base) contains
|
||||
all the rpm payload. Therefore, adding a new dependency is a 2-step
|
||||
process:
|
||||
|
||||
1. [ ] Build and upload fedora-base:$version+1
|
||||
1. [ ] Build and upload fedora:$version+1 based on fedora-base:version+1
|
||||
|
||||
[registry]: https://gitlab.gnome.org/GNOME/gtk/container_registry
|
||||
|
||||
@@ -41,14 +41,12 @@ RUN dnf -y install \
|
||||
itstool \
|
||||
json-glib-devel \
|
||||
lcov \
|
||||
libasan \
|
||||
libattr-devel \
|
||||
libepoxy-devel \
|
||||
libffi-devel \
|
||||
libmount-devel \
|
||||
librsvg2 \
|
||||
libselinux-devel \
|
||||
libubsan \
|
||||
libXcomposite-devel \
|
||||
libXcursor-devel \
|
||||
libXcursor-devel \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v20
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
|
||||
|
||||
ARG HOST_USER_ID=5555
|
||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
||||
|
||||
@@ -7,14 +7,10 @@ srcdir=$( pwd )
|
||||
builddir=$1
|
||||
backend=$2
|
||||
|
||||
# Ignore memory leaks lower in dependencies
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp
|
||||
|
||||
case "${backend}" in
|
||||
x11)
|
||||
xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
@@ -34,7 +30,6 @@ case "${backend}" in
|
||||
export WAYLAND_DISPLAY=wayland-5
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
@@ -53,7 +48,6 @@ case "${backend}" in
|
||||
export BROADWAY_DISPLAY=:5
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
|
||||
@@ -1,89 +1,3 @@
|
||||
Overview of Changes in GTK 3.99.0
|
||||
=================================
|
||||
|
||||
* Add GtkEditableLabel, a label that can be edited
|
||||
|
||||
* Add GtkBookmarkList, a list model for bookmarks
|
||||
|
||||
* Add GtkStringList, a list model for strings
|
||||
|
||||
* Add GtkBitset, and use it for representing selections
|
||||
|
||||
* GtkTreeView:
|
||||
- Make cell editing work again
|
||||
|
||||
* GtkSpinButton:
|
||||
- Make autosizing work again
|
||||
|
||||
* Printing:
|
||||
- Use GtkDropDown in the print dialog
|
||||
|
||||
* GtkApplication
|
||||
- Support opening files on OS X
|
||||
|
||||
* GtkFileChooser:
|
||||
- Fix libcloudproviders support
|
||||
- Turn GtkFileFilter into a GtkFilter
|
||||
- Simplify the api
|
||||
|
||||
* GtkGridView, GtkListView:
|
||||
- Improve scrolling behavior
|
||||
- Autoscroll and autoexpand during DND
|
||||
|
||||
* GtkScrolledWindow:
|
||||
- Make autoscrolling work again
|
||||
|
||||
* GtkFilterListModel:
|
||||
- Add incremental filtering
|
||||
|
||||
* GtkSortListModel:
|
||||
- Use timsort
|
||||
- Add various tweaks that massively speed up sorting
|
||||
- Add incremental sorting
|
||||
|
||||
* GtkWidget:
|
||||
- Massively speed up action handling
|
||||
|
||||
* GtkEntry:
|
||||
- Make entry completion work again
|
||||
- Drop action support from GtkEntryCompletion
|
||||
|
||||
* Inspector:
|
||||
- Improve list model support
|
||||
- Add direct navigation between objects
|
||||
|
||||
* GDK:
|
||||
- Compress scroll events
|
||||
- Keep a scroll history
|
||||
- Clean up GdkDevice api
|
||||
- Improve frame clock accuracy
|
||||
- Add a new macOS backend
|
||||
|
||||
* GSK:
|
||||
- Use GL_ARB_framebuffer_object
|
||||
|
||||
* gtk-demo:
|
||||
- Add incremental refill to the color grid
|
||||
- Improve performance of the color grid
|
||||
- Add an incrementally filtering word list
|
||||
- Improve the sidebar
|
||||
|
||||
* Install print-editor as another demo
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Catalan
|
||||
Chinese
|
||||
Japanese
|
||||
Kazakh
|
||||
Lithuanian
|
||||
Polish
|
||||
Romanian
|
||||
Spanish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in GTK 3.98.5
|
||||
=================================
|
||||
|
||||
|
||||
@@ -1,38 +1,29 @@
|
||||
{
|
||||
"app-id" : "org.gtk.WidgetFactory4",
|
||||
"runtime" : "org.gnome.Platform",
|
||||
"runtime-version" : "master",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "gtk4-widget-factory",
|
||||
"tags" : [
|
||||
"devel",
|
||||
"development",
|
||||
"nightly"
|
||||
],
|
||||
"desktop-file-name-prefix" : "(Development) ",
|
||||
"finish-args" : [
|
||||
"app-id": "org.gtk.WidgetFactory4",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-widget-factory",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--talk-name=org.gtk.vfs",
|
||||
"--talk-name=org.gtk.vfs.*"
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
||||
],
|
||||
"cleanup" : [
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig",
|
||||
"/share/pkgconfig",
|
||||
"/lib/pkgconfig", "/share/pkgconfig",
|
||||
"/share/aclocal",
|
||||
"/man",
|
||||
"/share/man",
|
||||
"/share/gtk-doc",
|
||||
"*.la",
|
||||
".a",
|
||||
"/man", "/share/man", "/share/gtk-doc",
|
||||
"*.la", ".a",
|
||||
"/lib/girepository-1.0",
|
||||
"/share/gir-1.0",
|
||||
"/share/doc"
|
||||
],
|
||||
"modules" : [
|
||||
"modules": [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
@@ -48,18 +39,18 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "graphene",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
],
|
||||
"sources" : [
|
||||
"sources": [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/ebassi/graphene.git"
|
||||
"type": "git",
|
||||
"url": "https://github.com/ebassi/graphene.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -67,7 +58,7 @@
|
||||
"name" : "libsass",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -82,7 +73,7 @@
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -94,23 +85,18 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"name": "gtk",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
"sources": [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -15,13 +15,7 @@ if 'DESTDIR' not in os.environ:
|
||||
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
glib_compile_schemas = subprocess.check_output(['pkg-config',
|
||||
'--variable=glib_compile_schemas',
|
||||
'gio-2.0']).strip()
|
||||
if not os.path.exists(glib_compile_schemas):
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
glib_compile_schemas = 'glib-compile-schemas'
|
||||
subprocess.call([glib_compile_schemas,
|
||||
subprocess.call(['glib-compile-schemas',
|
||||
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
|
||||
|
||||
print('Updating icon cache...')
|
||||
@@ -30,14 +24,8 @@ if 'DESTDIR' not in os.environ:
|
||||
|
||||
print('Updating module cache for print backends...')
|
||||
os.makedirs(gtk_printmodule_dir, exist_ok=True)
|
||||
gio_querymodules = subprocess.check_output(['pkg-config',
|
||||
'--variable=gio_querymodules',
|
||||
'gio-2.0']).strip()
|
||||
if not os.path.exists(gio_querymodules):
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
gio_querymodules = 'gio-querymodules'
|
||||
subprocess.call([gio_querymodules, gtk_printmodule_dir])
|
||||
subprocess.call(['gio-querymodules', gtk_printmodule_dir])
|
||||
|
||||
print('Updating module cache for input methods...')
|
||||
os.makedirs(gtk_immodule_dir, exist_ok=True)
|
||||
subprocess.call([gio_querymodules, gtk_immodule_dir])
|
||||
subprocess.call(['gio-querymodules', gtk_immodule_dir])
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
|
||||
@@ -188,7 +188,7 @@ constraint_view_init (ConstraintView *self)
|
||||
g_list_store_append (list, children);
|
||||
g_list_store_append (list, guides);
|
||||
g_list_store_append (list, constraints);
|
||||
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list)));
|
||||
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)));
|
||||
g_object_unref (children);
|
||||
g_object_unref (guides);
|
||||
g_object_unref (constraints);
|
||||
|
||||
@@ -140,7 +140,6 @@
|
||||
</gresource>
|
||||
<gresource prefix="/listview_colors">
|
||||
<file compressed="true">color.names.txt</file>
|
||||
<file>listview_colors.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/shortcuts">
|
||||
<file>shortcuts.ui</file>
|
||||
|
||||
+12
-78
@@ -597,83 +597,6 @@ css_button_new (const char *class)
|
||||
return button;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
GdkRGBA color;
|
||||
} ColorSwatch;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
} ColorSwatchClass;
|
||||
|
||||
G_DEFINE_TYPE (ColorSwatch, color_swatch, GTK_TYPE_WIDGET)
|
||||
|
||||
static GdkContentProvider *
|
||||
color_swatch_drag_prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
ColorSwatch *swatch)
|
||||
{
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_RGBA, &swatch->color);
|
||||
}
|
||||
|
||||
static void
|
||||
color_swatch_init (ColorSwatch *swatch)
|
||||
{
|
||||
GtkDragSource *source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (color_swatch_drag_prepare), swatch);
|
||||
gtk_widget_add_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
|
||||
static void
|
||||
color_swatch_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
ColorSwatch *swatch = (ColorSwatch *)widget;
|
||||
float w = gtk_widget_get_width (widget);
|
||||
float h = gtk_widget_get_height (widget);
|
||||
|
||||
gtk_snapshot_append_color (snapshot, &swatch->color,
|
||||
&GRAPHENE_RECT_INIT(0, 0, w, h));
|
||||
}
|
||||
|
||||
void
|
||||
color_swatch_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum_size,
|
||||
int *natural_size,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
*minimum_size = *natural_size = 48;
|
||||
else
|
||||
*minimum_size = *natural_size = 32;
|
||||
}
|
||||
|
||||
static void
|
||||
color_swatch_class_init (ColorSwatchClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
widget_class->snapshot = color_swatch_snapshot;
|
||||
widget_class->measure = color_swatch_measure;
|
||||
gtk_widget_class_set_css_name (widget_class, "colorswatch");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
color_swatch_new (const char *color)
|
||||
{
|
||||
ColorSwatch *swatch = g_object_new (color_swatch_get_type (), NULL);
|
||||
|
||||
gdk_rgba_parse (&swatch->color, color);
|
||||
|
||||
return GTK_WIDGET (swatch);
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
@@ -747,7 +670,18 @@ do_dnd (GtkWidget *do_widget)
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), box3);
|
||||
|
||||
for (i = 0; colors[i]; i++)
|
||||
gtk_box_append (GTK_BOX (box3), color_swatch_new (colors[i]));
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
GtkWidget *swatch;
|
||||
|
||||
gdk_rgba_parse (&rgba, colors[i]);
|
||||
|
||||
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
|
||||
"rgba", &rgba,
|
||||
"selectable", FALSE,
|
||||
NULL);
|
||||
gtk_box_append (GTK_BOX (box3), swatch);
|
||||
}
|
||||
|
||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow1"));
|
||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow2"));
|
||||
|
||||
+23
-238
@@ -1,15 +1,13 @@
|
||||
/* Lists/Selections
|
||||
/* Drop Downs
|
||||
*
|
||||
* The GtkDropDown and GtkSuggestionEntry widgets are modern
|
||||
* alternatives to GtkComboBox and GtkEntryCompletion.
|
||||
*
|
||||
* They use list models instead of tree models, and the content
|
||||
* is displayed using widgets instead of cell renderers.
|
||||
* The GtkDropDown widget is a modern alternative to GtkComboBox.
|
||||
* It uses list models instead of tree models, and the content is
|
||||
* displayed using widgets instead of cell renderers.
|
||||
*
|
||||
* The examples here demonstrate how to use different kinds of
|
||||
* list models with GtkDropDown and GtkSuggestionEntry, how to
|
||||
* use search and how to display the selected item differently
|
||||
* from the presentation in the popup.
|
||||
* list models with GtkDropDown, how to use search and how to
|
||||
* display the selected item differently from the presentation
|
||||
* in the popup.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -94,7 +92,7 @@ strings_setup_item_full (GtkSignalListItemFactory *factory,
|
||||
gtk_label_set_xalign (GTK_LABEL (title), 0.0);
|
||||
description = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (description), 0.0);
|
||||
gtk_widget_add_css_class (description, "dim-label");
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (description), "dim-label");
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
||||
@@ -220,110 +218,13 @@ get_title (gpointer item)
|
||||
return g_strdup (STRING_HOLDER (item)->title);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_file_name (gpointer item)
|
||||
{
|
||||
return g_strdup (g_file_info_get_display_name (G_FILE_INFO (item)));
|
||||
}
|
||||
|
||||
static void
|
||||
setup_item (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *icon;
|
||||
GtkWidget *label;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
icon = gtk_image_new ();
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_box_append (GTK_BOX (box), icon);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
gtk_list_item_set_child (item, box);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_item (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkMatchObject *match = GTK_MATCH_OBJECT (gtk_list_item_get_item (item));
|
||||
GFileInfo *info = G_FILE_INFO (gtk_match_object_get_item (match));
|
||||
GtkWidget *box = gtk_list_item_get_child (item);
|
||||
GtkWidget *icon = gtk_widget_get_first_child (box);
|
||||
GtkWidget *label = gtk_widget_get_last_child (box);
|
||||
|
||||
gtk_image_set_from_gicon (GTK_IMAGE (icon), g_file_info_get_icon (info));
|
||||
gtk_label_set_label (GTK_LABEL (label), g_file_info_get_display_name (info));
|
||||
}
|
||||
|
||||
static void
|
||||
setup_highlight_item (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_list_item_set_child (item, label);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_highlight_item (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkMatchObject *obj;
|
||||
GtkWidget *label;
|
||||
PangoAttrList *attrs;
|
||||
PangoAttribute *attr;
|
||||
const char *str;
|
||||
|
||||
obj = GTK_MATCH_OBJECT (gtk_list_item_get_item (item));
|
||||
label = gtk_list_item_get_child (item);
|
||||
|
||||
str = gtk_match_object_get_string (obj);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (label), str);
|
||||
attrs = pango_attr_list_new ();
|
||||
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
||||
attr->start_index = gtk_match_object_get_match_start (obj);
|
||||
attr->end_index = gtk_match_object_get_match_end (obj);
|
||||
pango_attr_list_insert (attrs, attr);
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
}
|
||||
|
||||
static void
|
||||
match_func (GtkMatchObject *obj,
|
||||
const char *search,
|
||||
gpointer user_data)
|
||||
{
|
||||
char *tmp1, *tmp2;
|
||||
char *p;
|
||||
|
||||
tmp1 = g_utf8_normalize (gtk_match_object_get_string (obj), -1, G_NORMALIZE_ALL);
|
||||
tmp2 = g_utf8_normalize (search, -1, G_NORMALIZE_ALL);
|
||||
|
||||
if ((p = strstr (tmp1, tmp2)) != NULL)
|
||||
gtk_match_object_set_match (obj,
|
||||
p - tmp1,
|
||||
(p - tmp1) + g_utf8_strlen (search, -1),
|
||||
1);
|
||||
else
|
||||
gtk_match_object_set_match (obj, 0, 0, 0);
|
||||
|
||||
g_free (tmp1);
|
||||
g_free (tmp2);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_dropdown (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *button, *box, *spin, *check, *hbox, *label, *entry;
|
||||
GtkWidget *button, *box, *spin, *check;
|
||||
GListModel *model;
|
||||
GtkExpression *expression;
|
||||
GtkListItemFactory *factory;
|
||||
const char * const times[] = { "1 minute", "2 minutes", "5 minutes", "20 minutes", NULL };
|
||||
const char * const many_times[] = {
|
||||
"1 minute", "2 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes",
|
||||
@@ -336,51 +237,23 @@ do_dropdown (GtkWidget *do_widget)
|
||||
const char * const device_descriptions[] = {
|
||||
"Built-in Audio", "Built-in audio", "Thinkpad Tunderbolt 3 Dock USB Audio", "Thinkpad Tunderbolt 3 Dock USB Audio", NULL
|
||||
};
|
||||
char *cwd;
|
||||
GFile *file;
|
||||
GListModel *dir;
|
||||
GtkStringList *strings;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Selections");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Drop Downs");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 20);
|
||||
|
||||
gtk_widget_set_margin_start (hbox, 20);
|
||||
gtk_widget_set_margin_end (hbox, 20);
|
||||
gtk_widget_set_margin_top (hbox, 20);
|
||||
gtk_widget_set_margin_bottom (hbox, 20);
|
||||
gtk_window_set_child (GTK_WINDOW (window), hbox);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_box_append (GTK_BOX (hbox), box);
|
||||
gtk_widget_set_margin_start (box, 10);
|
||||
gtk_widget_set_margin_end (box, 10);
|
||||
gtk_widget_set_margin_top (box, 10);
|
||||
gtk_widget_set_margin_bottom (box, 10);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
label = gtk_label_new ("Dropdowns");
|
||||
gtk_widget_add_css_class (label, "title-4");
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
/* A basic dropdown */
|
||||
button = drop_down_new_from_strings (times, NULL, NULL);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
/* A dropdown using an expression to obtain strings */
|
||||
button = drop_down_new_from_strings (many_times, NULL, NULL);
|
||||
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
|
||||
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
|
||||
0, NULL,
|
||||
(GCallback)get_title,
|
||||
NULL, NULL);
|
||||
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
|
||||
gtk_expression_unref (expression);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
/* A dropdown using a non-trivial model, and search */
|
||||
button = gtk_drop_down_new ();
|
||||
|
||||
model = G_LIST_MODEL (pango_cairo_font_map_get_default ());
|
||||
@@ -397,118 +270,30 @@ do_dropdown (GtkWidget *do_widget)
|
||||
|
||||
spin = gtk_spin_button_new_with_range (-1, g_list_model_get_n_items (G_LIST_MODEL (model)), 1);
|
||||
gtk_widget_set_halign (spin, GTK_ALIGN_START);
|
||||
gtk_widget_set_margin_start (spin, 20);
|
||||
g_object_bind_property (button, "selected", spin, "value", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
|
||||
gtk_box_append (GTK_BOX (box), spin);
|
||||
|
||||
check = gtk_check_button_new_with_label ("Enable search");
|
||||
gtk_widget_set_margin_start (check, 20);
|
||||
g_object_bind_property (button, "enable-search", check, "active", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
|
||||
gtk_box_append (GTK_BOX (box), check);
|
||||
|
||||
g_object_unref (model);
|
||||
|
||||
/* A dropdown with a separate list factory */
|
||||
button = drop_down_new_from_strings (device_titles, device_icons, device_descriptions);
|
||||
button = drop_down_new_from_strings (times, NULL, NULL);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
gtk_box_append (GTK_BOX (hbox), gtk_separator_new (GTK_ORIENTATION_VERTICAL));
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_box_append (GTK_BOX (hbox), box);
|
||||
|
||||
label = gtk_label_new ("Suggestions");
|
||||
gtk_widget_add_css_class (label, "title-4");
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
/* A basic suggestion entry */
|
||||
entry = gtk_suggestion_entry_new ();
|
||||
g_object_set (entry, "placeholder-text", "Words with T or G…", NULL);
|
||||
strings = gtk_string_list_new ((const char *[]){
|
||||
"GNOME",
|
||||
"gnominious",
|
||||
"Gnomonic projection",
|
||||
"total",
|
||||
"totally",
|
||||
"toto",
|
||||
"tottery",
|
||||
"totterer",
|
||||
"Totten trust",
|
||||
"totipotent",
|
||||
"totipotency",
|
||||
"totemism",
|
||||
"totem pole",
|
||||
"Totara",
|
||||
"totalizer",
|
||||
"totalizator",
|
||||
"totalitarianism",
|
||||
"total parenteral nutrition",
|
||||
"total hysterectomy",
|
||||
"total eclipse",
|
||||
"Totipresence",
|
||||
"Totipalmi",
|
||||
"Tomboy",
|
||||
"zombie",
|
||||
NULL});
|
||||
gtk_suggestion_entry_set_model (GTK_SUGGESTION_ENTRY (entry), G_LIST_MODEL (strings));
|
||||
g_object_unref (strings);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), entry);
|
||||
|
||||
/* A suggestion entry using a custom model, and no filtering */
|
||||
entry = gtk_suggestion_entry_new ();
|
||||
|
||||
cwd = g_get_current_dir ();
|
||||
file = g_file_new_for_path (cwd);
|
||||
dir = G_LIST_MODEL (gtk_directory_list_new ("standard::display-name,standard::content-type,standard::icon,standard::size", file));
|
||||
gtk_suggestion_entry_set_model (GTK_SUGGESTION_ENTRY (entry), dir);
|
||||
g_object_unref (dir);
|
||||
g_object_unref (file);
|
||||
g_free (cwd);
|
||||
|
||||
button = drop_down_new_from_strings (many_times, NULL, NULL);
|
||||
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
|
||||
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
|
||||
0, NULL,
|
||||
(GCallback)get_file_name,
|
||||
(GCallback)get_title,
|
||||
NULL, NULL);
|
||||
gtk_suggestion_entry_set_expression (GTK_SUGGESTION_ENTRY (entry), expression);
|
||||
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
|
||||
gtk_expression_unref (expression);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_item), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_item), NULL);
|
||||
|
||||
gtk_suggestion_entry_set_factory (GTK_SUGGESTION_ENTRY (entry), factory);
|
||||
g_object_unref (factory);
|
||||
|
||||
gtk_suggestion_entry_set_use_filter (GTK_SUGGESTION_ENTRY (entry), FALSE);
|
||||
gtk_suggestion_entry_set_show_arrow (GTK_SUGGESTION_ENTRY (entry), TRUE);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), entry);
|
||||
|
||||
/* A suggestion entry with match highlighting */
|
||||
entry = gtk_suggestion_entry_new ();
|
||||
g_object_set (entry, "placeholder-text", "Destination", NULL);
|
||||
|
||||
strings = gtk_string_list_new ((const char *[]){
|
||||
"app-mockups",
|
||||
"settings-mockups",
|
||||
"os-mockups",
|
||||
"software-mockups",
|
||||
"mocktails",
|
||||
NULL});
|
||||
gtk_suggestion_entry_set_model (GTK_SUGGESTION_ENTRY (entry), G_LIST_MODEL (strings));
|
||||
g_object_unref (strings);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), entry);
|
||||
|
||||
gtk_suggestion_entry_set_match_func (GTK_SUGGESTION_ENTRY (entry), match_func, NULL, NULL);
|
||||
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_highlight_item), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_highlight_item), NULL);
|
||||
gtk_suggestion_entry_set_factory (GTK_SUGGESTION_ENTRY (entry), factory);
|
||||
g_object_unref (factory);
|
||||
|
||||
button = drop_down_new_from_strings (device_titles, device_icons, device_descriptions);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<property name="title">Font Explorer</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="reset">
|
||||
<property name="receives-default">1</property>
|
||||
|
||||
@@ -30,6 +30,7 @@ do_headerbar (GtkWidget *do_widget)
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
|
||||
button = gtk_button_new ();
|
||||
icon = g_themed_icon_new ("mail-send-receive-symbolic");
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">500</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
|
||||
@@ -627,23 +627,6 @@ setup_listitem_cb (GtkListItemFactory *factory,
|
||||
gtk_expression_unref (color_expression);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_selection_listitem_cb (GtkListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
GtkExpression *color_expression, *expression;
|
||||
|
||||
expression = gtk_constant_expression_new (GTK_TYPE_LIST_ITEM, list_item);
|
||||
color_expression = gtk_property_expression_new (GTK_TYPE_LIST_ITEM, expression, "item");
|
||||
|
||||
picture = gtk_picture_new ();
|
||||
gtk_widget_set_size_request (picture, 8, 8);
|
||||
gtk_expression_bind (color_expression, picture, "paintable", NULL);
|
||||
|
||||
gtk_list_item_set_child (list_item, picture);
|
||||
}
|
||||
|
||||
static void
|
||||
set_title (gpointer item,
|
||||
const char *title)
|
||||
@@ -662,6 +645,7 @@ create_color_grid (void)
|
||||
{
|
||||
GtkWidget *gridview;
|
||||
GtkListItemFactory *factory;
|
||||
GListModel *model, *selection;
|
||||
|
||||
gridview = gtk_grid_view_new ();
|
||||
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
|
||||
@@ -675,6 +659,13 @@ create_color_grid (void)
|
||||
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (gridview), 24);
|
||||
gtk_grid_view_set_enable_rubberband (GTK_GRID_VIEW (gridview), TRUE);
|
||||
|
||||
model = G_LIST_MODEL (gtk_sort_list_model_new (gtk_color_list_new (0), NULL));
|
||||
|
||||
selection = G_LIST_MODEL (gtk_multi_selection_new (model));
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), selection);
|
||||
g_object_unref (selection);
|
||||
g_object_unref (model);
|
||||
|
||||
return gridview;
|
||||
}
|
||||
|
||||
@@ -786,63 +777,6 @@ bind_number_item (GtkSignalListItemFactory *factory,
|
||||
g_free (string);
|
||||
}
|
||||
|
||||
static void
|
||||
update_selection_count (GListModel *model,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
gpointer data)
|
||||
{
|
||||
char *text;
|
||||
text = g_strdup_printf ("%u", g_list_model_get_n_items (model));
|
||||
gtk_label_set_label (GTK_LABEL (data), text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
update_selection_average (GListModel *model,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
gpointer data)
|
||||
{
|
||||
guint n = g_list_model_get_n_items (model);
|
||||
GdkRGBA c = { 0, 0, 0, 1 };
|
||||
guint i;
|
||||
GtkColor *color;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
color = g_list_model_get_item (model, i);
|
||||
|
||||
c.red += color->color.red;
|
||||
c.green += color->color.green;
|
||||
c.blue += color->color.blue;
|
||||
|
||||
g_object_unref (color);
|
||||
}
|
||||
|
||||
color = gtk_color_new ("", c.red / n, c.green / n, c.blue / n);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (data), GDK_PAINTABLE (color));
|
||||
g_object_unref (color);
|
||||
}
|
||||
|
||||
static void
|
||||
update_progress_cb (GtkSortListModel *model,
|
||||
GParamSpec *pspec,
|
||||
GtkProgressBar *progress)
|
||||
{
|
||||
guint total;
|
||||
guint pending;
|
||||
|
||||
total = g_list_model_get_n_items (G_LIST_MODEL (model));
|
||||
total = MAX (total, 1); /* avoid div by 0 below */
|
||||
pending = gtk_sort_list_model_get_pending (model);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (progress), pending != 0);
|
||||
gtk_progress_bar_set_fraction (progress, (total - pending) / (double) total);
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
@@ -850,11 +784,10 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
{
|
||||
if (window == NULL)
|
||||
{
|
||||
GtkMultiSelection *selection;
|
||||
GtkSortListModel *sort_model;
|
||||
GtkWidget *header, *overlay, *gridview, *sw, *box, *dropdown;
|
||||
GtkWidget *header, *gridview, *sw, *box, *dropdown;
|
||||
GtkListItemFactory *factory;
|
||||
GListStore *factories;
|
||||
GListModel *model;
|
||||
GtkSorter *sorter;
|
||||
GtkSorter *multi_sorter;
|
||||
GListStore *sorters;
|
||||
@@ -864,31 +797,11 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
PangoAttrList *attrs;
|
||||
char *string;
|
||||
guint len;
|
||||
GtkWidget *selection_view;
|
||||
GListModel *selection_filter;
|
||||
GListModel *no_selection;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *selection_size_label;
|
||||
GtkWidget *selection_average_picture;
|
||||
GtkWidget *selection_info_toggle;
|
||||
GtkWidget *selection_info_revealer;
|
||||
GtkWidget *progress;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/listview_colors/listview_colors.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
|
||||
sort_model = gtk_sort_list_model_new (gtk_color_list_new (0), NULL);
|
||||
gtk_sort_list_model_set_incremental (sort_model, TRUE);
|
||||
selection = GTK_MULTI_SELECTION (gtk_multi_selection_new (G_LIST_MODEL (sort_model)));
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Colors");
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
@@ -896,96 +809,18 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), overlay);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), box);
|
||||
|
||||
progress = gtk_progress_bar_new ();
|
||||
gtk_widget_set_hexpand (progress, TRUE);
|
||||
gtk_widget_set_valign (progress, GTK_ALIGN_START);
|
||||
g_signal_connect (sort_model, "notify::pending", G_CALLBACK (update_progress_cb), progress);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), progress);
|
||||
|
||||
selection_info_revealer = gtk_revealer_new ();
|
||||
gtk_box_append (GTK_BOX (box), selection_info_revealer);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_revealer_set_child (GTK_REVEALER (selection_info_revealer), grid);
|
||||
gtk_widget_set_margin_start (grid, 10);
|
||||
gtk_widget_set_margin_end (grid, 10);
|
||||
gtk_widget_set_margin_top (grid, 10);
|
||||
gtk_widget_set_margin_bottom (grid, 10);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
|
||||
|
||||
label = gtk_label_new ("Selection");
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_widget_add_css_class (label, "title-3");
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 5, 1);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Size:"), 0, 2, 1, 1);
|
||||
|
||||
selection_size_label = gtk_label_new ("0");
|
||||
gtk_grid_attach (GTK_GRID (grid), selection_size_label, 1, 2, 1, 1);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Average:"), 2, 2, 1, 1);
|
||||
|
||||
selection_average_picture = gtk_picture_new ();
|
||||
gtk_widget_set_size_request (selection_average_picture, 32, 32);
|
||||
gtk_grid_attach (GTK_GRID (grid), selection_average_picture, 3, 2, 1, 1);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 4, 2, 1, 1);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_widget_set_hexpand (sw, TRUE);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), sw, 0, 1, 5, 1);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_selection_listitem_cb), NULL);
|
||||
selection_view = gtk_grid_view_new_with_factory (factory);
|
||||
gtk_widget_add_css_class (selection_view, "compact");
|
||||
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (selection_view), 200);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), selection_view);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_box_append (GTK_BOX (box), sw);
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
|
||||
gridview = create_color_grid ();
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), G_LIST_MODEL (selection));
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), gridview);
|
||||
gtk_widget_set_hexpand (sw, TRUE);
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
|
||||
selection_filter = G_LIST_MODEL (gtk_selection_filter_model_new (GTK_SELECTION_MODEL (selection)));
|
||||
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_count), selection_size_label);
|
||||
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_average), selection_average_picture);
|
||||
|
||||
no_selection = G_LIST_MODEL (gtk_no_selection_new (selection_filter));
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (selection_view), no_selection);
|
||||
g_object_unref (selection_filter);
|
||||
g_object_unref (no_selection);
|
||||
|
||||
selection_info_toggle = gtk_toggle_button_new ();
|
||||
gtk_button_set_icon_name (GTK_BUTTON (selection_info_toggle), "emblem-important-symbolic");
|
||||
gtk_widget_set_tooltip_text (selection_info_toggle, "Show selection info");
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), selection_info_toggle);
|
||||
|
||||
g_object_bind_property (selection_info_toggle, "active",
|
||||
selection_info_revealer, "reveal-child",
|
||||
G_BINDING_DEFAULT);
|
||||
model = gtk_grid_view_get_model (GTK_GRID_VIEW (gridview));
|
||||
g_object_get (model, "model", &model, NULL);
|
||||
|
||||
button = gtk_button_new_with_mnemonic ("_Refill");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (refill),
|
||||
gtk_sort_list_model_get_model (sort_model));
|
||||
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
|
||||
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
|
||||
|
||||
@@ -1000,14 +835,15 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_label_set_width_chars (GTK_LABEL (label), len + 2);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
|
||||
g_signal_connect (selection, "items-changed", G_CALLBACK (items_changed_cb), label);
|
||||
g_signal_connect (gtk_grid_view_get_model (GTK_GRID_VIEW (gridview)),
|
||||
"items-changed", G_CALLBACK (items_changed_cb), label);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), label);
|
||||
|
||||
dropdown = gtk_drop_down_new ();
|
||||
gtk_drop_down_set_from_strings (GTK_DROP_DOWN (dropdown), (const char *[]) { "8", "64", "512", "4096", "32768", "262144", "2097152", "16777216", NULL });
|
||||
g_signal_connect (dropdown, "notify::selected",
|
||||
G_CALLBACK (limit_changed_cb),
|
||||
gtk_sort_list_model_get_model (sort_model));
|
||||
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
|
||||
g_signal_connect (dropdown, "notify::selected",
|
||||
G_CALLBACK (limit_changed_cb2),
|
||||
label);
|
||||
@@ -1099,7 +935,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (dropdown), G_LIST_MODEL (sorters));
|
||||
g_object_unref (sorters);
|
||||
|
||||
g_object_bind_property (dropdown, "selected-item", sort_model, "sorter", G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (dropdown, "selected-item", model, "sorter", G_BINDING_SYNC_CREATE);
|
||||
|
||||
factories = g_list_store_new (GTK_TYPE_LIST_ITEM_FACTORY);
|
||||
|
||||
@@ -1131,6 +967,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
g_object_unref (factories);
|
||||
|
||||
g_object_bind_property (dropdown, "selected-item", gridview, "factory", G_BINDING_SYNC_CREATE);
|
||||
g_object_unref (model);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.view.compact > child {
|
||||
padding: 1px;
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
listview.viewswitcher {
|
||||
list.viewswitcher {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
listview.viewswitcher > row {
|
||||
list.viewswitcher > row {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
listview.viewswitcher row:selected {
|
||||
list.viewswitcher row:selected {
|
||||
background: gray;
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">go-up-symbolic</property>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="title" translatable="yes">Minesweeper</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">New Game</property>
|
||||
|
||||
@@ -215,6 +215,7 @@ transform_settings_to_keys (GBinding *binding,
|
||||
GtkFilterListModel *filter_model;
|
||||
GtkFilter *filter;
|
||||
GtkNoSelection *selection_model;
|
||||
GtkExpression *expression;
|
||||
char **keys;
|
||||
guint i;
|
||||
|
||||
@@ -245,8 +246,11 @@ transform_settings_to_keys (GBinding *binding,
|
||||
gtk_column_view_get_sorter (GTK_COLUMN_VIEW (data)));
|
||||
g_object_unref (store);
|
||||
|
||||
filter = gtk_string_filter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name"));
|
||||
expression = gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name");
|
||||
filter = gtk_string_filter_new ();
|
||||
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (sort_model), filter);
|
||||
gtk_expression_unref (expression);
|
||||
g_object_unref (sort_model);
|
||||
|
||||
g_set_object (¤t_filter, filter);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">480</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="search_button">
|
||||
<property name="icon-name">system-search-symbolic</property>
|
||||
|
||||
@@ -194,8 +194,8 @@ create_weather_model (void)
|
||||
}
|
||||
|
||||
static void
|
||||
setup_widget (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
setup_widget (GtkListItem *list_item,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *box, *child;
|
||||
|
||||
@@ -218,8 +218,8 @@ setup_widget (GtkSignalListItemFactory *factory,
|
||||
}
|
||||
|
||||
static void
|
||||
bind_widget (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
bind_widget (GtkListItem *list_item,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *box, *child;
|
||||
GtkWeatherInfo *info;
|
||||
@@ -282,12 +282,11 @@ create_weather_view (void)
|
||||
{
|
||||
GtkWidget *listview;
|
||||
GListModel *model, *selection;
|
||||
GtkListItemFactory *factory;
|
||||
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_widget), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_widget), NULL);
|
||||
listview = gtk_list_view_new_with_factory (factory);
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
gtk_functions_list_item_factory_new (setup_widget,
|
||||
bind_widget,
|
||||
NULL, NULL));
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
|
||||
model = create_weather_model ();
|
||||
|
||||
@@ -160,6 +160,7 @@ do_listview_words (GtkWidget *do_widget)
|
||||
GtkNoSelection *selection;
|
||||
GtkStringList *stringlist;
|
||||
GtkFilter *filter;
|
||||
GtkExpression *expression;
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_path ("/usr/share/dict/words");
|
||||
@@ -176,7 +177,10 @@ do_listview_words (GtkWidget *do_widget)
|
||||
g_strfreev (words);
|
||||
}
|
||||
|
||||
filter = gtk_string_filter_new (gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string"));
|
||||
filter = gtk_string_filter_new ();
|
||||
expression = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
|
||||
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
|
||||
gtk_expression_unref (expression);
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (stringlist), filter);
|
||||
gtk_filter_list_model_set_incremental (filter_model, TRUE);
|
||||
|
||||
@@ -211,7 +215,6 @@ do_listview_words (GtkWidget *do_widget)
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), progress);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
|
||||
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
|
||||
+4
-113
@@ -18,7 +18,6 @@ static gchar *current_file = NULL;
|
||||
static GtkWidget *notebook;
|
||||
static GtkSingleSelection *selection;
|
||||
static GtkWidget *toplevel;
|
||||
static char **search_needle;
|
||||
|
||||
typedef struct _GtkDemo GtkDemo;
|
||||
struct _GtkDemo
|
||||
@@ -946,18 +945,7 @@ selection_cb (GtkSingleSelection *sel,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTreeListRow *row = gtk_single_selection_get_selected_item (sel);
|
||||
GtkDemo *demo;
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (notebook), !!row);
|
||||
|
||||
if (!row)
|
||||
{
|
||||
gtk_window_set_title (GTK_WINDOW (toplevel), "No match");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
demo = gtk_tree_list_row_get_item (row);
|
||||
GtkDemo *demo = gtk_tree_list_row_get_item (row);
|
||||
|
||||
if (demo->filename)
|
||||
load_file (demo->name, demo->filename);
|
||||
@@ -965,84 +953,6 @@ selection_cb (GtkSingleSelection *sel,
|
||||
gtk_window_set_title (GTK_WINDOW (toplevel), demo->title);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
filter_demo (GtkDemo *demo)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Show only if the name maches every needle */
|
||||
for (i = 0; search_needle[i]; i++)
|
||||
{
|
||||
if (!demo->title)
|
||||
return FALSE;
|
||||
|
||||
if (g_str_match_string (search_needle[i], demo->title, TRUE))
|
||||
continue;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
demo_filter_by_name (GtkTreeListRow *row,
|
||||
GtkFilterListModel *model)
|
||||
{
|
||||
GListModel *children;
|
||||
GtkDemo *demo;
|
||||
guint i, n;
|
||||
|
||||
/* Show all items if search is empty */
|
||||
if (!search_needle || !search_needle[0] || !*search_needle[0])
|
||||
return TRUE;
|
||||
|
||||
g_assert (GTK_IS_TREE_LIST_ROW (row));
|
||||
g_assert (GTK_IS_FILTER_LIST_MODEL (model));
|
||||
|
||||
children = gtk_tree_list_row_get_children (row);
|
||||
if (children)
|
||||
{
|
||||
n = g_list_model_get_n_items (children);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
demo = g_list_model_get_item (children, i);
|
||||
g_assert (GTK_IS_DEMO (demo));
|
||||
|
||||
if (filter_demo (demo))
|
||||
{
|
||||
g_object_unref (demo);
|
||||
return TRUE;
|
||||
}
|
||||
g_object_unref (demo);
|
||||
}
|
||||
}
|
||||
|
||||
demo = gtk_tree_list_row_get_item (row);
|
||||
g_assert (GTK_IS_DEMO (demo));
|
||||
|
||||
return filter_demo (demo);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_search_changed_cb (GtkSearchEntry *entry,
|
||||
GtkFilter *filter)
|
||||
{
|
||||
const char *text;
|
||||
|
||||
g_assert (GTK_IS_SEARCH_ENTRY (entry));
|
||||
g_assert (GTK_IS_FILTER (filter));
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
|
||||
g_clear_pointer (&search_needle, g_strfreev);
|
||||
|
||||
if (text && *text)
|
||||
search_needle = g_strsplit (text, " ", 0);
|
||||
|
||||
gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
create_demo_model (void)
|
||||
{
|
||||
@@ -1097,25 +1007,13 @@ get_child_model (gpointer item,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_search (GtkSearchBar *bar)
|
||||
{
|
||||
if (!gtk_search_bar_get_search_mode (bar))
|
||||
{
|
||||
GtkWidget *entry = gtk_search_bar_get_child (GTK_SEARCH_BAR (bar));
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), "");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
activate (GApplication *app)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GListModel *listmodel;
|
||||
GtkTreeListModel *treemodel;
|
||||
GtkWidget *window, *listview, *search_entry, *search_bar;
|
||||
GtkFilterListModel *filter_model;
|
||||
GtkFilter *filter;
|
||||
GtkWidget *window, *listview;
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "run", activate_run, NULL, NULL, NULL }
|
||||
@@ -1136,8 +1034,6 @@ activate (GApplication *app)
|
||||
toplevel = GTK_WIDGET (window);
|
||||
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
|
||||
g_signal_connect (listview, "activate", G_CALLBACK (activate_cb), window);
|
||||
search_bar = GTK_WIDGET (gtk_builder_get_object (builder, "searchbar"));
|
||||
g_signal_connect (search_bar, "notify::search-mode-enabled", G_CALLBACK (clear_search), NULL);
|
||||
|
||||
listmodel = create_demo_model ();
|
||||
treemodel = gtk_tree_list_model_new (FALSE,
|
||||
@@ -1146,13 +1042,7 @@ activate (GApplication *app)
|
||||
get_child_model,
|
||||
NULL,
|
||||
NULL);
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (treemodel), NULL);
|
||||
filter = gtk_custom_filter_new ((GtkCustomFilterFunc)demo_filter_by_name, filter_model, NULL);
|
||||
gtk_filter_list_model_set_filter (filter_model, filter);
|
||||
search_entry = GTK_WIDGET (gtk_builder_get_object (builder, "search-entry"));
|
||||
g_signal_connect (search_entry, "search-changed", G_CALLBACK (demo_search_changed_cb), filter);
|
||||
|
||||
selection = gtk_single_selection_new (G_LIST_MODEL (filter_model));
|
||||
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
|
||||
g_signal_connect (selection, "notify::selected-item", G_CALLBACK (selection_cb), NULL);
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
|
||||
|
||||
@@ -1249,6 +1139,7 @@ out:
|
||||
demo = (func) (window);
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW (demo), GTK_WINDOW (window));
|
||||
gtk_window_set_modal (GTK_WINDOW (demo), TRUE);
|
||||
|
||||
g_signal_connect_swapped (G_OBJECT (demo), "destroy", G_CALLBACK (g_application_quit), app);
|
||||
}
|
||||
|
||||
+6
-22
@@ -24,6 +24,7 @@
|
||||
<property name="default-height">600</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="valign">center</property>
|
||||
@@ -55,29 +56,12 @@
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="min-content-width">150</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="width-request">220</property>
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkSearchBar" id="searchbar">
|
||||
<property name="key-capture-widget">window</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="search-entry"/>
|
||||
</child>
|
||||
<object class="GtkListView" id="listview">
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="resource">/ui/main-listitem.ui</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListView" id="listview">
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="resource">/ui/main-listitem.ui</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -69,6 +69,7 @@ do_markup (GtkWidget *do_widget)
|
||||
g_signal_connect (show_source, "toggled", G_CALLBACK (source_toggled), stack);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), show_source);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ demos = files([
|
||||
'cursors.c',
|
||||
'dialog.c',
|
||||
'drawingarea.c',
|
||||
'dropdown.c',
|
||||
'dnd.c',
|
||||
'editable_cells.c',
|
||||
'entry_completion.c',
|
||||
@@ -46,7 +47,6 @@ demos = files([
|
||||
'listview_colors.c',
|
||||
'listview_filebrowser.c',
|
||||
'listview_minesweeper.c',
|
||||
'dropdown.c',
|
||||
'listview_settings.c',
|
||||
'listview_weather.c',
|
||||
'listview_words.c',
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
<property name="title" translatable="yes">Model Button</property>
|
||||
<property name="resizable">0</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar"/>
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
|
||||
@@ -392,6 +392,7 @@ do_paint (GtkWidget *toplevel)
|
||||
gtk_window_set_child (GTK_WINDOW (window), draw_area);
|
||||
|
||||
headerbar = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (headerbar), TRUE);
|
||||
|
||||
colorbutton = gtk_color_button_new ();
|
||||
g_signal_connect (colorbutton, "color-set",
|
||||
|
||||
@@ -276,6 +276,7 @@ do_peg_solitaire (GtkWidget *do_widget)
|
||||
g_signal_connect (restart, "clicked", G_CALLBACK (restart), NULL);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
|
||||
@@ -40,6 +40,7 @@ do_sidebar (GtkWidget *do_widget)
|
||||
gtk_widget_set_size_request (window, 500, 350);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR(header), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW(window), header);
|
||||
gtk_window_set_title (GTK_WINDOW(window), "Stack Sidebar");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
@@ -470,6 +470,7 @@ do_sliding_puzzle (GtkWidget *do_widget)
|
||||
g_signal_connect (restart, "clicked", G_CALLBACK (reshuffle), NULL);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), tweak);
|
||||
window = gtk_window_new ();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<property name="resizable">0</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkToggleButton" id="toggle">
|
||||
<property name="label">Cycle</property>
|
||||
|
||||
@@ -73,6 +73,7 @@ do_video_player (GtkWidget *do_widget)
|
||||
gtk_window_set_child (GTK_WINDOW (window), video);
|
||||
|
||||
title = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (title), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), title);
|
||||
|
||||
open_button = gtk_button_new_with_mnemonic ("_Open");
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="43.000351" x2="85.000351" y1="39.000164" y2="39.000164">
|
||||
<stop offset="0" stop-color="#26a269"/>
|
||||
<stop offset="0.0934161" stop-color="#84e3b7"/>
|
||||
<stop offset="0.330831" stop-color="#26a269"/>
|
||||
<stop offset="0.686952" stop-color="#26a269"/>
|
||||
<stop offset="0.89736" stop-color="#175e3c"/>
|
||||
<stop offset="1" stop-color="#26a269"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.154754" stop-color="#ffffff"/>
|
||||
<stop offset="0.433722" stop-color="#bdbbb5"/>
|
||||
<stop offset="0.650505" stop-color="#c1c0ba"/>
|
||||
<stop offset="0.825253" stop-color="#ffffff"/>
|
||||
<stop offset="1" stop-color="#c0bfbc"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="c" gradientTransform="matrix(0.0811899 -0.046875 0.069079 0.119648 307.03142 127.069456)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
|
||||
<linearGradient id="d" gradientTransform="matrix(-0.0811899 -0.046875 -0.069079 0.119648 -177.242852 127.069447)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
|
||||
<linearGradient id="e" gradientUnits="userSpaceOnUse" x1="14" x2="56" y1="94.999964" y2="94.999964">
|
||||
<stop offset="0" stop-color="#813d9c"/>
|
||||
<stop offset="0.109119" stop-color="#b378ca"/>
|
||||
<stop offset="0.241583" stop-color="#813d9c"/>
|
||||
<stop offset="0.731841" stop-color="#813d9c"/>
|
||||
<stop offset="0.872163" stop-color="#4d255d"/>
|
||||
<stop offset="1" stop-color="#813d9c"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="f" gradientUnits="userSpaceOnUse" x1="72" x2="114" y1="94.999964" y2="94.999964">
|
||||
<stop offset="0" stop-color="#e66100"/>
|
||||
<stop offset="0.0678478" stop-color="#ff903e"/>
|
||||
<stop offset="0.168852" stop-color="#e66100"/>
|
||||
<stop offset="0.886626" stop-color="#e66100"/>
|
||||
<stop offset="1" stop-color="#9d4200"/>
|
||||
</linearGradient>
|
||||
<clipPath id="g">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="h">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<filter id="i" height="100%" width="100%" x="0%" y="0%">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="j">
|
||||
<g clip-path="url(#h)" filter="url(#i)">
|
||||
<g clip-path="url(#g)">
|
||||
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
|
||||
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
|
||||
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
|
||||
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
|
||||
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
|
||||
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
<mask id="k">
|
||||
<g filter="url(#i)">
|
||||
<rect fill-opacity="0.8" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<linearGradient id="l" gradientTransform="matrix(0 0.37 -0.98462 0 295.38501 -30.360001)" gradientUnits="userSpaceOnUse" x1="300" x2="428" y1="235" y2="235">
|
||||
<stop offset="0" stop-color="#f9f06b"/>
|
||||
<stop offset="1" stop-color="#f5c211"/>
|
||||
</linearGradient>
|
||||
<clipPath id="m">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="n">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
|
||||
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
|
||||
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
|
||||
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
|
||||
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
|
||||
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
|
||||
<g clip-path="url(#n)" mask="url(#j)">
|
||||
<g clip-path="url(#m)" mask="url(#k)">
|
||||
<path d="m 128 80.640625 v 47.359375 h -128 v -47.359375 z m 0 0" fill="url(#l)"/>
|
||||
<path d="m 13.308594 80.640625 l 47.355468 47.359375 h 21.214844 l -47.359375 -47.359375 z m 42.421875 0 l 47.363281 47.359375 h 21.214844 l -47.363282 -47.359375 z m 42.429687 0 l 29.839844 29.839844 v -21.210938 l -8.628906 -8.628906 z m -98.160156 7.90625 v 21.214844 l 18.238281 18.238281 h 21.214844 z m 0 0"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.4 KiB |
@@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="43.000351" x2="85.000351" y1="39.000164" y2="39.000164">
|
||||
<stop offset="0" stop-color="#26a269"/>
|
||||
<stop offset="0.0934161" stop-color="#84e3b7"/>
|
||||
<stop offset="0.330831" stop-color="#26a269"/>
|
||||
<stop offset="0.686952" stop-color="#26a269"/>
|
||||
<stop offset="0.89736" stop-color="#175e3c"/>
|
||||
<stop offset="1" stop-color="#26a269"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.154754" stop-color="#ffffff"/>
|
||||
<stop offset="0.433722" stop-color="#bdbbb5"/>
|
||||
<stop offset="0.650505" stop-color="#c1c0ba"/>
|
||||
<stop offset="0.825253" stop-color="#ffffff"/>
|
||||
<stop offset="1" stop-color="#c0bfbc"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="c" gradientTransform="matrix(0.0811899 -0.046875 0.069079 0.119648 307.03142 127.069456)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
|
||||
<linearGradient id="d" gradientTransform="matrix(-0.0811899 -0.046875 -0.069079 0.119648 -177.242852 127.069447)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
|
||||
<linearGradient id="e" gradientUnits="userSpaceOnUse" x1="14" x2="56" y1="94.999964" y2="94.999964">
|
||||
<stop offset="0" stop-color="#813d9c"/>
|
||||
<stop offset="0.109119" stop-color="#b378ca"/>
|
||||
<stop offset="0.241583" stop-color="#813d9c"/>
|
||||
<stop offset="0.731841" stop-color="#813d9c"/>
|
||||
<stop offset="0.872163" stop-color="#4d255d"/>
|
||||
<stop offset="1" stop-color="#813d9c"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="f" gradientUnits="userSpaceOnUse" x1="72" x2="114" y1="94.999964" y2="94.999964">
|
||||
<stop offset="0" stop-color="#e66100"/>
|
||||
<stop offset="0.0678478" stop-color="#ff903e"/>
|
||||
<stop offset="0.168852" stop-color="#e66100"/>
|
||||
<stop offset="0.886626" stop-color="#e66100"/>
|
||||
<stop offset="1" stop-color="#9d4200"/>
|
||||
</linearGradient>
|
||||
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
|
||||
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
|
||||
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
|
||||
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
|
||||
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
|
||||
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB |
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 5.75 1 c -0.414062 0 -0.75 0.335938 -0.75 0.75 v 4.5 c 0 0.414062 0.335938 0.75 0.75 0.75 h 0.191406 l -1 2 h -3.191406 c -0.414062 0 -0.75 0.335938 -0.75 0.75 v 4.5 c 0 0.414062 0.335938 0.75 0.75 0.75 h 4.5 c 0.414062 0 0.75 -0.335938 0.75 -0.75 v -4.5 c 0 -0.414062 -0.335938 -0.75 -0.75 -0.75 h -0.191406 l 1 -2 h 1.882812 l 1 2 h -0.191406 c -0.414062 0 -0.75 0.335938 -0.75 0.75 v 4.5 c 0 0.414062 0.335938 0.75 0.75 0.75 h 4.5 c 0.414062 0 0.75 -0.335938 0.75 -0.75 v -4.5 c 0 -0.414062 -0.335938 -0.75 -0.75 -0.75 h -3.191406 l -1 -2 h 0.191406 c 0.414062 0 0.75 -0.335938 0.75 -0.75 v -4.5 c 0 -0.414062 -0.335938 -0.75 -0.75 -0.75 z m 0 0"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 801 B |
@@ -19,12 +19,3 @@ executable('gtk4-node-editor',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
||||
foreach size: ['scalable', 'symbolic']
|
||||
install_subdir('data/' + size,
|
||||
install_dir: icontheme_dir
|
||||
)
|
||||
endforeach
|
||||
|
||||
@@ -101,7 +101,7 @@ activate_about (GSimpleAction *action,
|
||||
"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.Devel",
|
||||
"logo-icon-name", "text-editor-symbolic",
|
||||
"title", "About GTK Node Editor",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
<property name="focus-widget">text_view</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<linearGradient id="a" gradientTransform="matrix(0.232143 0 0 0.328947 -7.567033 263.82666)" gradientUnits="userSpaceOnUse" x1="88.595886" x2="536.595886" y1="-449.394012" y2="-449.394012">
|
||||
<stop offset="0" stop-color="#acabae"/>
|
||||
<stop offset="0.0384615" stop-color="#deddda"/>
|
||||
<stop offset="0.0768555" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.923077" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.961538" stop-color="#deddda"/>
|
||||
<stop offset="1" stop-color="#9a9996"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="26.999876" x2="100.999876" y1="32.999688" y2="32.999688">
|
||||
<stop offset="0" stop-color="#7e7c77"/>
|
||||
<stop offset="0.3" stop-color="#9a9996"/>
|
||||
<stop offset="1" stop-color="#9a9996"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="67.467916" x2="67.467916" y1="83.999688" y2="36.782906">
|
||||
<stop offset="0" stop-color="#deddda"/>
|
||||
<stop offset="1" stop-color="#c0bfbc"/>
|
||||
</linearGradient>
|
||||
<clipPath id="d">
|
||||
<path d="m 79 72 h 15 v 16 h -15 z m 0 0"/>
|
||||
</clipPath>
|
||||
<clipPath id="e">
|
||||
<path d="m 93.21875 72.921875 l -14.21875 14.21875 h -4.0625 v -18.28125 h 18.28125 z m 0 0"/>
|
||||
</clipPath>
|
||||
<linearGradient id="f" gradientTransform="matrix(0 0.126951 0.126951 0 76.460862 36.359884)" gradientUnits="userSpaceOnUse" x1="344" x2="340" y1="76" y2="72">
|
||||
<stop offset="0" stop-color="#d5d3cf"/>
|
||||
<stop offset="1" stop-color="#ffffff"/>
|
||||
</linearGradient>
|
||||
<filter id="g" height="100%" width="100%" x="0%" y="0%">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="h">
|
||||
<g filter="url(#g)">
|
||||
<rect fill-opacity="0.396" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<linearGradient id="i" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#1c71d8"/>
|
||||
<stop offset="0.323117" stop-color="#62a0ea"/>
|
||||
<stop offset="0.59387" stop-color="#1b5aa6"/>
|
||||
<stop offset="1" stop-color="#1c71d8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="j" gradientTransform="matrix(1.597748 1.597748 -1.06066 1.06066 -56.853041 -543.720139)" x1="224.504562" x2="231.453873" xlink:href="#i" y1="282.5" y2="282.5"/>
|
||||
<radialGradient id="k" cx="227.599915" cy="201.029724" gradientTransform="matrix(4.072817 4.073078 -5.940048 5.939073 373.883117 -2098.049112)" gradientUnits="userSpaceOnUse" r="2.5">
|
||||
<stop offset="0" stop-color="#93bdf1"/>
|
||||
<stop offset="1" stop-color="#1a5fb4"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="l" gradientTransform="matrix(2.121328 2.121328 -2.174353 2.174353 181.766074 -1021.145947)" gradientUnits="userSpaceOnUse" x1="226.90625" x2="228.86203" y1="288.75" y2="288.767151">
|
||||
<stop offset="0" stop-color="#77767b"/>
|
||||
<stop offset="0.443872" stop-color="#f6f5f4"/>
|
||||
<stop offset="1" stop-color="#5e5c64"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="m" gradientTransform="matrix(1.258421 1.258421 -1.06066 1.06066 57.381892 -503.024312)" gradientUnits="userSpaceOnUse" x1="223.1875" x2="233.0625" y1="278" y2="278">
|
||||
<stop offset="0" stop-color="#ffa348"/>
|
||||
<stop offset="0.265823" stop-color="#ffd7af"/>
|
||||
<stop offset="0.734177" stop-color="#ff8d1c"/>
|
||||
<stop offset="1" stop-color="#ffa348"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="n" gradientTransform="matrix(1.573027 1.573027 -1.06066 1.06066 -14.348129 -574.754333)" x1="224.504562" x2="231.453873" xlink:href="#i" y1="282.5" y2="282.5"/>
|
||||
<clipPath id="o">
|
||||
<path d="m 79 72 h 15 v 16 h -15 z m 0 0"/>
|
||||
</clipPath>
|
||||
<clipPath id="p">
|
||||
<path d="m 93.21875 72.921875 l -14.21875 14.21875 h -4.0625 v -18.28125 h 18.28125 z m 0 0"/>
|
||||
</clipPath>
|
||||
<mask id="q">
|
||||
<g filter="url(#g)">
|
||||
<rect fill-opacity="0.396" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="r">
|
||||
<rect height="152" width="192"/>
|
||||
</clipPath>
|
||||
<g id="s" clip-path="url(#r)">
|
||||
<path d="m 29 112 c -4.433594 0 -8 -3.566406 -8 -8 v -2 c 0 4.433594 3.566406 8 8 8 h 88 c 4.433594 0 8 -3.566406 8 -8 v 2 c 0 4.433594 -3.566406 8 -8 8 z m 0 0" fill="#f6f5f4"/>
|
||||
</g>
|
||||
<clipPath id="t">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="u">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<mask id="v">
|
||||
<g clip-path="url(#u)" filter="url(#g)">
|
||||
<g clip-path="url(#t)">
|
||||
<path d="m 21 16 c -4.433594 0 -8 3.566406 -8 8 v 84 c 0 4.433594 3.566406 8 8 8 h 4 v -4 h 80 v 4 h 4 c 4.433594 0 8 -3.566406 8 -8 v -84 c 0 -4.433594 -3.566406 -8 -8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 21 12 h 88 c 4.417969 0 8 3.582031 8 8 v 68 c 0 4.417969 -3.582031 8 -8 8 h -88 c -4.417969 0 -8 -3.582031 -8 -8 v -68 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#deddda"/>
|
||||
<path d="m 27 28 h 74 v 10 h -74 z m 0 0" fill="url(#b)"/>
|
||||
<path d="m 27 38 h 74 v 46 h -74 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 24 33 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#bf5f00" fill-opacity="0.964567"/>
|
||||
<path d="m 18 40 h 6 v 12 h -6 z m 0 0" fill="#acacac" fill-opacity="0.984252"/>
|
||||
<path d="m 18 40 h 6 v 10 h -6 z m 0 0" fill="#d1d1d1" fill-opacity="0.984252"/>
|
||||
<path d="m 37 36 h 56 v 44 h -56 z m 0 0" fill="#deddda" fill-opacity="0.984252"/>
|
||||
<path d="m 37 34 h 56 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 h -56 c -1.105469 0 -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m 0 0" fill-opacity="0.940945"/>
|
||||
<path d="m 37 36.859375 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#9a9996" fill-opacity="0.984252"/>
|
||||
<path d="m 37 36 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#f6f5f4" fill-opacity="0.984252"/>
|
||||
<g clip-path="url(#o)">
|
||||
<g clip-path="url(#p)">
|
||||
<path d="m 79 77.386719 v 9.351562 c 0 2.464844 2 4.464844 4.464844 4.464844 h 9.351562 c 2.464844 0 4.464844 -2 4.464844 -4.464844 v -9.351562 c 0 -2.464844 -2 -4.464844 -4.464844 -4.464844 h -9.351562 c -2.464844 0 -4.464844 2 -4.464844 4.464844 z m 0 0" fill="url(#f)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="m 27 100 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#5e5c64" fill-opacity="0.940945"/>
|
||||
<path d="m 27 102 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#9a9996"/>
|
||||
<path d="m 13 106 v 2 c 0 4.433594 3.566406 8 8 8 h 4 v -2 h -4 c -4.433594 0 -8 -3.566406 -8 -8 z m 104 0 c 0 4.433594 -3.566406 8 -8 8 h -4 v 2 h 4 c 4.433594 0 8 -3.566406 8 -8 z m -92 6 v 2 h 80 v -2 z m 0 0" fill="#9e9c99" fill-opacity="0.366142"/>
|
||||
<path d="m 27 38 v 46 l 6 -46 z m 0 0" fill="#7e7c77" fill-opacity="0.11811"/>
|
||||
<path d="m 24 32 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#ffa348" fill-opacity="0.964567"/>
|
||||
<use mask="url(#q)" transform="matrix(1 0 0 1 -8 -16)" xlink:href="#s"/>
|
||||
<path d="m 89.503906 31.144531 l 10.066406 10.066407 l -41.71875 41.71875 l -10.066406 -10.066407 z m 0 0" fill="#ffa348"/>
|
||||
<path d="m 88.246094 29.886719 l 7.550781 7.550781 l -41.71875 41.71875 l -7.550781 -7.550781 z m 0 0" fill="#ff7800"/>
|
||||
<path d="m 86.789062 28.429688 l 2.515626 2.515624 l -41.71875 41.71875 l -2.515626 -2.515624 z m 0 0" fill="#ffbe6f"/>
|
||||
<path d="m 121.898438 -0.101562 c -4.855469 0.921874 -11.730469 5.152343 -18.140626 11.558593 l -16.96875 16.972657 l 12.78125 12.78125 l 16.972657 -16.972657 c 6.40625 -6.40625 10.636719 -13.28125 11.558593 -18.136719 z m 0 0" fill="url(#j)"/>
|
||||
<path d="m 110.011719 13.882812 c -2.1875 -0.398437 -5.421875 0.988282 -8.167969 3.730469 l -11.871094 11.875 l -6.6875 6.6875 c -4.800781 4.800781 -9.234375 12.007813 -9.648437 13.042969 c -0.484375 1.207031 -0.449219 2.730469 0.953125 4.136719 c 1.40625 1.40625 2.917968 1.441406 4.136718 0.953125 c 1.035157 -0.414063 8.292969 -4.984375 13.042969 -9.648438 l 2.402344 -2.398437 l 16.160156 -16.160157 c 2.742188 -2.746093 4.128907 -5.976562 3.730469 -8.167968 c -0.742188 1.390625 -1.859375 2.902344 -3.308594 4.347656 l -13.996094 13.996094 l -5.089843 -5.089844 l 13.996093 -13.996094 c 1.445313 -1.445312 2.960938 -2.566406 4.347657 -3.308594 z m 0 0" fill="url(#k)"/>
|
||||
<path d="m 95.273438 36.914062 l -2.960938 2.960938 l -2.398438 2.402344 c -4.90625 5.101562 -11.855468 10.828125 -11.855468 10.828125 c 1.011718 -0.433594 8.167968 -5.101563 12.914062 -9.769531 l 2.402344 -2.402344 l 2.960938 -2.957032 z m 0 0" fill="#62a0ea"/>
|
||||
<path d="m 87.320312 26.835938 l 13.789063 13.789062 c 0.292969 0.292969 0.292969 0.769531 0 1.0625 s -0.769531 0.292969 -1.0625 0 l -13.789063 -13.789062 c -0.292968 -0.292969 -0.292968 -0.769532 0 -1.0625 c 0.292969 -0.289063 0.769532 -0.289063 1.0625 0 z m 0 0" fill="#3584e4"/>
|
||||
<path d="m 42.421875 89.765625 c -3 3 -6.382813 4.484375 -7.554687 3.3125 c -1.171876 -1.171875 0.3125 -4.554687 3.3125 -7.554687 c 3.003906 -3.003907 6.386718 -4.488282 7.558593 -3.316407 s -0.3125 4.554688 -3.316406 7.558594 z m 0 0" fill="url(#l)"/>
|
||||
<path d="m 45.269531 70.347656 l -7.851562 12.511719 l 7.835937 7.925781 l 12.597656 -7.855468 z m -6.039062 13.171875 l 5.449219 5.449219 c 0.347656 0.347656 0.449218 0.933594 0.097656 1.160156 c -0.886719 0.570313 -2.9375 1.539063 -2.9375 1.539063 c -0.25 0.128906 -0.539063 0.164062 -0.773438 -0.066407 l -4.546875 -4.550781 c -0.234375 -0.230469 -0.207031 -0.527343 -0.066406 -0.773437 l 1.617187 -2.859375 c 0.207032 -0.363281 0.8125 -0.25 1.160157 0.101562 z m 0 0" fill="url(#m)"/>
|
||||
<path d="m 43.332031 74.777344 l 9.867188 9.867187 c 0.394531 0.390625 0.476562 0.871094 0.128906 1.066407 l -7.710937 5.253906 c -0.308594 0.210937 -0.785157 0.160156 -1.171876 -0.226563 l -6.984374 -6.988281 c -0.386719 -0.386719 -0.4375 -0.859375 -0.230469 -1.167969 l 5.234375 -7.8125 c 0.125 -0.285156 0.558594 -0.304687 0.867187 0.007813 z m 0 0" fill="url(#n)"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
<mask id="w">
|
||||
<g filter="url(#g)">
|
||||
<rect fill-opacity="0.8" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<linearGradient id="x" gradientTransform="matrix(0 0.37 -0.98462 0 295.38501 -30.360001)" gradientUnits="userSpaceOnUse" x1="300" x2="428" y1="235" y2="235">
|
||||
<stop offset="0" stop-color="#f9f06b"/>
|
||||
<stop offset="1" stop-color="#f5c211"/>
|
||||
</linearGradient>
|
||||
<clipPath id="y">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="z">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<path d="m 21 16 c -4.433594 0 -8 3.566406 -8 8 v 84 c 0 4.433594 3.566406 8 8 8 h 4 v -4 h 80 v 4 h 4 c 4.433594 0 8 -3.566406 8 -8 v -84 c 0 -4.433594 -3.566406 -8 -8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 21 12 h 88 c 4.417969 0 8 3.582031 8 8 v 68 c 0 4.417969 -3.582031 8 -8 8 h -88 c -4.417969 0 -8 -3.582031 -8 -8 v -68 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#deddda"/>
|
||||
<path d="m 27 28 h 74 v 10 h -74 z m 0 0" fill="url(#b)"/>
|
||||
<path d="m 27 38 h 74 v 46 h -74 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 24 33 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#bf5f00" fill-opacity="0.964567"/>
|
||||
<g fill-opacity="0.984252">
|
||||
<path d="m 18 40 h 6 v 12 h -6 z m 0 0" fill="#acacac"/>
|
||||
<path d="m 18 40 h 6 v 10 h -6 z m 0 0" fill="#d1d1d1"/>
|
||||
<path d="m 37 36 h 56 v 44 h -56 z m 0 0" fill="#deddda"/>
|
||||
</g>
|
||||
<path d="m 37 34 h 56 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 h -56 c -1.105469 0 -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m 0 0" fill-opacity="0.940945"/>
|
||||
<path d="m 37 36.859375 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#9a9996" fill-opacity="0.984252"/>
|
||||
<path d="m 37 36 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#f6f5f4" fill-opacity="0.984252"/>
|
||||
<g clip-path="url(#d)">
|
||||
<g clip-path="url(#e)">
|
||||
<path d="m 79 77.386719 v 9.351562 c 0 2.464844 2 4.464844 4.464844 4.464844 h 9.351562 c 2.464844 0 4.464844 -2 4.464844 -4.464844 v -9.351562 c 0 -2.464844 -2 -4.464844 -4.464844 -4.464844 h -9.351562 c -2.464844 0 -4.464844 2 -4.464844 4.464844 z m 0 0" fill="url(#f)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="m 27 100 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#5e5c64" fill-opacity="0.940945"/>
|
||||
<path d="m 27 102 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#9a9996"/>
|
||||
<path d="m 13 106 v 2 c 0 4.433594 3.566406 8 8 8 h 4 v -2 h -4 c -4.433594 0 -8 -3.566406 -8 -8 z m 104 0 c 0 4.433594 -3.566406 8 -8 8 h -4 v 2 h 4 c 4.433594 0 8 -3.566406 8 -8 z m -92 6 v 2 h 80 v -2 z m 0 0" fill="#9e9c99" fill-opacity="0.366142"/>
|
||||
<path d="m 27 38 v 46 l 6 -46 z m 0 0" fill="#7e7c77" fill-opacity="0.11811"/>
|
||||
<path d="m 24 32 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#ffa348" fill-opacity="0.964567"/>
|
||||
<use mask="url(#h)" transform="matrix(1 0 0 1 -8 -16)" xlink:href="#s"/>
|
||||
<path d="m 89.503906 31.144531 l 10.066406 10.066407 l -41.71875 41.71875 l -10.066406 -10.066407 z m 0 0" fill="#ffa348"/>
|
||||
<path d="m 88.246094 29.886719 l 7.550781 7.550781 l -41.71875 41.71875 l -7.550781 -7.550781 z m 0 0" fill="#ff7800"/>
|
||||
<path d="m 86.789062 28.429688 l 2.515626 2.515624 l -41.71875 41.71875 l -2.515626 -2.515624 z m 0 0" fill="#ffbe6f"/>
|
||||
<path d="m 121.898438 -0.101562 c -4.855469 0.921874 -11.730469 5.152343 -18.140626 11.558593 l -16.96875 16.972657 l 12.78125 12.78125 l 16.972657 -16.972657 c 6.40625 -6.40625 10.636719 -13.28125 11.558593 -18.136719 z m 0 0" fill="url(#j)"/>
|
||||
<path d="m 110.011719 13.882812 c -2.1875 -0.398437 -5.421875 0.988282 -8.167969 3.730469 l -11.871094 11.875 l -6.6875 6.6875 c -4.800781 4.800781 -9.234375 12.007813 -9.648437 13.042969 c -0.484375 1.207031 -0.449219 2.730469 0.953125 4.136719 c 1.40625 1.40625 2.917968 1.441406 4.136718 0.953125 c 1.035157 -0.414063 8.292969 -4.984375 13.042969 -9.648438 l 2.402344 -2.398437 l 16.160156 -16.160157 c 2.742188 -2.746093 4.128907 -5.976562 3.730469 -8.167968 c -0.742188 1.390625 -1.859375 2.902344 -3.308594 4.347656 l -13.996094 13.996094 l -5.089843 -5.089844 l 13.996093 -13.996094 c 1.445313 -1.445312 2.960938 -2.566406 4.347657 -3.308594 z m 0 0" fill="url(#k)"/>
|
||||
<path d="m 95.273438 36.914062 l -2.960938 2.960938 l -2.398438 2.402344 c -4.90625 5.101562 -11.855468 10.828125 -11.855468 10.828125 c 1.011718 -0.433594 8.167968 -5.101563 12.914062 -9.769531 l 2.402344 -2.402344 l 2.960938 -2.957032 z m 0 0" fill="#62a0ea"/>
|
||||
<path d="m 87.320312 26.835938 l 13.789063 13.789062 c 0.292969 0.292969 0.292969 0.769531 0 1.0625 s -0.769531 0.292969 -1.0625 0 l -13.789063 -13.789062 c -0.292968 -0.292969 -0.292968 -0.769532 0 -1.0625 c 0.292969 -0.289063 0.769532 -0.289063 1.0625 0 z m 0 0" fill="#3584e4"/>
|
||||
<path d="m 42.421875 89.765625 c -3 3 -6.382813 4.484375 -7.554687 3.3125 c -1.171876 -1.171875 0.3125 -4.554687 3.3125 -7.554687 c 3.003906 -3.003907 6.386718 -4.488282 7.558593 -3.316407 s -0.3125 4.554688 -3.316406 7.558594 z m 0 0" fill="url(#l)"/>
|
||||
<path d="m 45.269531 70.347656 l -7.851562 12.511719 l 7.835937 7.925781 l 12.597656 -7.855468 z m -6.039062 13.171875 l 5.449219 5.449219 c 0.347656 0.347656 0.449218 0.933594 0.097656 1.160156 c -0.886719 0.570313 -2.9375 1.539063 -2.9375 1.539063 c -0.25 0.128906 -0.539063 0.164062 -0.773438 -0.066407 l -4.546875 -4.550781 c -0.234375 -0.230469 -0.207031 -0.527343 -0.066406 -0.773437 l 1.617187 -2.859375 c 0.207032 -0.363281 0.8125 -0.25 1.160157 0.101562 z m 0 0" fill="url(#m)"/>
|
||||
<path d="m 43.332031 74.777344 l 9.867188 9.867187 c 0.394531 0.390625 0.476562 0.871094 0.128906 1.066407 l -7.710937 5.253906 c -0.308594 0.210937 -0.785157 0.160156 -1.171876 -0.226563 l -6.984374 -6.988281 c -0.386719 -0.386719 -0.4375 -0.859375 -0.230469 -1.167969 l 5.234375 -7.8125 c 0.125 -0.285156 0.558594 -0.304687 0.867187 0.007813 z m 0 0" fill="url(#n)"/>
|
||||
<g clip-path="url(#z)" mask="url(#v)">
|
||||
<g clip-path="url(#y)" mask="url(#w)">
|
||||
<path d="m 128 80.640625 v 47.359375 h -128 v -47.359375 z m 0 0" fill="url(#x)"/>
|
||||
<path d="m 13.308594 80.640625 l 47.355468 47.359375 h 21.214844 l -47.359375 -47.359375 z m 42.421875 0 l 47.363281 47.359375 h 21.214844 l -47.363282 -47.359375 z m 42.429687 0 l 29.839844 29.839844 v -21.210938 l -8.628906 -8.628906 z m -98.160156 7.90625 v 21.214844 l 18.238281 18.238281 h 21.214844 z m 0 0"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 18 KiB |
@@ -1,100 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientTransform="matrix(0.232143 0 0 0.328947 -7.567033 263.82666)" gradientUnits="userSpaceOnUse" x1="88.595886" x2="536.595886" y1="-449.394012" y2="-449.394012">
|
||||
<stop offset="0" stop-color="#acabae"/>
|
||||
<stop offset="0.0384615" stop-color="#deddda"/>
|
||||
<stop offset="0.0768555" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.923077" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.961538" stop-color="#deddda"/>
|
||||
<stop offset="1" stop-color="#9a9996"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="26.999876" x2="100.999876" y1="32.999688" y2="32.999688">
|
||||
<stop offset="0" stop-color="#7e7c77"/>
|
||||
<stop offset="0.3" stop-color="#9a9996"/>
|
||||
<stop offset="1" stop-color="#9a9996"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="67.467916" x2="67.467916" y1="83.999688" y2="36.782906">
|
||||
<stop offset="0" stop-color="#deddda"/>
|
||||
<stop offset="1" stop-color="#c0bfbc"/>
|
||||
</linearGradient>
|
||||
<clipPath id="d">
|
||||
<path d="m 79 72 h 15 v 16 h -15 z m 0 0"/>
|
||||
</clipPath>
|
||||
<clipPath id="e">
|
||||
<path d="m 93.21875 72.921875 l -14.21875 14.21875 h -4.0625 v -18.28125 h 18.28125 z m 0 0"/>
|
||||
</clipPath>
|
||||
<linearGradient id="f" gradientTransform="matrix(0 0.126951 0.126951 0 76.460862 36.359884)" gradientUnits="userSpaceOnUse" x1="344" x2="340" y1="76" y2="72">
|
||||
<stop offset="0" stop-color="#d5d3cf"/>
|
||||
<stop offset="1" stop-color="#ffffff"/>
|
||||
</linearGradient>
|
||||
<filter id="g" height="100%" width="100%" x="0%" y="0%">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="h">
|
||||
<g filter="url(#g)">
|
||||
<rect fill-opacity="0.396" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="i">
|
||||
<rect height="152" width="192"/>
|
||||
</clipPath>
|
||||
<linearGradient id="j" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#1c71d8"/>
|
||||
<stop offset="0.323117" stop-color="#62a0ea"/>
|
||||
<stop offset="0.59387" stop-color="#1b5aa6"/>
|
||||
<stop offset="1" stop-color="#1c71d8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="k" gradientTransform="matrix(1.597748 1.597748 -1.06066 1.06066 -56.853041 -543.720139)" x1="224.504562" x2="231.453873" xlink:href="#j" y1="282.5" y2="282.5"/>
|
||||
<radialGradient id="l" cx="227.599915" cy="201.029724" gradientTransform="matrix(4.072817 4.073078 -5.940048 5.939073 373.883117 -2098.049112)" gradientUnits="userSpaceOnUse" r="2.5">
|
||||
<stop offset="0" stop-color="#93bdf1"/>
|
||||
<stop offset="1" stop-color="#1a5fb4"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="m" gradientTransform="matrix(2.121328 2.121328 -2.174353 2.174353 181.766074 -1021.145947)" gradientUnits="userSpaceOnUse" x1="226.90625" x2="228.86203" y1="288.75" y2="288.767151">
|
||||
<stop offset="0" stop-color="#77767b"/>
|
||||
<stop offset="0.443872" stop-color="#f6f5f4"/>
|
||||
<stop offset="1" stop-color="#5e5c64"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="n" gradientTransform="matrix(1.258421 1.258421 -1.06066 1.06066 57.381892 -503.024312)" gradientUnits="userSpaceOnUse" x1="223.1875" x2="233.0625" y1="278" y2="278">
|
||||
<stop offset="0" stop-color="#ffa348"/>
|
||||
<stop offset="0.265823" stop-color="#ffd7af"/>
|
||||
<stop offset="0.734177" stop-color="#ff8d1c"/>
|
||||
<stop offset="1" stop-color="#ffa348"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="o" gradientTransform="matrix(1.573027 1.573027 -1.06066 1.06066 -14.348129 -574.754333)" x1="224.504562" x2="231.453873" xlink:href="#j" y1="282.5" y2="282.5"/>
|
||||
<path d="m 21 16 c -4.433594 0 -8 3.566406 -8 8 v 84 c 0 4.433594 3.566406 8 8 8 h 4 v -4 h 80 v 4 h 4 c 4.433594 0 8 -3.566406 8 -8 v -84 c 0 -4.433594 -3.566406 -8 -8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 21 12 h 88 c 4.417969 0 8 3.582031 8 8 v 68 c 0 4.417969 -3.582031 8 -8 8 h -88 c -4.417969 0 -8 -3.582031 -8 -8 v -68 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#deddda"/>
|
||||
<path d="m 27 28 h 74 v 10 h -74 z m 0 0" fill="url(#b)"/>
|
||||
<path d="m 27 38 h 74 v 46 h -74 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 24 33 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#bf5f00" fill-opacity="0.964567"/>
|
||||
<g fill-opacity="0.984252">
|
||||
<path d="m 18 40 h 6 v 12 h -6 z m 0 0" fill="#acacac"/>
|
||||
<path d="m 18 40 h 6 v 10 h -6 z m 0 0" fill="#d1d1d1"/>
|
||||
<path d="m 37 36 h 56 v 44 h -56 z m 0 0" fill="#deddda"/>
|
||||
</g>
|
||||
<path d="m 37 34 h 56 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 h -56 c -1.105469 0 -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m 0 0" fill-opacity="0.940945"/>
|
||||
<path d="m 37 36.859375 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#9a9996" fill-opacity="0.984252"/>
|
||||
<path d="m 37 36 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#f6f5f4" fill-opacity="0.984252"/>
|
||||
<g clip-path="url(#d)">
|
||||
<g clip-path="url(#e)">
|
||||
<path d="m 79 77.386719 v 9.351562 c 0 2.464844 2 4.464844 4.464844 4.464844 h 9.351562 c 2.464844 0 4.464844 -2 4.464844 -4.464844 v -9.351562 c 0 -2.464844 -2 -4.464844 -4.464844 -4.464844 h -9.351562 c -2.464844 0 -4.464844 2 -4.464844 4.464844 z m 0 0" fill="url(#f)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="m 27 100 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#5e5c64" fill-opacity="0.940945"/>
|
||||
<path d="m 27 102 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#9a9996"/>
|
||||
<path d="m 13 106 v 2 c 0 4.433594 3.566406 8 8 8 h 4 v -2 h -4 c -4.433594 0 -8 -3.566406 -8 -8 z m 104 0 c 0 4.433594 -3.566406 8 -8 8 h -4 v 2 h 4 c 4.433594 0 8 -3.566406 8 -8 z m -92 6 v 2 h 80 v -2 z m 0 0" fill="#9e9c99" fill-opacity="0.366142"/>
|
||||
<path d="m 27 38 v 46 l 6 -46 z m 0 0" fill="#7e7c77" fill-opacity="0.11811"/>
|
||||
<path d="m 24 32 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#ffa348" fill-opacity="0.964567"/>
|
||||
<g clip-path="url(#i)" mask="url(#h)" transform="matrix(1 0 0 1 -8 -16)">
|
||||
<path d="m 29 112 c -4.433594 0 -8 -3.566406 -8 -8 v -2 c 0 4.433594 3.566406 8 8 8 h 88 c 4.433594 0 8 -3.566406 8 -8 v 2 c 0 4.433594 -3.566406 8 -8 8 z m 0 0" fill="#f6f5f4"/>
|
||||
</g>
|
||||
<path d="m 89.503906 31.144531 l 10.066406 10.066407 l -41.71875 41.71875 l -10.066406 -10.066407 z m 0 0" fill="#ffa348"/>
|
||||
<path d="m 88.246094 29.886719 l 7.550781 7.550781 l -41.71875 41.71875 l -7.550781 -7.550781 z m 0 0" fill="#ff7800"/>
|
||||
<path d="m 86.789062 28.429688 l 2.515626 2.515624 l -41.71875 41.71875 l -2.515626 -2.515624 z m 0 0" fill="#ffbe6f"/>
|
||||
<path d="m 121.898438 -0.101562 c -4.855469 0.921874 -11.730469 5.152343 -18.140626 11.558593 l -16.96875 16.972657 l 12.78125 12.78125 l 16.972657 -16.972657 c 6.40625 -6.40625 10.636719 -13.28125 11.558593 -18.136719 z m 0 0" fill="url(#k)"/>
|
||||
<path d="m 110.011719 13.882812 c -2.1875 -0.398437 -5.421875 0.988282 -8.167969 3.730469 l -11.871094 11.875 l -6.6875 6.6875 c -4.800781 4.800781 -9.234375 12.007813 -9.648437 13.042969 c -0.484375 1.207031 -0.449219 2.730469 0.953125 4.136719 c 1.40625 1.40625 2.917968 1.441406 4.136718 0.953125 c 1.035157 -0.414063 8.292969 -4.984375 13.042969 -9.648438 l 2.402344 -2.398437 l 16.160156 -16.160157 c 2.742188 -2.746093 4.128907 -5.976562 3.730469 -8.167968 c -0.742188 1.390625 -1.859375 2.902344 -3.308594 4.347656 l -13.996094 13.996094 l -5.089843 -5.089844 l 13.996093 -13.996094 c 1.445313 -1.445312 2.960938 -2.566406 4.347657 -3.308594 z m 0 0" fill="url(#l)"/>
|
||||
<path d="m 95.273438 36.914062 l -2.960938 2.960938 l -2.398438 2.402344 c -4.90625 5.101562 -11.855468 10.828125 -11.855468 10.828125 c 1.011718 -0.433594 8.167968 -5.101563 12.914062 -9.769531 l 2.402344 -2.402344 l 2.960938 -2.957032 z m 0 0" fill="#62a0ea"/>
|
||||
<path d="m 87.320312 26.835938 l 13.789063 13.789062 c 0.292969 0.292969 0.292969 0.769531 0 1.0625 s -0.769531 0.292969 -1.0625 0 l -13.789063 -13.789062 c -0.292968 -0.292969 -0.292968 -0.769532 0 -1.0625 c 0.292969 -0.289063 0.769532 -0.289063 1.0625 0 z m 0 0" fill="#3584e4"/>
|
||||
<path d="m 42.421875 89.765625 c -3 3 -6.382813 4.484375 -7.554687 3.3125 c -1.171876 -1.171875 0.3125 -4.554687 3.3125 -7.554687 c 3.003906 -3.003907 6.386718 -4.488282 7.558593 -3.316407 s -0.3125 4.554688 -3.316406 7.558594 z m 0 0" fill="url(#m)"/>
|
||||
<path d="m 45.269531 70.347656 l -7.851562 12.511719 l 7.835937 7.925781 l 12.597656 -7.855468 z m -6.039062 13.171875 l 5.449219 5.449219 c 0.347656 0.347656 0.449218 0.933594 0.097656 1.160156 c -0.886719 0.570313 -2.9375 1.539063 -2.9375 1.539063 c -0.25 0.128906 -0.539063 0.164062 -0.773438 -0.066407 l -4.546875 -4.550781 c -0.234375 -0.230469 -0.207031 -0.527343 -0.066406 -0.773437 l 1.617187 -2.859375 c 0.207032 -0.363281 0.8125 -0.25 1.160157 0.101562 z m 0 0" fill="url(#n)"/>
|
||||
<path d="m 43.332031 74.777344 l 9.867188 9.867187 c 0.394531 0.390625 0.476562 0.871094 0.128906 1.066407 l -7.710937 5.253906 c -0.308594 0.210937 -0.785157 0.160156 -1.171876 -0.226563 l -6.984374 -6.988281 c -0.386719 -0.386719 -0.4375 -0.859375 -0.230469 -1.167969 l 5.234375 -7.8125 c 0.125 -0.285156 0.558594 -0.304687 0.867187 0.007813 z m 0 0" fill="url(#o)"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.4 KiB |
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<filter id="a" height="100%" width="100%" x="0%" y="0%">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="b">
|
||||
<g filter="url(#a)">
|
||||
<rect fill-opacity="0.396" height="16" width="16"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="c">
|
||||
<rect height="152" width="192"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#c)" mask="url(#b)" transform="matrix(1 0 0 1 -168 -16)">
|
||||
<path d="m 29 112 c -4.433594 0 -8 -3.566406 -8 -8 v -2 c 0 4.433594 3.566406 8 8 8 h 88 c 4.433594 0 8 -3.566406 8 -8 v 2 c 0 4.433594 -3.566406 8 -8 8 z m 0 0" fill="#f6f5f4"/>
|
||||
</g>
|
||||
<g fill="#2e3436">
|
||||
<path d="m 4 2 v 2 h 5.585938 l 2 -2 z m -2 3 c -0.5 0 -1 0.5 -1 1 v 4 c 0 0.5 0.5 1 1 1 h 1 v -2 h 2 c 0 -0.265625 0.105469 -0.519531 0.292969 -0.707031 l 3.292969 -3.292969 z m 11.414062 0 l -4 4 h 3.585938 v 2 h 1 c 0.5 0 1 -0.5 1 -1 v -4 c 0 -0.5 -0.5 -1 -1 -1 z m -9.414062 5 v 5 h 8 v -5 h -3.585938 l -0.707031 0.707031 c -0.1875 0.1875 -0.441406 0.292969 -0.707031 0.292969 h -1 c -0.550781 0 -1 -0.449219 -1 -1 z m 0 0"/>
|
||||
<path d="m 6 10 h 1 l 9 -9 l -1 -1 l -9 9 z m 0 0"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -12,12 +12,3 @@ install_data('org.gtk.PrintEditor4.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# appdata
|
||||
install_data('org.gtk.PrintEditor4.appdata.xml', install_dir: gtk_appdatadir)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
||||
foreach size: ['scalable', 'symbolic']
|
||||
install_subdir('data/' + size,
|
||||
install_dir: icontheme_dir
|
||||
)
|
||||
endforeach
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Name=Print Editor
|
||||
Comment=A simple editor demonstrating GTK printing
|
||||
Exec=gtk4-print-editor %f
|
||||
Icon=org.gtk.PrintEditor4.Devel
|
||||
Icon=text-editor-symbolic
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
|
||||
@@ -633,7 +633,7 @@ activate_about (GSimpleAction *action,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK printing",
|
||||
"authors", (const char *[]){ "Alexander Larsson", NULL },
|
||||
"logo-icon-name", "org.gtk.PrintEditor4.Devel",
|
||||
"logo-icon-name", "text-editor-symbolic",
|
||||
"title", "About GTK Print Editor",
|
||||
"system-information", sysinfo->str,
|
||||
NULL);
|
||||
@@ -781,8 +781,6 @@ activate (GApplication *app)
|
||||
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (main_window), TRUE);
|
||||
update_title (GTK_WINDOW (main_window));
|
||||
|
||||
gtk_widget_add_css_class (main_window, "devel");
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (main_window), box);
|
||||
|
||||
|
||||
@@ -436,6 +436,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="title">GTK Widget Factory</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar1">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="stack_switcher">
|
||||
<property name="stack">toplevel_stack</property>
|
||||
|
||||
@@ -1423,6 +1423,7 @@ the search bar below the header bar.
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
@@ -1536,6 +1537,7 @@ GtkMenuButton, GtkRevealer and GtkListBox.
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -177,7 +177,6 @@ def ConvertToDocbook(infile, outfile):
|
||||
subprocess.check_call(["pandoc", infile, "-o", outfile,
|
||||
"--from=" + input_format,
|
||||
"--to=" + output_format,
|
||||
"--standalone",
|
||||
"--top-level-division=" + division])
|
||||
|
||||
def ExpandGtkDocAbbreviations(infile, outfile):
|
||||
|
||||
@@ -54,9 +54,8 @@
|
||||
<section>
|
||||
<xi:include href="xml/gtkfilter.xml" />
|
||||
<xi:include href="xml/gtkcustomfilter.xml" />
|
||||
<xi:include href="xml/gtkmultifilter.xml" />
|
||||
<xi:include href="xml/gtkstringfilter.xml" />
|
||||
<xi:include href="xml/gtkfilefilter.xml" />
|
||||
<xi:include href="xml/gtkmultifilter.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkflattenlistmodel.xml" />
|
||||
<xi:include href="xml/gtkmaplistmodel.xml" />
|
||||
@@ -65,9 +64,9 @@
|
||||
<section>
|
||||
<xi:include href="xml/gtksorter.xml" />
|
||||
<xi:include href="xml/gtkcustomsorter.xml" />
|
||||
<xi:include href="xml/gtkmultisorter.xml" />
|
||||
<xi:include href="xml/gtkstringsorter.xml" />
|
||||
<xi:include href="xml/gtknumericsorter.xml" />
|
||||
<xi:include href="xml/gtkmultisorter.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkselectionmodel.xml" />
|
||||
<section>
|
||||
@@ -75,7 +74,6 @@
|
||||
<xi:include href="xml/gtksingleselection.xml" />
|
||||
<xi:include href="xml/gtkmultiselection.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkselectionfiltermodel.xml" />
|
||||
<xi:include href="xml/gtkbookmarklist.xml" />
|
||||
<xi:include href="xml/gtkdirectorylist.xml" />
|
||||
<xi:include href="xml/gtkstringlist.xml" />
|
||||
@@ -93,9 +91,7 @@
|
||||
<xi:include href="xml/gtklistview.xml" />
|
||||
<xi:include href="xml/gtkgridview.xml" />
|
||||
<xi:include href="xml/gtkcolumnview.xml" />
|
||||
<section>
|
||||
<xi:include href="xml/gtkcolumnviewcolumn.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkcolumnviewcolumn.xml" />
|
||||
<xi:include href="xml/gtkdropdown.xml" />
|
||||
</chapter>
|
||||
|
||||
@@ -223,7 +219,6 @@
|
||||
<xi:include href="xml/gtksearchentry.xml" />
|
||||
<xi:include href="xml/gtksearchbar.xml" />
|
||||
<xi:include href="xml/gtkeditablelabel.xml" />
|
||||
<xi:include href="xml/gtksuggestionentry.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="TextWidgetObjects">
|
||||
@@ -289,6 +284,7 @@
|
||||
<xi:include href="xml/gtkfilechoosernative.xml" />
|
||||
<xi:include href="xml/gtkfilechooserdialog.xml" />
|
||||
<xi:include href="xml/gtkfilechooserwidget.xml" />
|
||||
<xi:include href="xml/gtkfilefilter.xml" />
|
||||
<xi:include href="xml/gtkfontchooser.xml" />
|
||||
<xi:include href="xml/gtkfontbutton.xml" />
|
||||
<xi:include href="xml/gtkfontchooserwidget.xml" />
|
||||
|
||||
@@ -375,7 +375,7 @@ gtk_bitset_subtract
|
||||
gtk_bitset_difference
|
||||
gtk_bitset_shift_left
|
||||
gtk_bitset_shift_right
|
||||
gtk_bitset_splice
|
||||
gtk_bitset_slice
|
||||
<SUBSECTION>
|
||||
GtkBitsetIter
|
||||
gtk_bitset_iter_init_first
|
||||
@@ -423,7 +423,6 @@ gtk_selection_model_get_type
|
||||
GtkNoSelection
|
||||
gtk_no_selection_new
|
||||
gtk_no_selection_get_model
|
||||
gtk_no_selection_set_model
|
||||
<SUBSECTION Private>
|
||||
gtk_no_selection_get_type
|
||||
</SECTION>
|
||||
@@ -435,7 +434,6 @@ GtkSingleSelection
|
||||
GTK_INVALID_LIST_POSITION
|
||||
gtk_single_selection_new
|
||||
gtk_single_selection_get_model
|
||||
gtk_single_selection_set_model
|
||||
gtk_single_selection_get_selected
|
||||
gtk_single_selection_set_selected
|
||||
gtk_single_selection_get_selected_item
|
||||
@@ -452,8 +450,6 @@ gtk_single_selection_get_type
|
||||
<TITLE>GtkMultiSeledction</TITLE>
|
||||
GtkMultiSelection
|
||||
gtk_multi_selection_new
|
||||
gtk_multi_selection_get_model
|
||||
gtk_multi_selection_set_model
|
||||
<SUBSECTION Private>
|
||||
gtk_multi_selection_get_type
|
||||
</SECTION>
|
||||
@@ -1300,19 +1296,23 @@ gtk_file_chooser_get_current_name
|
||||
<SUBSECTION>
|
||||
gtk_file_chooser_get_file
|
||||
gtk_file_chooser_set_file
|
||||
gtk_file_chooser_select_file
|
||||
gtk_file_chooser_unselect_file
|
||||
gtk_file_chooser_select_all
|
||||
gtk_file_chooser_unselect_all
|
||||
gtk_file_chooser_get_files
|
||||
gtk_file_chooser_set_current_folder
|
||||
gtk_file_chooser_get_current_folder
|
||||
<SUBSECTION>
|
||||
gtk_file_chooser_add_filter
|
||||
gtk_file_chooser_remove_filter
|
||||
gtk_file_chooser_get_filters
|
||||
gtk_file_chooser_list_filters
|
||||
gtk_file_chooser_set_filter
|
||||
gtk_file_chooser_get_filter
|
||||
<SUBSECTION>
|
||||
gtk_file_chooser_add_shortcut_folder
|
||||
gtk_file_chooser_remove_shortcut_folder
|
||||
gtk_file_chooser_get_shortcut_folders
|
||||
gtk_file_chooser_list_shortcut_folders
|
||||
<SUBSECTION>
|
||||
gtk_file_chooser_add_choice
|
||||
gtk_file_chooser_remove_choice
|
||||
@@ -1409,13 +1409,18 @@ GtkFileChooserButtonPrivate
|
||||
<SECTION>
|
||||
<FILE>gtkfilefilter</FILE>
|
||||
GtkFileFilter
|
||||
GtkFileFilterInfo
|
||||
GtkFileFilterFlags
|
||||
GtkFileFilterFunc
|
||||
gtk_file_filter_new
|
||||
gtk_file_filter_set_name
|
||||
gtk_file_filter_get_name
|
||||
gtk_file_filter_add_mime_type
|
||||
gtk_file_filter_add_pattern
|
||||
gtk_file_filter_add_pixbuf_formats
|
||||
gtk_file_filter_get_attributes
|
||||
gtk_file_filter_add_custom
|
||||
gtk_file_filter_get_needed
|
||||
gtk_file_filter_filter
|
||||
|
||||
<SUBSECTION Serialization>
|
||||
gtk_file_filter_new_from_gvariant
|
||||
@@ -1440,8 +1445,6 @@ gtk_directory_list_get_file
|
||||
gtk_directory_list_set_file
|
||||
gtk_directory_list_get_io_priority
|
||||
gtk_directory_list_set_io_priority
|
||||
gtk_directory_list_get_monitored
|
||||
gtk_directory_list_set_monitored
|
||||
gtk_directory_list_is_loading
|
||||
gtk_directory_list_get_error
|
||||
<SUBSECTION Standard>
|
||||
@@ -1536,6 +1539,7 @@ gtk_custom_filter_get_type
|
||||
<TITLE>GtkFilterListModel</TITLE>
|
||||
GtkFilterListModel
|
||||
gtk_filter_list_model_new
|
||||
gtk_filter_list_model_new_for_type
|
||||
gtk_filter_list_model_set_model
|
||||
gtk_filter_list_model_get_model
|
||||
gtk_filter_list_model_set_filter
|
||||
@@ -2697,6 +2701,7 @@ gtk_size_group_get_type
|
||||
<TITLE>GtkSliceListModel</TITLE>
|
||||
GtkSliceListModel
|
||||
gtk_slice_list_model_new
|
||||
gtk_slice_list_model_new_for_type
|
||||
gtk_slice_list_model_set_model
|
||||
gtk_slice_list_model_get_model
|
||||
gtk_slice_list_model_set_offset
|
||||
@@ -2828,13 +2833,11 @@ gtk_tree_list_row_sorter_get_type
|
||||
<TITLE>GtkSortListModel</TITLE>
|
||||
GtkSortListModel
|
||||
gtk_sort_list_model_new
|
||||
gtk_sort_list_model_new_for_type
|
||||
gtk_sort_list_model_set_sorter
|
||||
gtk_sort_list_model_get_sorter
|
||||
gtk_sort_list_model_set_model
|
||||
gtk_sort_list_model_get_model
|
||||
gtk_sort_list_model_set_incremental
|
||||
gtk_sort_list_model_get_incremental
|
||||
gtk_sort_list_model_get_peanding
|
||||
<SUBSECTION Standard>
|
||||
GTK_SORT_LIST_MODEL
|
||||
GTK_IS_SORT_LIST_MODEL
|
||||
@@ -3423,7 +3426,6 @@ gtk_tree_list_row_get_type
|
||||
<SECTION>
|
||||
<FILE>gtktreeexpander</FILE>
|
||||
<TITLE>GtkTreeExpander</TITLE>
|
||||
GtkTreeExpander
|
||||
gtk_tree_expander_new
|
||||
gtk_tree_expander_get_child
|
||||
gtk_tree_expander_set_child
|
||||
@@ -7545,27 +7547,12 @@ gtk_expression_watch_unwatch
|
||||
<SUBSECTION>
|
||||
gtk_property_expression_new
|
||||
gtk_property_expression_new_for_pspec
|
||||
gtk_property_expression_get_expression
|
||||
gtk_property_expression_get_pspec
|
||||
gtk_constant_expression_new
|
||||
gtk_constant_expression_new_for_value
|
||||
gtk_constant_expression_get_value
|
||||
gtk_object_expression_new
|
||||
gtk_object_expression_get_object
|
||||
gtk_closure_expression_new
|
||||
gtk_cclosure_expression_new
|
||||
|
||||
<SUBSECTION>
|
||||
GTK_VALUE_HOLDS_EXPRESSION
|
||||
gtk_value_set_expression
|
||||
gtk_value_take_expression
|
||||
gtk_value_get_expression
|
||||
gtk_value_dup_expression
|
||||
|
||||
<SUBSECTION>
|
||||
GtkParamSpecExpression
|
||||
gtk_param_spec_expression
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_IS_EXPRESSION
|
||||
GTK_TYPE_EXPRESSION
|
||||
@@ -7626,42 +7613,6 @@ gtk_string_list_take
|
||||
gtk_string_list_remove
|
||||
gtk_string_list_splice
|
||||
gtk_string_list_get_string
|
||||
<SUBSECTION>
|
||||
GtkStringObject
|
||||
gtk_string_object_new
|
||||
gtk_string_object_get_string
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkselectionfiltermodel</FILE>
|
||||
<TITLE>GtkSelectionFilterModel</TITLE>
|
||||
GtkSelectionFilterModel
|
||||
gtk_selection_filter_model_new
|
||||
gtk_selection_filter_model_new_for_type
|
||||
gtk_selection_filter_model_set_model
|
||||
gtk_selection_filter_model_get_model
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtksuggestionentry</FILE>
|
||||
<TITLE>GtkSuggestionEntry</TITLE>
|
||||
GtkSuggestionEntry
|
||||
gtk_suggestion_entry_new
|
||||
gtk_suggestion_entry_set_model
|
||||
gtk_suggestion_entry_get_model
|
||||
gtk_suggestion_entry_set_from_strings
|
||||
gtk_suggestion_entry_set_factory
|
||||
gtk_suggestion_entry_get_factory
|
||||
gtk_suggestion_entry_set_expression
|
||||
gtk_suggestion_entry_get_expression
|
||||
gtk_suggestion_entry_set_use_filter
|
||||
gtk_suggestion_entry_get_use_filter
|
||||
gtk_suggestion_entry_set_insert_selection
|
||||
gtk_suggestion_entry_get_insert_selection
|
||||
gtk_suggestion_entry_set_insert_prefix
|
||||
gtk_suggestion_entry_get_insert_prefix
|
||||
gtk_suggestion_entry_set_show_button
|
||||
gtk_suggestion_entry_get_show_button
|
||||
gtk_suggestion_entry_set_minimum_length
|
||||
gtk_suggestion_entry_get_minimum_length
|
||||
</SECTION>
|
||||
|
||||
@@ -19,7 +19,6 @@ gtk_assistant_get_type
|
||||
gtk_assistant_page_get_type
|
||||
gtk_bin_layout_get_type
|
||||
gtk_bitset_get_type
|
||||
gtk_expression_get_type
|
||||
gtk_bookmark_list_get_type
|
||||
gtk_box_get_type
|
||||
gtk_box_layout_get_type
|
||||
@@ -30,7 +29,6 @@ gtk_builder_list_item_factory_get_type
|
||||
gtk_builder_scope_get_type
|
||||
gtk_button_get_type
|
||||
gtk_calendar_get_type
|
||||
gtk_cclosure_expression_get_type
|
||||
gtk_cell_area_get_type
|
||||
gtk_cell_area_box_get_type
|
||||
gtk_cell_area_context_get_type
|
||||
@@ -48,7 +46,6 @@ gtk_cell_renderer_toggle_get_type
|
||||
gtk_cell_view_get_type
|
||||
gtk_center_layout_get_type
|
||||
gtk_check_button_get_type
|
||||
gtk_closure_expression_get_type
|
||||
gtk_color_button_get_type
|
||||
gtk_color_chooser_get_type
|
||||
gtk_color_chooser_dialog_get_type
|
||||
@@ -57,7 +54,6 @@ gtk_column_view_get_type
|
||||
gtk_column_view_column_get_type
|
||||
gtk_combo_box_get_type
|
||||
gtk_combo_box_text_get_type
|
||||
gtk_constant_expression_get_type
|
||||
gtk_constraint_get_type
|
||||
gtk_constraint_guide_get_type
|
||||
gtk_constraint_layout_get_type
|
||||
@@ -154,7 +150,6 @@ gtk_no_selection_get_type
|
||||
gtk_notebook_get_type
|
||||
gtk_notebook_page_get_type
|
||||
gtk_numeric_sorter_get_type
|
||||
gtk_object_expression_get_type
|
||||
gtk_orientable_get_type
|
||||
gtk_overlay_get_type
|
||||
gtk_overlay_layout_get_type
|
||||
@@ -177,7 +172,6 @@ gtk_print_operation_preview_get_type
|
||||
gtk_print_settings_get_type
|
||||
@DISABLE_ON_W32@gtk_print_unix_dialog_get_type
|
||||
gtk_progress_bar_get_type
|
||||
gtk_property_expression_get_type
|
||||
gtk_radio_button_get_type
|
||||
gtk_range_get_type
|
||||
gtk_recent_manager_get_type
|
||||
@@ -190,7 +184,6 @@ gtk_scrollbar_get_type
|
||||
gtk_scrolled_window_get_type
|
||||
gtk_search_bar_get_type
|
||||
gtk_search_entry_get_type
|
||||
gtk_selection_filter_model_get_type
|
||||
gtk_selection_model_get_type
|
||||
gtk_separator_get_type
|
||||
gtk_settings_get_type
|
||||
@@ -220,7 +213,6 @@ gtk_string_filter_get_type
|
||||
gtk_string_list_get_type
|
||||
gtk_string_object_get_type
|
||||
gtk_string_sorter_get_type
|
||||
gtk_suggestion_entry_get_type
|
||||
gtk_switch_get_type
|
||||
gtk_level_bar_get_type
|
||||
gtk_style_context_get_type
|
||||
@@ -236,7 +228,6 @@ gtk_text_view_get_type
|
||||
gtk_toggle_button_get_type
|
||||
gtk_tree_drag_dest_get_type
|
||||
gtk_tree_drag_source_get_type
|
||||
gtk_tree_expander_get_type
|
||||
gtk_tree_list_model_get_type
|
||||
gtk_tree_list_row_get_type
|
||||
gtk_tree_list_row_sorter_get_type
|
||||
|
||||
@@ -137,41 +137,8 @@ use gtk_button_new_from_icon_name().
|
||||
|
||||
### Stop using GtkWidget event signals
|
||||
|
||||
Event controllers and gestures replace event signals in GTK 4.
|
||||
|
||||
Most of them have been backported to GTK 3.x so you can prepare
|
||||
for this change.
|
||||
|
||||
| Signal | Event controller |
|
||||
| --- | --- |
|
||||
| ::event | #GtkEventControllerLegacy |
|
||||
| ::event-after | #GtkEventControllerLegacy |
|
||||
| ::button-press-event | #GtkGestureClick |
|
||||
| ::button-release-event | #GtkGestureClick |
|
||||
| ::touch-event | various touch gestures |
|
||||
| ::scroll-event | #GtkEventControllerScroll |
|
||||
| ::motion-notify-event | #GtkEventControllerMotion |
|
||||
| ::delete-event | - |
|
||||
| ::key-press-event | #GtkEventControllerKey |
|
||||
| ::key-release-event | #GtkEventControllerKey |
|
||||
| ::enter-notify-event | #GtkEventControllerMotion |
|
||||
| ::leave-notify-event | #GtkEventControllerMotion |
|
||||
| ::configure-event | replaced by #GdkSurface::size-changed |
|
||||
| ::focus-in-event | #GtkEventControllerFocus |
|
||||
| ::focus-out-event | #GtkEventControllerFocus |
|
||||
| ::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 |
|
||||
| ::selection-notify-event | replaced by #GdkClipboard |
|
||||
| Drag-and-Drop signals | #GtkDragSource, #GtkDropTarget |
|
||||
| ::proximity-in-event | #GtkGestureStylus |
|
||||
| ::proximity-out-event | #GtkGestureStylus |
|
||||
| ::visibility-notify-event | - |
|
||||
| ::window-state-event | replaced by #GdkToplevel:state |
|
||||
| ::damage-event | - |
|
||||
| ::grab-broken-event | - |
|
||||
Event controllers and #GtkGestures replace event signals in GTK 4.
|
||||
They have been backported to GTK 3.x so you can prepare for this change.
|
||||
|
||||
### Set a proper application ID
|
||||
|
||||
@@ -203,7 +170,7 @@ in GTK 3, you can prepare for the switch by using gtk_widget_destroy()
|
||||
only on toplevel windows, and replace all other uses with
|
||||
gtk_container_remove() or g_object_unref().
|
||||
|
||||
### Reduce the use of generic container APIs
|
||||
### Reduce the use of generic container APIs</title>
|
||||
|
||||
GTK 4 removes gtk_container_add() and gtk_container_remove(). While there
|
||||
is not always a replacement for gtk_container_remove() in GTK 3, you can
|
||||
@@ -444,7 +411,6 @@ and gtk_box_append(). You can also reorder box children as necessary.
|
||||
The gtk_header_bar_set_show_close_button() function has been renamed to
|
||||
the more accurate name gtk_header_bar_set_show_title_buttons(). The
|
||||
corresponding getter and the property itself have also been renamed.
|
||||
The default value of the property is now %TRUE instead of %FALSE.
|
||||
|
||||
The gtk_header_bar_set_custom_title() function has been renamed to
|
||||
the more accurate name gtk_header_bar_set_title_widget(). The
|
||||
@@ -564,26 +530,6 @@ by a layout manager (if they are layout-related), or handled in some
|
||||
other way. One possibility is to use child meta objects, as seen with
|
||||
GtkAssistantPage, GtkStackPage and the like.
|
||||
|
||||
The replacements for gtk_container_add() are:
|
||||
|
||||
| Widget | Replacement |
|
||||
| ------ | ----------- |
|
||||
| GtkActionBar | gtk_action_bar_pack_start(), gtk_action_bar_pack_end() |
|
||||
| GtkBox | gtk_box_append() |
|
||||
| GtkExpander | gtk_expander_set_child() |
|
||||
| GtkFixed | gtk_fixed_put() |
|
||||
| GtkFlowBox | gtk_flow_box_insert() |
|
||||
| GtkGrid | gtk_grid_attach() |
|
||||
| GtkHeaderBar | gtk_header_bar_pack_start(), gtk_header_bar_pack_end() |
|
||||
| GtkIconView | - |
|
||||
| GtkInfoBar | gtk_info_bar_add_child() |
|
||||
| GtkListBox | gtk_list_box_insert() |
|
||||
| GtkNotebook | gtk_notebook_append_page() |
|
||||
| GtkPaned | gtk_paned_set_start_child(), gtk_paned_set_end_child() |
|
||||
| GtkStack | gtk_stack_add_named() |
|
||||
| GtkTextView | gtk_text_view_add_child_at_anchor(), gtk_text_view_add_overlay() |
|
||||
| GtkTreeView | - |
|
||||
|
||||
### Stop using GtkContainer::border-width
|
||||
|
||||
GTK 4 has removed the #GtkContainer::border-width property (together
|
||||
|
||||
@@ -123,32 +123,6 @@ the number of listitems they create such as with gtk_grid_view_set_max_columns()
|
||||
and developers running into performance problems should definitely study the
|
||||
tradeoffs of those and experiment with them.
|
||||
|
||||
## Choosing the right model {#model-choosing}
|
||||
|
||||
GTK offers a wide variety of wrapping models which change or supplement an
|
||||
existing model (or models) in some way. But when it comes to storing your
|
||||
actual data, there are only a few ready-made choices available: #GListStore
|
||||
and #GtkStringList.
|
||||
|
||||
GListStore is backed by a balanced tree and has performance characteristics
|
||||
that are expected for that data structure. It works reasonably well for dataset
|
||||
sizes in the 1,000,000 range, and can handle insertions and deletions. It uses
|
||||
a cached iter to make linear access to the items fast.
|
||||
|
||||
GtkStringList is not a general store - it can only handle strings. It is
|
||||
backed by an dynamically allocated array and has performance characteristics
|
||||
that are expected for that data structure. GtkStringList is a good fit for any
|
||||
place where you would otherwise use `char*[]` and works best if the dataset
|
||||
is not very dynamic.
|
||||
|
||||
If these models don't fit your use case or scalability requirements, you
|
||||
should make a custom #GListModel. It is a small interface and not very hard
|
||||
to implement.
|
||||
|
||||
For asymptotic performance comparisons between tree- and array-based
|
||||
implementations, see this
|
||||
[article](https://en.wikipedia.org/wiki/Dynamic_array#Performance).
|
||||
|
||||
## Displaying trees {#displaying-trees}
|
||||
|
||||
While #GtkTreeView provided built-in support for trees, the list widgets, and
|
||||
@@ -209,7 +183,7 @@ transitioning code for easy lookup:
|
||||
| #GtkTreeModel | #GListModel |
|
||||
| #GtkTreePath | #guint position, #GtkTreeListRow |
|
||||
| #GtkTreeIter | #guint position |
|
||||
| #GtkTreeRowReference | #GObject item |
|
||||
| GtkTreeRowReference | #GObject item |
|
||||
| #GtkListStore | #GListStore |
|
||||
| #GtkTreeStore | #GtkTreeListModel, #GtkTreeExpander |
|
||||
| #GtkTreeSelection | #GtkSelectionModel |
|
||||
@@ -224,6 +198,4 @@ transitioning code for easy lookup:
|
||||
| #GtkCellLayout | #GtkListItemFactory |
|
||||
| #GtkCellArea | #GtkWidget |
|
||||
| #GtkCellRenderer | #GtkWidget |
|
||||
| #GtkComboBoxText | #GtkSuggestionEntry |
|
||||
| #GtkEntryCompletion | #GtkSuggestionEntry |
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="lines_label">
|
||||
<property name="visible">0</property>
|
||||
|
||||
@@ -15,6 +15,7 @@ new_window (GApplication *app,
|
||||
gtk_window_set_icon_name (GTK_WINDOW (window), "sunny");
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifndef GDK_ARRAY_TYPE_NAME
|
||||
#define GDK_ARRAY_TYPE_NAME GdkArray
|
||||
#endif
|
||||
|
||||
#ifndef GDK_ARRAY_NAME
|
||||
#define GDK_ARRAY_NAME gdk_array
|
||||
#endif
|
||||
|
||||
#ifndef GDK_ARRAY_ELEMENT_TYPE
|
||||
#define GDK_ARRAY_ELEMENT_TYPE gpointer
|
||||
#endif
|
||||
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
#if GDK_ARRAY_PREALLOC == 0
|
||||
#undef GDK_ARRAY_PREALLOC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||
#define GDK_ARRAY_REAL_SIZE(_size) ((_size) + 1)
|
||||
#else
|
||||
#define GDK_ARRAY_REAL_SIZE(_size) (_size)
|
||||
#endif
|
||||
|
||||
/* make this readable */
|
||||
#define _T_ GDK_ARRAY_ELEMENT_TYPE
|
||||
#define GdkArray GDK_ARRAY_TYPE_NAME
|
||||
#define gdk_array_paste_more(GDK_ARRAY_NAME, func_name) GDK_ARRAY_NAME ## _ ## func_name
|
||||
#define gdk_array_paste(GDK_ARRAY_NAME, func_name) gdk_array_paste_more (GDK_ARRAY_NAME, func_name)
|
||||
#define gdk_array(func_name) gdk_array_paste (GDK_ARRAY_NAME, func_name)
|
||||
|
||||
typedef struct GdkArray GdkArray;
|
||||
|
||||
struct GdkArray
|
||||
{
|
||||
_T_ *start;
|
||||
_T_ *end;
|
||||
_T_ *end_allocation;
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
_T_ preallocated[GDK_ARRAY_REAL_SIZE(GDK_ARRAY_PREALLOC)];
|
||||
#endif
|
||||
};
|
||||
|
||||
/* no G_GNUC_UNUSED here, if you don't use an array type, remove it. */
|
||||
static inline void
|
||||
gdk_array(init) (GdkArray *self)
|
||||
{
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
self->start = self->preallocated;
|
||||
self->end = self->start;
|
||||
self->end_allocation = self->start + GDK_ARRAY_PREALLOC;
|
||||
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||
*self->start = *(_T_[1]) {};
|
||||
#endif
|
||||
#else
|
||||
self->start = NULL;
|
||||
self->end = NULL;
|
||||
self->end_allocation = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_array(free_elements) (_T_ *start,
|
||||
_T_ *end)
|
||||
{
|
||||
#ifdef GDK_ARRAY_FREE_FUNC
|
||||
_T_ *e;
|
||||
for (e = start; e < end; e++)
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
GDK_ARRAY_FREE_FUNC (e);
|
||||
#else
|
||||
GDK_ARRAY_FREE_FUNC (*e);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* no G_GNUC_UNUSED here */
|
||||
static inline void
|
||||
gdk_array(clear) (GdkArray *self)
|
||||
{
|
||||
gdk_array(free_elements) (self->start, self->end);
|
||||
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
if (self->start != self->preallocated)
|
||||
#endif
|
||||
g_free (self->start);
|
||||
gdk_array(init) (self);
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline _T_ *
|
||||
gdk_array(get_data) (const GdkArray *self)
|
||||
{
|
||||
return self->start;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline _T_ *
|
||||
gdk_array(index) (const GdkArray *self,
|
||||
gsize pos)
|
||||
{
|
||||
return self->start + pos;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline gsize
|
||||
gdk_array(get_capacity) (const GdkArray *self)
|
||||
{
|
||||
return self->end_allocation - self->start;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline gsize
|
||||
gdk_array(get_size) (const GdkArray *self)
|
||||
{
|
||||
return self->end - self->start;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline gboolean
|
||||
gdk_array(is_empty) (const GdkArray *self)
|
||||
{
|
||||
return self->end == self->start;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
gdk_array(reserve) (GdkArray *self,
|
||||
gsize n)
|
||||
{
|
||||
gsize new_size, size;
|
||||
|
||||
if (n <= gdk_array(get_capacity) (self))
|
||||
return;
|
||||
|
||||
size = gdk_array(get_size) (self);
|
||||
new_size = 1 << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
|
||||
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
if (self->start == self->preallocated)
|
||||
{
|
||||
self->start = g_new (_T_, new_size);
|
||||
memcpy (self->start, self->preallocated, sizeof (_T_) * GDK_ARRAY_REAL_SIZE (size));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||
if (self->start == NULL)
|
||||
{
|
||||
self->start = g_new (_T_, new_size);
|
||||
*self->start = *(_T_[1]) {};
|
||||
}
|
||||
else
|
||||
#endif
|
||||
self->start = g_renew (_T_, self->start, new_size);
|
||||
|
||||
self->end = self->start + size;
|
||||
self->end_allocation = self->start + new_size;
|
||||
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||
self->end_allocation--;
|
||||
#endif
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
gdk_array(splice) (GdkArray *self,
|
||||
gsize pos,
|
||||
gsize removed,
|
||||
_T_ *additions,
|
||||
gsize added)
|
||||
{
|
||||
gsize size;
|
||||
gsize remaining;
|
||||
|
||||
size = gdk_array(get_size) (self);
|
||||
g_assert (pos + removed <= size);
|
||||
remaining = size - pos - removed;
|
||||
|
||||
gdk_array(free_elements) (gdk_array(index) (self, pos),
|
||||
gdk_array(index) (self, pos + removed));
|
||||
|
||||
gdk_array(reserve) (self, size - removed + added);
|
||||
|
||||
if (GDK_ARRAY_REAL_SIZE (remaining) && removed != added)
|
||||
memmove (gdk_array(index) (self, pos + added),
|
||||
gdk_array(index) (self, pos + removed),
|
||||
GDK_ARRAY_REAL_SIZE (remaining) * sizeof (_T_));
|
||||
|
||||
if (added)
|
||||
{
|
||||
if (additions)
|
||||
memcpy (gdk_array(index) (self, pos),
|
||||
additions,
|
||||
added * sizeof (_T_));
|
||||
else
|
||||
memset (gdk_array(index) (self, pos), 0, added * sizeof (_T_));
|
||||
}
|
||||
|
||||
|
||||
/* might overflow, but does the right thing */
|
||||
self->end += added - removed;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
gdk_array(set_size) (GdkArray *self,
|
||||
gsize new_size)
|
||||
{
|
||||
gsize old_size = gdk_array(get_size) (self);
|
||||
if (new_size > old_size)
|
||||
gdk_array(splice) (self, old_size, 0, NULL, new_size - old_size);
|
||||
else
|
||||
gdk_array(splice) (self, new_size, old_size - new_size, NULL, 0);
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
gdk_array(append) (GdkArray *self,
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
_T_ *value)
|
||||
#else
|
||||
_T_ value)
|
||||
#endif
|
||||
{
|
||||
gdk_array(splice) (self,
|
||||
gdk_array(get_size) (self),
|
||||
0,
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
value,
|
||||
#else
|
||||
&value,
|
||||
#endif
|
||||
1);
|
||||
}
|
||||
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
G_GNUC_UNUSED static _T_ *
|
||||
gdk_array(get) (const GdkArray *self,
|
||||
gsize pos)
|
||||
{
|
||||
return gdk_array(index) (self, pos);
|
||||
}
|
||||
#else
|
||||
G_GNUC_UNUSED static _T_
|
||||
gdk_array(get) (const GdkArray *self,
|
||||
gsize pos)
|
||||
{
|
||||
return *gdk_array(index) (self, pos);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GDK_ARRAY_NO_UNDEF
|
||||
|
||||
#undef _T_
|
||||
#undef GdkArray
|
||||
#undef gdk_array_paste_more
|
||||
#undef gdk_array_paste
|
||||
#undef gdk_array
|
||||
#undef GDK_ARRAY_REAL_SIZE
|
||||
|
||||
#undef GDK_ARRAY_BY_VALUE
|
||||
#undef GDK_ARRAY_ELEMENT_TYPE
|
||||
#undef GDK_ARRAY_FREE_FUNC
|
||||
#undef GDK_ARRAY_NAME
|
||||
#undef GDK_ARRAY_NULL_TERMINATED
|
||||
#undef GDK_ARRAY_PREALLOC
|
||||
#undef GDK_ARRAY_TYPE_NAME
|
||||
|
||||
#endif
|
||||
@@ -12,7 +12,6 @@ G_BEGIN_DECLS
|
||||
|
||||
#mesondefine GDK_WINDOWING_X11
|
||||
#mesondefine GDK_WINDOWING_BROADWAY
|
||||
#mesondefine GDK_WINDOWING_MACOS
|
||||
#mesondefine GDK_WINDOWING_WAYLAND
|
||||
#mesondefine GDK_WINDOWING_WIN32
|
||||
|
||||
|
||||
@@ -875,7 +875,7 @@ init (void)
|
||||
|
||||
g_slist_free (formats);
|
||||
|
||||
#if defined(G_OS_UNIX) && !defined(__APPLE__)
|
||||
#ifdef G_OS_UNIX
|
||||
file_transfer_portal_register ();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -907,7 +907,7 @@ init (void)
|
||||
|
||||
g_slist_free (formats);
|
||||
|
||||
#if defined(G_OS_UNIX) && !defined(__APPLE__)
|
||||
#ifdef G_OS_UNIX
|
||||
file_transfer_portal_register ();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -50,10 +50,6 @@
|
||||
#include "broadway/gdkprivate-broadway.h"
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_MACOS
|
||||
#include "macos/gdkmacosdisplay-private.h"
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_WIN32
|
||||
#include "win32/gdkwin32.h"
|
||||
#include "win32/gdkprivate-win32.h"
|
||||
@@ -266,9 +262,6 @@ static GdkBackend gdk_backends[] = {
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
{ "quartz", _gdk_quartz_display_open },
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_MACOS
|
||||
{ "macos", _gdk_macos_display_open },
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_WIN32
|
||||
{ "win32", _gdk_win32_display_open },
|
||||
#endif
|
||||
|
||||
@@ -283,10 +283,6 @@
|
||||
#define GDK_KEY_dead_invertedbreve 0xfe6d
|
||||
#define GDK_KEY_dead_belowcomma 0xfe6e
|
||||
#define GDK_KEY_dead_currency 0xfe6f
|
||||
#define GDK_KEY_dead_lowline 0xfe90
|
||||
#define GDK_KEY_dead_aboveverticalline 0xfe91
|
||||
#define GDK_KEY_dead_belowverticalline 0xfe92
|
||||
#define GDK_KEY_dead_longsolidusoverlay 0xfe93
|
||||
#define GDK_KEY_dead_a 0xfe80
|
||||
#define GDK_KEY_dead_A 0xfe81
|
||||
#define GDK_KEY_dead_e 0xfe82
|
||||
@@ -2292,10 +2288,6 @@
|
||||
#define GDK_KEY_TouchpadOn 0x1008ffb0
|
||||
#define GDK_KEY_TouchpadOff 0x1008ffb1
|
||||
#define GDK_KEY_AudioMicMute 0x1008ffb2
|
||||
#define GDK_KEY_Keyboard 0x1008ffb3
|
||||
#define GDK_KEY_WWAN 0x1008ffb4
|
||||
#define GDK_KEY_RFKill 0x1008ffb5
|
||||
#define GDK_KEY_AudioPreset 0x1008ffb6
|
||||
#define GDK_KEY_Switch_VT_1 0x1008fe01
|
||||
#define GDK_KEY_Switch_VT_2 0x1008fe02
|
||||
#define GDK_KEY_Switch_VT_3 0x1008fe03
|
||||
|
||||
+1
-1
@@ -354,7 +354,7 @@ gdk_rgba_equal (gconstpointer p1,
|
||||
*
|
||||
* Returns a textual specification of @rgba in the form
|
||||
* `rgb(r,g,b)` or
|
||||
* `rgba(r,g,b,a)`,
|
||||
* `rgba(r g,b,a)`,
|
||||
* where “r”, “g”, “b” and “a” represent the red, green,
|
||||
* blue and alpha values respectively. “r”, “g”, and “b” are
|
||||
* represented as integers in the range 0 to 255, and “a”
|
||||
|
||||
@@ -1,718 +0,0 @@
|
||||
/* GdkMacosBaseView.c
|
||||
*
|
||||
* Copyright 2005-2007 Imendio AB
|
||||
* Copyright 2011 Hiroyuki Yamamoto
|
||||
* Copyright 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#import "GdkMacosBaseView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
/* Text Input Client */
|
||||
#define TIC_MARKED_TEXT "tic-marked-text"
|
||||
#define TIC_SELECTED_POS "tic-selected-pos"
|
||||
#define TIC_SELECTED_LEN "tic-selected-len"
|
||||
#define TIC_INSERT_TEXT "tic-insert-text"
|
||||
#define TIC_IN_KEY_DOWN "tic-in-key-down"
|
||||
|
||||
/* GtkIMContext */
|
||||
#define GIC_CURSOR_RECT "gic-cursor-rect"
|
||||
#define GIC_FILTER_KEY "gic-filter-key"
|
||||
#define GIC_FILTER_PASSTHRU 0
|
||||
#define GIC_FILTER_FILTERED 1
|
||||
|
||||
@implementation GdkMacosBaseView
|
||||
|
||||
-(id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
if ((self = [super initWithFrame: frameRect]))
|
||||
{
|
||||
NSRect rect = NSMakeRect (0, 0, 0, 0);
|
||||
NSTrackingAreaOptions options;
|
||||
|
||||
markedRange = NSMakeRange (NSNotFound, 0);
|
||||
selectedRange = NSMakeRange (0, 0);
|
||||
[self setValue: @(YES) forKey: @"postsFrameChangedNotifications"];
|
||||
|
||||
options = (NSTrackingMouseEnteredAndExited |
|
||||
NSTrackingMouseMoved |
|
||||
NSTrackingInVisibleRect |
|
||||
NSTrackingActiveAlways);
|
||||
trackingArea = [[NSTrackingArea alloc] initWithRect:rect
|
||||
options:options
|
||||
owner:(id)self
|
||||
userInfo:nil];
|
||||
[self addTrackingArea:trackingArea];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)setNeedsDisplay:(BOOL)needsDisplay
|
||||
{
|
||||
for (id child in [self subviews])
|
||||
[child setNeedsDisplay:needsDisplay];
|
||||
}
|
||||
|
||||
-(void)setOpaqueRegion:(cairo_region_t *)region
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstMouse
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)mouseDownCanMoveWindow
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstResponder
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("acceptsFirstResponder"));
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)becomeFirstResponder
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("becomeFirstResponder"));
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)resignFirstResponder
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("resignFirstResponder"));
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)setNeedsInvalidateShadow: (BOOL)invalidate
|
||||
{
|
||||
needsInvalidateShadow = invalidate;
|
||||
}
|
||||
|
||||
-(NSTrackingArea *)trackingArea
|
||||
{
|
||||
return trackingArea;
|
||||
}
|
||||
|
||||
-(GdkMacosSurface *)gdkSurface
|
||||
{
|
||||
return [(GdkMacosWindow *)[self window] gdkSurface];
|
||||
}
|
||||
|
||||
-(GdkMacosDisplay *)gdkDisplay
|
||||
{
|
||||
GdkMacosSurface *surface = [self gdkSurface];
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (surface));
|
||||
|
||||
return GDK_MACOS_DISPLAY (display);
|
||||
}
|
||||
|
||||
-(void)keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
/* NOTE: When user press Cmd+A, interpretKeyEvents: will call noop:
|
||||
* method. When user press and hold A to show the accented char window,
|
||||
* it consumed repeating key down events for key 'A' do NOT call
|
||||
* any other method. We use this behavior to determine if this key
|
||||
* down event is filtered by interpretKeyEvents.
|
||||
*/
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_FILTERED));
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("keyDown"));
|
||||
[self interpretKeyEvents: [NSArray arrayWithObject: theEvent]];
|
||||
}
|
||||
|
||||
-(void)flagsChanged: (NSEvent *)theEvent
|
||||
{
|
||||
}
|
||||
|
||||
-(NSUInteger)characterIndexForPoint:(NSPoint)aPoint
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("characterIndexForPoint"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
-(NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange: (NSRangePointer)actualRange
|
||||
{
|
||||
GdkRectangle *rect;
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("firstRectForCharacterRange"));
|
||||
|
||||
if ((rect = g_object_get_data (G_OBJECT ([self gdkSurface]), GIC_CURSOR_RECT)))
|
||||
{
|
||||
GdkMacosDisplay *display = [self gdkDisplay];
|
||||
int ns_x, ns_y;
|
||||
|
||||
_gdk_macos_display_to_display_coords (display,
|
||||
rect->x, rect->y + rect->height,
|
||||
&ns_x, &ns_y);
|
||||
|
||||
return NSMakeRect (ns_x, ns_y, rect->width, rect->height);
|
||||
}
|
||||
|
||||
return NSMakeRect (0, 0, 0, 0);
|
||||
}
|
||||
|
||||
-(NSArray *)validAttributesForMarkedText
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("validAttributesForMarkedText"));
|
||||
return [NSArray arrayWithObjects: NSUnderlineStyleAttributeName, nil];
|
||||
}
|
||||
|
||||
-(NSAttributedString *)attributedSubstringForProposedRange: (NSRange)aRange actualRange: (NSRangePointer)actualRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("attributedSubstringForProposedRange"));
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(BOOL)hasMarkedText
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("hasMarkedText"));
|
||||
return markedRange.location != NSNotFound && markedRange.length != 0;
|
||||
}
|
||||
|
||||
-(NSRange)markedRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("markedRange"));
|
||||
return markedRange;
|
||||
}
|
||||
|
||||
-(NSRange)selectedRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectedRange"));
|
||||
return selectedRange;
|
||||
}
|
||||
|
||||
-(void)unmarkText
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("unmarkText"));
|
||||
|
||||
selectedRange = NSMakeRange (0, 0);
|
||||
markedRange = NSMakeRange (NSNotFound, 0);
|
||||
|
||||
g_object_set_data_full (G_OBJECT ([self gdkSurface]), TIC_MARKED_TEXT, NULL, g_free);
|
||||
}
|
||||
|
||||
-(void)setMarkedText:(id)aString selectedRange: (NSRange)newSelection replacementRange: (NSRange)replacementRange
|
||||
{
|
||||
const char *str;
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("setMarkedText"));
|
||||
|
||||
if (replacementRange.location == NSNotFound)
|
||||
{
|
||||
markedRange = NSMakeRange (newSelection.location, [aString length]);
|
||||
selectedRange = NSMakeRange (newSelection.location, newSelection.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
markedRange = NSMakeRange (replacementRange.location, [aString length]);
|
||||
selectedRange = NSMakeRange (replacementRange.location + newSelection.location, newSelection.length);
|
||||
}
|
||||
|
||||
if ([aString isKindOfClass: [NSAttributedString class]])
|
||||
str = [[aString string] UTF8String];
|
||||
else
|
||||
str = [aString UTF8String];
|
||||
|
||||
g_object_set_data_full (G_OBJECT ([self gdkSurface]), TIC_MARKED_TEXT, g_strdup (str), g_free);
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
TIC_SELECTED_POS,
|
||||
GUINT_TO_POINTER (selectedRange.location));
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
TIC_SELECTED_LEN,
|
||||
GUINT_TO_POINTER (selectedRange.length));
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("setMarkedText: set %s (%p, nsview %p): %s",
|
||||
TIC_MARKED_TEXT, [self gdkSurface], self,
|
||||
str ? str : "(empty)"));
|
||||
|
||||
/* handle text input changes by mouse events */
|
||||
if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT ([self gdkSurface]), TIC_IN_KEY_DOWN)))
|
||||
_gdk_macos_surface_synthesize_null_key ([self gdkSurface]);
|
||||
}
|
||||
|
||||
-(void)doCommandBySelector:(SEL)aSelector
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("doCommandBySelector"));
|
||||
|
||||
if ([self respondsToSelector: aSelector])
|
||||
[self performSelector: aSelector];
|
||||
}
|
||||
|
||||
-(void)insertText:(id)aString replacementRange: (NSRange)replacementRange
|
||||
{
|
||||
const char *str;
|
||||
NSString *string;
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("insertText"));
|
||||
|
||||
if ([self hasMarkedText])
|
||||
[self unmarkText];
|
||||
|
||||
if ([aString isKindOfClass: [NSAttributedString class]])
|
||||
string = [aString string];
|
||||
else
|
||||
string = aString;
|
||||
|
||||
NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet];
|
||||
NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
||||
if ([string rangeOfCharacterFromSet:ctrlChars].length &&
|
||||
[string rangeOfCharacterFromSet:wsnlChars].length == 0)
|
||||
{
|
||||
/* discard invalid text input with Chinese input methods */
|
||||
str = "";
|
||||
[self unmarkText];
|
||||
[[NSTextInputContext currentInputContext] discardMarkedText];
|
||||
}
|
||||
else
|
||||
{
|
||||
str = [string UTF8String];
|
||||
}
|
||||
|
||||
g_object_set_data_full (G_OBJECT ([self gdkSurface]), TIC_INSERT_TEXT, g_strdup (str), g_free);
|
||||
GDK_NOTE (EVENTS, g_message ("insertText: set %s (%p, nsview %p): %s",
|
||||
TIC_INSERT_TEXT, [self gdkSurface], self,
|
||||
str ? str : "(empty)"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_FILTERED));
|
||||
|
||||
/* handle text input changes by mouse events */
|
||||
if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT ([self gdkSurface]), TIC_IN_KEY_DOWN)))
|
||||
_gdk_macos_surface_synthesize_null_key ([self gdkSurface]);
|
||||
}
|
||||
|
||||
-(void)deleteBackward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteBackward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteForward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteForward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteToBeginningOfLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteToBeginningOfLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteToEndOfLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteToEndOfLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteWordBackward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteWordBackward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteWordForward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteWordForward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)insertBacktab:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertBacktab"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)insertNewline:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertNewline"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)insertTab:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertTab"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveBackward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveBackward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveBackwardAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveBackwardAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveDown:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveDown"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveDownAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveDownAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveForward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveForward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveForwardAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveForwardAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveLeft:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveLeft"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveLeftAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveLeftAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveRight:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveRight"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveRightAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveRightAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfDocument:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfDocument"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfDocumentAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfDocumentAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfLineAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfLineAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfDocument:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfDocument"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfDocumentAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfDocumentAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfLineAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfLineAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveUp:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveUp"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveUpAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveUpAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordBackward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordBackward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordBackwardAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordBackwardAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordForward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordForward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordForwardAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordForwardAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordLeft:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordLeft"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordLeftAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordLeftAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordRight:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordRight"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordRightAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordRightAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageDown:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageDown"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageDownAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageDownAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageUp:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageUp"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageUpAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageUpAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)selectAll:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectAll"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)selectLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)selectWord:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectWord"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)noop: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("noop"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,171 +0,0 @@
|
||||
/* GdkMacosCairoSubview.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#import "GdkMacosCairoSubview.h"
|
||||
#import "GdkMacosCairoView.h"
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
@implementation GdkMacosCairoSubview
|
||||
|
||||
-(BOOL)isOpaque
|
||||
{
|
||||
return _isOpaque;
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(GdkSurface *)gdkSurface
|
||||
{
|
||||
return GDK_SURFACE ([(GdkMacosBaseView *)[self superview] gdkSurface]);
|
||||
}
|
||||
|
||||
-(void)drawRect:(NSRect)rect
|
||||
{
|
||||
CGContextRef cgContext;
|
||||
GdkSurface *gdk_surface;
|
||||
cairo_surface_t *dest;
|
||||
const NSRect *rects = NULL;
|
||||
NSView *root_view;
|
||||
NSInteger n_rects = 0;
|
||||
NSRect abs_bounds;
|
||||
cairo_t *cr;
|
||||
CGSize scale;
|
||||
int scale_factor;
|
||||
|
||||
if (self->cairoSurface == NULL)
|
||||
return;
|
||||
|
||||
/* Acquire everything we need to do translations, drawing, etc */
|
||||
gdk_surface = [self gdkSurface];
|
||||
scale_factor = gdk_surface_get_scale_factor (gdk_surface);
|
||||
root_view = [[self window] contentView];
|
||||
cgContext = [[NSGraphicsContext currentContext] CGContext];
|
||||
abs_bounds = [self convertRect:[self bounds] toView:root_view];
|
||||
|
||||
CGContextSaveGState (cgContext);
|
||||
|
||||
/* Translate scaling to remove HiDPI scaling from CGContext as
|
||||
* cairo will be doing that for us already.
|
||||
*/
|
||||
scale = CGSizeMake (1.0, 1.0);
|
||||
scale = CGContextConvertSizeToDeviceSpace (cgContext, scale);
|
||||
CGContextScaleCTM (cgContext, 1.0 / scale.width, 1.0 / scale.height);
|
||||
|
||||
/* Create the cairo surface to draw to the CGContext and translate
|
||||
* coordinates so we can pretend we are in the same coordinate system
|
||||
* as the GDK surface.
|
||||
*/
|
||||
dest = cairo_quartz_surface_create_for_cg_context (cgContext,
|
||||
gdk_surface->width * scale_factor,
|
||||
gdk_surface->height * scale_factor);
|
||||
cairo_surface_set_device_scale (dest, scale_factor, scale_factor);
|
||||
|
||||
/* Create cairo context and translate things into the origin of
|
||||
* the topmost contentView so that we just draw at 0,0 with a
|
||||
* clip region to paint the surface.
|
||||
*/
|
||||
cr = cairo_create (dest);
|
||||
cairo_translate (cr, -abs_bounds.origin.x, -abs_bounds.origin.y);
|
||||
|
||||
/* Clip the cairo context based on the rectangles to be drawn
|
||||
* within the bounding box :rect.
|
||||
*/
|
||||
[self getRectsBeingDrawn:&rects count:&n_rects];
|
||||
for (NSInteger i = 0; i < n_rects; i++)
|
||||
{
|
||||
NSRect area = [self convertRect:rects[i] toView:root_view];
|
||||
cairo_rectangle (cr,
|
||||
area.origin.x, area.origin.y,
|
||||
area.size.width, area.size.height);
|
||||
}
|
||||
cairo_clip (cr);
|
||||
|
||||
/* Now paint the surface (without blending) as we do not need
|
||||
* any compositing here. The transparent regions (like shadows)
|
||||
* are already on non-opaque layers.
|
||||
*/
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_surface (cr, self->cairoSurface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
/* Cleanup state, flush the surface to the backing layer, and
|
||||
* restore GState for future use.
|
||||
*/
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_flush (dest);
|
||||
cairo_surface_destroy (dest);
|
||||
CGContextRestoreGState (cgContext);
|
||||
}
|
||||
|
||||
-(void)setCairoSurface:(cairo_surface_t *)surface
|
||||
withDamage:(cairo_region_t *)region
|
||||
{
|
||||
if (surface != self->cairoSurface)
|
||||
{
|
||||
g_clear_pointer (&self->cairoSurface, cairo_surface_destroy);
|
||||
if (surface != NULL)
|
||||
self->cairoSurface = cairo_surface_reference (surface);
|
||||
}
|
||||
|
||||
if (region != NULL)
|
||||
{
|
||||
NSView *root_view = [[self window] contentView];
|
||||
NSRect abs_bounds = [self convertRect:[self bounds] toView:root_view];
|
||||
guint n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
NSRect nsrect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
nsrect = NSMakeRect (rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
if (NSIntersectsRect (abs_bounds, nsrect))
|
||||
{
|
||||
nsrect.origin.x -= abs_bounds.origin.x;
|
||||
nsrect.origin.y -= abs_bounds.origin.y;
|
||||
[self setNeedsDisplayInRect:nsrect];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (id view in [self subviews])
|
||||
[(GdkMacosCairoSubview *)view setCairoSurface:surface
|
||||
withDamage:region];
|
||||
}
|
||||
|
||||
-(void)setOpaque:(BOOL)opaque
|
||||
{
|
||||
self->_isOpaque = opaque;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,35 +0,0 @@
|
||||
/* GdkMacosCairoSubview.h
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#define GDK_IS_MACOS_CAIRO_SUBVIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosCairoSubview class]])
|
||||
|
||||
@interface GdkMacosCairoSubview : NSView
|
||||
{
|
||||
BOOL _isOpaque;
|
||||
cairo_surface_t *cairoSurface;
|
||||
}
|
||||
|
||||
-(void)setOpaque:(BOOL)opaque;
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)region;
|
||||
|
||||
@end
|
||||
@@ -1,170 +0,0 @@
|
||||
/* GdkMacosCairoView.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#import "GdkMacosCairoView.h"
|
||||
#import "GdkMacosCairoSubview.h"
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
@implementation GdkMacosCairoView
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_clear_pointer (&self->opaque, g_ptr_array_unref);
|
||||
self->transparent = NULL;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(BOOL)isOpaque
|
||||
{
|
||||
if ([self window])
|
||||
return [[self window] isOpaque];
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)cairoRegion
|
||||
{
|
||||
for (id view in [self subviews])
|
||||
[(GdkMacosCairoSubview *)view setCairoSurface:cairoSurface
|
||||
withDamage:cairoRegion];
|
||||
}
|
||||
|
||||
-(void)removeOpaqueChildren
|
||||
{
|
||||
[[self->transparent subviews]
|
||||
makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
|
||||
if (self->opaque->len)
|
||||
g_ptr_array_remove_range (self->opaque, 0, self->opaque->len);
|
||||
}
|
||||
|
||||
-(void)setOpaqueRegion:(cairo_region_t *)region
|
||||
{
|
||||
NSRect abs_bounds;
|
||||
guint n_rects;
|
||||
|
||||
if (region == NULL)
|
||||
return;
|
||||
|
||||
abs_bounds = [self convertRect:[self bounds] toView:nil];
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
/* The common case (at least for opaque windows and CSD) is that we will
|
||||
* have either one or two opaque rectangles. If we detect that the same
|
||||
* number of them are available as the previous, we can just resize the
|
||||
* previous ones to avoid adding/removing views at a fast rate while
|
||||
* resizing.
|
||||
*/
|
||||
if (n_rects == self->opaque->len)
|
||||
{
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
GdkMacosCairoSubview *child;
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
child = g_ptr_array_index (self->opaque, i);
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
[child setFrame:NSMakeRect (rect.x - abs_bounds.origin.x,
|
||||
rect.y - abs_bounds.origin.y,
|
||||
rect.width,
|
||||
rect.height)];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[self removeOpaqueChildren];
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
GdkMacosCairoSubview *child;
|
||||
cairo_rectangle_int_t rect;
|
||||
NSRect nsrect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
nsrect = NSMakeRect (rect.x - abs_bounds.origin.x,
|
||||
rect.y - abs_bounds.origin.y,
|
||||
rect.width,
|
||||
rect.height);
|
||||
|
||||
child = [[GdkMacosCairoSubview alloc] initWithFrame:nsrect];
|
||||
[child setOpaque:YES];
|
||||
[child setWantsLayer:YES];
|
||||
[self->transparent addSubview:child];
|
||||
g_ptr_array_add (self->opaque, child);
|
||||
}
|
||||
}
|
||||
|
||||
-(NSView *)initWithFrame:(NSRect)frame
|
||||
{
|
||||
if ((self = [super initWithFrame:frame]))
|
||||
{
|
||||
/* An array to track all the opaque children placed into
|
||||
* the child self->transparent. This allows us to reuse them
|
||||
* when we receive a new opaque area instead of discarding
|
||||
* them on each draw.
|
||||
*/
|
||||
self->opaque = g_ptr_array_new ();
|
||||
|
||||
/* Setup our primary subview which will render all content that is not
|
||||
* within an opaque region (such as shadows for CSD windows). For opaque
|
||||
* windows, this will all be obscurred by other views, so it doesn't
|
||||
* matter much to have it here.
|
||||
*/
|
||||
self->transparent = [[GdkMacosCairoSubview alloc] initWithFrame:frame];
|
||||
[self addSubview:self->transparent];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)setFrame:(NSRect)rect
|
||||
{
|
||||
[super setFrame:rect];
|
||||
[self->transparent setFrame:NSMakeRect (0, 0, rect.size.width, rect.size.height)];
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstMouse
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)mouseDownCanMoveWindow
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,157 +0,0 @@
|
||||
/* GdkMacosGLLayer.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/* Based on Chromium image_transport_surface_calayer_mac.mm
|
||||
* See the BSD-style license above.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <OpenGL/gl.h>
|
||||
|
||||
#import "GdkMacosGLLayer.h"
|
||||
|
||||
@implementation GdkMacosGLLayer
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
-(id)initWithContext:(NSOpenGLContext *)shared
|
||||
{
|
||||
[super init];
|
||||
_shared = [shared retain];
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
[_shared release];
|
||||
_shared = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)setContentsRect:(NSRect)bounds
|
||||
{
|
||||
_pixelSize = bounds.size;
|
||||
[super setContentsRect:bounds];
|
||||
}
|
||||
|
||||
-(CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
|
||||
{
|
||||
return CGLRetainPixelFormat ([[_shared pixelFormat] CGLPixelFormatObj]);
|
||||
}
|
||||
|
||||
-(CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
|
||||
{
|
||||
CGLContextObj context = NULL;
|
||||
CGLCreateContext (pixelFormat, [_shared CGLContextObj], &context);
|
||||
return context;
|
||||
}
|
||||
|
||||
-(BOOL)canDrawInCGLContext:(CGLContextObj)glContext
|
||||
pixelFormat:(CGLPixelFormatObj)pixelFormat
|
||||
forLayerTime:(CFTimeInterval)timeInterval
|
||||
displayTime:(const CVTimeStamp*)timeStamp
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)drawInCGLContext:(CGLContextObj)glContext
|
||||
pixelFormat:(CGLPixelFormatObj)pixelFormat
|
||||
forLayerTime:(CFTimeInterval)timeInterval
|
||||
displayTime:(const CVTimeStamp*)timeStamp
|
||||
{
|
||||
if (_texture == 0)
|
||||
return;
|
||||
|
||||
glClearColor (1, 0, 1, 1);
|
||||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
GLint viewport[4] = {0, 0, 0, 0};
|
||||
glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
NSSize viewportSize = NSMakeSize (viewport[2], viewport[3]);
|
||||
|
||||
/* Set the coordinate system to be one-to-one with pixels. */
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
glOrtho (0, viewportSize.width, 0, viewportSize.height, -1, 1);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
|
||||
/* Draw a fullscreen quad. */
|
||||
glColor4f (1, 1, 1, 1);
|
||||
glEnable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, _texture);
|
||||
glBegin (GL_QUADS);
|
||||
{
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex2f (0, 0);
|
||||
glTexCoord2f (0, _pixelSize.height);
|
||||
glVertex2f (0, _pixelSize.height);
|
||||
glTexCoord2f (_pixelSize.width, _pixelSize.height);
|
||||
glVertex2f (_pixelSize.width, _pixelSize.height);
|
||||
glTexCoord2f (_pixelSize.width, 0);
|
||||
glVertex2f (_pixelSize.width, 0);
|
||||
}
|
||||
glEnd ();
|
||||
glBindTexture (0, _texture);
|
||||
glDisable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
[super drawInCGLContext:glContext
|
||||
pixelFormat:pixelFormat
|
||||
forLayerTime:timeInterval
|
||||
displayTime:timeStamp];
|
||||
}
|
||||
|
||||
-(void)setTexture:(GLuint)texture
|
||||
{
|
||||
_texture = texture;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
@end
|
||||
@@ -1,732 +0,0 @@
|
||||
/* GdkMacosWindow.m
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#import "GdkMacosBaseView.h"
|
||||
#import "GdkMacosCairoView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacospopupsurface-private.h"
|
||||
#include "gdkmacostoplevelsurface-private.h"
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
|
||||
@implementation GdkMacosWindow
|
||||
|
||||
-(BOOL)windowShouldClose:(id)sender
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkEvent *event;
|
||||
GList *node;
|
||||
|
||||
display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
event = gdk_delete_event_new (GDK_SURFACE (gdk_surface));
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event,
|
||||
_gdk_display_get_next_serial (display));
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)windowWillMiniaturize:(NSNotification *)aNotification
|
||||
{
|
||||
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface))
|
||||
_gdk_macos_toplevel_surface_detach_from_parent (GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface));
|
||||
else if (GDK_IS_MACOS_POPUP_SURFACE (gdk_surface))
|
||||
_gdk_macos_popup_surface_detach_from_parent (GDK_MACOS_POPUP_SURFACE (gdk_surface));
|
||||
}
|
||||
|
||||
-(void)windowDidMiniaturize:(NSNotification *)aNotification
|
||||
{
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), 0, GDK_SURFACE_STATE_MINIMIZED);
|
||||
}
|
||||
|
||||
-(void)windowDidDeminiaturize:(NSNotification *)aNotification
|
||||
{
|
||||
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface))
|
||||
_gdk_macos_toplevel_surface_attach_to_parent (GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface));
|
||||
else if (GDK_IS_MACOS_POPUP_SURFACE (gdk_surface))
|
||||
_gdk_macos_popup_surface_attach_to_parent (GDK_MACOS_POPUP_SURFACE (gdk_surface));
|
||||
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_SURFACE_STATE_MINIMIZED, 0);
|
||||
}
|
||||
|
||||
-(void)windowDidBecomeKey:(NSNotification *)aNotification
|
||||
{
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), 0, GDK_SURFACE_STATE_FOCUSED);
|
||||
_gdk_macos_display_surface_became_key ([self gdkDisplay], gdk_surface);
|
||||
}
|
||||
|
||||
-(void)windowDidResignKey:(NSNotification *)aNotification
|
||||
{
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_SURFACE_STATE_FOCUSED, 0);
|
||||
_gdk_macos_display_surface_resigned_key ([self gdkDisplay], gdk_surface);
|
||||
}
|
||||
|
||||
-(void)windowDidBecomeMain:(NSNotification *)aNotification
|
||||
{
|
||||
if (![self isVisible])
|
||||
{
|
||||
/* Note: This is a hack needed because for unknown reasons, hidden
|
||||
* windows get shown when clicking the dock icon when the application
|
||||
* is not already active.
|
||||
*/
|
||||
[self orderOut:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
_gdk_macos_display_surface_became_main ([self gdkDisplay], gdk_surface);
|
||||
}
|
||||
|
||||
-(void)windowDidResignMain:(NSNotification *)aNotification
|
||||
{
|
||||
_gdk_macos_display_surface_resigned_main ([self gdkDisplay], gdk_surface);
|
||||
}
|
||||
|
||||
/* Used in combination with NSLeftMouseUp in sendEvent to keep track
|
||||
* of when the window is being moved with the mouse.
|
||||
*/
|
||||
-(void)windowWillMove:(NSNotification *)aNotification
|
||||
{
|
||||
inMove = YES;
|
||||
}
|
||||
|
||||
-(void)sendEvent:(NSEvent *)event
|
||||
{
|
||||
NSEventType event_type = [event type];
|
||||
|
||||
switch ((int)event_type)
|
||||
{
|
||||
case NSEventTypeLeftMouseUp: {
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
double time = ((double)[event timestamp]) * 1000.0;
|
||||
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
|
||||
|
||||
inManualMove = NO;
|
||||
inManualResize = NO;
|
||||
inMove = NO;
|
||||
|
||||
/* We need to deliver the event to the proper drag gestures or we
|
||||
* will leave the window in inconsistent state that requires clicking
|
||||
* in the window to cancel the gesture.
|
||||
*
|
||||
* TODO: Can we improve grab breaking to fix this?
|
||||
*/
|
||||
_gdk_macos_display_send_button_event ([self gdkDisplay], event);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NSEventTypeLeftMouseDragged:
|
||||
if ([self trackManualMove] || [self trackManualResize])
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[super sendEvent:event];
|
||||
}
|
||||
|
||||
-(BOOL)isInMove
|
||||
{
|
||||
return inMove;
|
||||
}
|
||||
|
||||
-(void)checkSendEnterNotify
|
||||
{
|
||||
/* When a new window has been created, and the mouse is in the window
|
||||
* area, we will not receive an NSEventTypeMouseEntered event.
|
||||
* Therefore, we synthesize an enter notify event manually.
|
||||
*/
|
||||
if (!initialPositionKnown)
|
||||
{
|
||||
initialPositionKnown = YES;
|
||||
|
||||
if (NSPointInRect ([NSEvent mouseLocation], [self frame]))
|
||||
{
|
||||
GdkMacosBaseView *view = (GdkMacosBaseView *)[self contentView];
|
||||
NSEvent *event;
|
||||
|
||||
event = [NSEvent enterExitEventWithType: NSEventTypeMouseEntered
|
||||
location: [self mouseLocationOutsideOfEventStream]
|
||||
modifierFlags: 0
|
||||
timestamp: [[NSApp currentEvent] timestamp]
|
||||
windowNumber: [self windowNumber]
|
||||
context: NULL
|
||||
eventNumber: 0
|
||||
trackingNumber: (NSInteger)[view trackingArea]
|
||||
userData: nil];
|
||||
|
||||
[NSApp postEvent:event atStart:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)windowDidUnmaximize
|
||||
{
|
||||
NSWindowStyleMask style_mask = [self styleMask];
|
||||
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_SURFACE_STATE_MAXIMIZED, 0);
|
||||
|
||||
/* If we are using CSD, then we transitioned to an opaque
|
||||
* window while we were maximized. Now we need to drop that
|
||||
* as we are leaving maximized state.
|
||||
*/
|
||||
if ((style_mask & NSWindowStyleMaskTitled) == 0 && [self isOpaque])
|
||||
[self setOpaque:NO];
|
||||
}
|
||||
|
||||
-(void)windowDidMove:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (gdk_surface);
|
||||
gboolean maximized = (surface->state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
|
||||
|
||||
/* In case the window is changed when maximized remove the maximized state */
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
|
||||
[self windowDidUnmaximize];
|
||||
|
||||
_gdk_macos_surface_update_position (gdk_surface);
|
||||
_gdk_macos_surface_reposition_children (gdk_surface);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)windowDidResize:(NSNotification *)aNotification
|
||||
{
|
||||
NSRect content_rect;
|
||||
GdkSurface *surface;
|
||||
GdkDisplay *display;
|
||||
GdkEvent *event;
|
||||
gboolean maximized;
|
||||
GList *node;
|
||||
|
||||
surface = GDK_SURFACE (gdk_surface);
|
||||
display = gdk_surface_get_display (surface);
|
||||
|
||||
content_rect = [self contentRectForFrameRect:[self frame]];
|
||||
maximized = (surface->state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
|
||||
|
||||
/* see same in windowDidMove */
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
|
||||
[self windowDidUnmaximize];
|
||||
|
||||
surface->width = content_rect.size.width;
|
||||
surface->height = content_rect.size.height;
|
||||
|
||||
/* Certain resize operations (e.g. going fullscreen), also move the
|
||||
* origin of the window.
|
||||
*/
|
||||
_gdk_macos_surface_update_position (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
[[self contentView] setFrame:NSMakeRect (0, 0, surface->width, surface->height)];
|
||||
|
||||
_gdk_surface_update_size (surface);
|
||||
|
||||
/* Synthesize a configure event */
|
||||
event = gdk_configure_event_new (surface,
|
||||
content_rect.size.width,
|
||||
content_rect.size.height);
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event,
|
||||
_gdk_display_get_next_serial (display));
|
||||
|
||||
_gdk_macos_surface_reposition_children (gdk_surface);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(id)initWithContentRect:(NSRect)contentRect
|
||||
styleMask:(NSWindowStyleMask)styleMask
|
||||
backing:(NSBackingStoreType)backingType
|
||||
defer:(BOOL)flag
|
||||
screen:(NSScreen *)screen
|
||||
{
|
||||
GdkMacosCairoView *view;
|
||||
|
||||
self = [super initWithContentRect:contentRect
|
||||
styleMask:styleMask
|
||||
backing:backingType
|
||||
defer:flag
|
||||
screen:screen];
|
||||
|
||||
[self setAcceptsMouseMovedEvents:YES];
|
||||
[self setDelegate:(id<NSWindowDelegate>)self];
|
||||
[self setReleasedWhenClosed:YES];
|
||||
|
||||
view = [[GdkMacosCairoView alloc] initWithFrame:contentRect];
|
||||
[self setContentView:view];
|
||||
[view release];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL)canBecomeMainWindow
|
||||
{
|
||||
return GDK_IS_TOPLEVEL (gdk_surface);
|
||||
}
|
||||
|
||||
-(BOOL)canBecomeKeyWindow
|
||||
{
|
||||
return GDK_IS_TOPLEVEL (gdk_surface);
|
||||
}
|
||||
|
||||
-(void)showAndMakeKey:(BOOL)makeKey
|
||||
{
|
||||
inShowOrHide = YES;
|
||||
|
||||
if (makeKey && [self canBecomeKeyWindow])
|
||||
[self makeKeyAndOrderFront:nil];
|
||||
else
|
||||
[self orderFront:nil];
|
||||
|
||||
inShowOrHide = NO;
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)hide
|
||||
{
|
||||
inShowOrHide = YES;
|
||||
[self orderOut:nil];
|
||||
inShowOrHide = NO;
|
||||
|
||||
initialPositionKnown = NO;
|
||||
}
|
||||
|
||||
-(BOOL)trackManualMove
|
||||
{
|
||||
NSRect windowFrame;
|
||||
NSPoint currentLocation;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle geometry;
|
||||
GdkRectangle workarea;
|
||||
int shadow_top = 0;
|
||||
int shadow_left = 0;
|
||||
int shadow_right = 0;
|
||||
int shadow_bottom = 0;
|
||||
GdkRectangle window_gdk;
|
||||
GdkPoint pointer_position;
|
||||
GdkPoint new_origin;
|
||||
|
||||
if (!inManualMove)
|
||||
return NO;
|
||||
|
||||
/* Get our shadow so we can adjust the window position sans-shadow */
|
||||
_gdk_macos_surface_get_shadow (gdk_surface,
|
||||
&shadow_top,
|
||||
&shadow_right,
|
||||
&shadow_bottom,
|
||||
&shadow_left);
|
||||
|
||||
windowFrame = [self frame];
|
||||
currentLocation = [NSEvent mouseLocation];
|
||||
|
||||
/* Update the snapping geometry to match the current monitor */
|
||||
monitor = _gdk_macos_display_get_monitor_at_display_coords ([self gdkDisplay],
|
||||
currentLocation.x,
|
||||
currentLocation.y);
|
||||
gdk_monitor_get_geometry (monitor, &geometry);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
_edge_snapping_set_monitor (&self->snapping, &geometry, &workarea);
|
||||
|
||||
/* Convert origins to GDK coordinates */
|
||||
_gdk_macos_display_from_display_coords ([self gdkDisplay],
|
||||
currentLocation.x,
|
||||
currentLocation.y,
|
||||
&pointer_position.x,
|
||||
&pointer_position.y);
|
||||
_gdk_macos_display_from_display_coords ([self gdkDisplay],
|
||||
windowFrame.origin.x,
|
||||
windowFrame.origin.y + windowFrame.size.height,
|
||||
&window_gdk.x,
|
||||
&window_gdk.y);
|
||||
window_gdk.width = windowFrame.size.width;
|
||||
window_gdk.height = windowFrame.size.height;
|
||||
|
||||
/* Subtract our shadowin from the window */
|
||||
window_gdk.x += shadow_left;
|
||||
window_gdk.y += shadow_top;
|
||||
window_gdk.width = window_gdk.width - shadow_left - shadow_right;
|
||||
window_gdk.height = window_gdk.height - shadow_top - shadow_bottom;
|
||||
|
||||
/* Now place things on the monitor */
|
||||
_edge_snapping_motion (&self->snapping, &pointer_position, &window_gdk);
|
||||
|
||||
/* And add our shadow back to the frame */
|
||||
window_gdk.x -= shadow_left;
|
||||
window_gdk.y -= shadow_top;
|
||||
window_gdk.width += shadow_left + shadow_right;
|
||||
window_gdk.height += shadow_top + shadow_bottom;
|
||||
|
||||
/* Convert to quartz coordiantes */
|
||||
_gdk_macos_display_to_display_coords ([self gdkDisplay],
|
||||
window_gdk.x,
|
||||
window_gdk.y + window_gdk.height,
|
||||
&new_origin.x, &new_origin.y);
|
||||
windowFrame.origin.x = new_origin.x;
|
||||
windowFrame.origin.y = new_origin.y;
|
||||
|
||||
/* And now apply the frame to the window */
|
||||
[self setFrameOrigin:NSMakePoint(new_origin.x, new_origin.y)];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* Used by gdkmacosdisplay-translate.c to decide if our sendEvent() handler
|
||||
* above will see the event or if it will be subjected to standard processing
|
||||
* by GDK.
|
||||
*/
|
||||
-(BOOL)isInManualResizeOrMove
|
||||
{
|
||||
return inManualResize || inManualMove;
|
||||
}
|
||||
|
||||
-(void)beginManualMove
|
||||
{
|
||||
NSPoint initialMoveLocation;
|
||||
GdkPoint point;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle geometry;
|
||||
GdkRectangle area;
|
||||
GdkRectangle workarea;
|
||||
|
||||
if (inMove || inManualMove || inManualResize)
|
||||
return;
|
||||
|
||||
inManualMove = YES;
|
||||
|
||||
monitor = _gdk_macos_surface_get_best_monitor ([self gdkSurface]);
|
||||
gdk_monitor_get_geometry (monitor, &geometry);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
initialMoveLocation = [NSEvent mouseLocation];
|
||||
|
||||
_gdk_macos_display_from_display_coords ([self gdkDisplay],
|
||||
initialMoveLocation.x,
|
||||
initialMoveLocation.y,
|
||||
&point.x,
|
||||
&point.y);
|
||||
|
||||
area.x = gdk_surface->root_x;
|
||||
area.y = gdk_surface->root_y;
|
||||
area.width = GDK_SURFACE (gdk_surface)->width;
|
||||
area.height = GDK_SURFACE (gdk_surface)->height;
|
||||
|
||||
_edge_snapping_init (&self->snapping,
|
||||
&geometry,
|
||||
&workarea,
|
||||
&point,
|
||||
&area);
|
||||
}
|
||||
|
||||
-(BOOL)trackManualResize
|
||||
{
|
||||
NSPoint mouse_location;
|
||||
NSRect new_frame;
|
||||
float mdx, mdy, dw, dh, dx, dy;
|
||||
NSSize min_size;
|
||||
|
||||
if (!inManualResize || inTrackManualResize)
|
||||
return NO;
|
||||
|
||||
inTrackManualResize = YES;
|
||||
|
||||
mouse_location = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
mdx = initialResizeLocation.x - mouse_location.x;
|
||||
mdy = initialResizeLocation.y - mouse_location.y;
|
||||
|
||||
/* Set how a mouse location delta translates to changes in width,
|
||||
* height and position.
|
||||
*/
|
||||
dw = dh = dx = dy = 0.0;
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_EAST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_EAST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_EAST)
|
||||
{
|
||||
dw = -1.0;
|
||||
}
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_NORTH ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_EAST)
|
||||
{
|
||||
dh = -1.0;
|
||||
}
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_SOUTH ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_EAST)
|
||||
{
|
||||
dh = 1.0;
|
||||
dy = -1.0;
|
||||
}
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_WEST)
|
||||
{
|
||||
dw = 1.0;
|
||||
dx = -1.0;
|
||||
}
|
||||
|
||||
/* Apply changes to the frame captured when we started resizing */
|
||||
new_frame = initialResizeFrame;
|
||||
new_frame.origin.x += mdx * dx;
|
||||
new_frame.origin.y += mdy * dy;
|
||||
new_frame.size.width += mdx * dw;
|
||||
new_frame.size.height += mdy * dh;
|
||||
|
||||
/* In case the resulting window would be too small reduce the
|
||||
* change to both size and position.
|
||||
*/
|
||||
min_size = [self contentMinSize];
|
||||
|
||||
if (new_frame.size.width < min_size.width)
|
||||
{
|
||||
if (dx)
|
||||
new_frame.origin.x -= min_size.width - new_frame.size.width;
|
||||
new_frame.size.width = min_size.width;
|
||||
}
|
||||
|
||||
if (new_frame.size.height < min_size.height)
|
||||
{
|
||||
if (dy)
|
||||
new_frame.origin.y -= min_size.height - new_frame.size.height;
|
||||
new_frame.size.height = min_size.height;
|
||||
}
|
||||
|
||||
/* We could also apply aspect ratio:
|
||||
new_frame.size.height = new_frame.size.width / [self aspectRatio].width * [self aspectRatio].height;
|
||||
*/
|
||||
|
||||
[self setFrame:new_frame display:YES];
|
||||
|
||||
/* Let the resizing be handled by GTK+. */
|
||||
if (g_main_context_pending (NULL))
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
|
||||
inTrackManualResize = NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)beginManualResize:(GdkSurfaceEdge)edge
|
||||
{
|
||||
if (inMove || inManualMove || inManualResize)
|
||||
return;
|
||||
|
||||
inManualResize = YES;
|
||||
resizeEdge = edge;
|
||||
|
||||
initialResizeFrame = [self frame];
|
||||
initialResizeLocation = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
}
|
||||
|
||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
-(void)draggingEnded:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
}
|
||||
|
||||
-(void)draggingExited:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
}
|
||||
|
||||
-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)wantsPeriodicDraggingUpdates
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
}
|
||||
|
||||
-(void)setStyleMask:(NSWindowStyleMask)styleMask
|
||||
{
|
||||
gboolean was_fullscreen;
|
||||
gboolean is_fullscreen;
|
||||
gboolean was_opaque;
|
||||
gboolean is_opaque;
|
||||
|
||||
was_fullscreen = (([self styleMask] & NSWindowStyleMaskFullScreen) != 0);
|
||||
was_opaque = (([self styleMask] & NSWindowStyleMaskTitled) != 0);
|
||||
|
||||
[super setStyleMask:styleMask];
|
||||
|
||||
is_fullscreen = (([self styleMask] & NSWindowStyleMaskFullScreen) != 0);
|
||||
is_opaque = (([self styleMask] & NSWindowStyleMaskTitled) != 0);
|
||||
|
||||
if (was_fullscreen != is_fullscreen)
|
||||
_gdk_macos_surface_update_fullscreen_state (gdk_surface);
|
||||
|
||||
if (was_opaque != is_opaque)
|
||||
{
|
||||
[self setOpaque:is_opaque];
|
||||
|
||||
if (!is_opaque)
|
||||
[self setBackgroundColor:[NSColor clearColor]];
|
||||
}
|
||||
}
|
||||
|
||||
-(NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
|
||||
{
|
||||
GdkMacosSurface *surface = gdk_surface;
|
||||
NSRect rect;
|
||||
gint shadow_top;
|
||||
|
||||
/* Allow the window to move up "shadow_top" more than normally allowed
|
||||
* by the default impl. This makes it possible to move windows with
|
||||
* client side shadow right up to the screen's menu bar. */
|
||||
_gdk_macos_surface_get_shadow (surface, &shadow_top, NULL, NULL, NULL);
|
||||
rect = [super constrainFrameRect:frameRect toScreen:screen];
|
||||
if (frameRect.origin.y > rect.origin.y)
|
||||
rect.origin.y = MIN (frameRect.origin.y, rect.origin.y + shadow_top);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
-(NSRect)windowWillUseStandardFrame:(NSWindow *)nsWindow
|
||||
defaultFrame:(NSRect)newFrame
|
||||
{
|
||||
NSRect screenFrame = [[self screen] visibleFrame];
|
||||
GdkMacosSurface *surface = gdk_surface;
|
||||
gboolean maximized = GDK_SURFACE (surface)->state & GDK_SURFACE_STATE_MAXIMIZED;
|
||||
|
||||
if (!maximized)
|
||||
return screenFrame;
|
||||
else
|
||||
return lastUnmaximizedFrame;
|
||||
}
|
||||
|
||||
-(BOOL)windowShouldZoom:(NSWindow *)nsWindow
|
||||
toFrame:(NSRect)newFrame
|
||||
{
|
||||
GdkMacosSurface *surface = gdk_surface;
|
||||
GdkSurfaceState state = GDK_SURFACE (surface)->state;
|
||||
|
||||
if (state & GDK_SURFACE_STATE_MAXIMIZED)
|
||||
{
|
||||
lastMaximizedFrame = newFrame;
|
||||
[self windowDidUnmaximize];
|
||||
}
|
||||
else
|
||||
{
|
||||
lastUnmaximizedFrame = [nsWindow frame];
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), 0, GDK_SURFACE_STATE_MAXIMIZED);
|
||||
}
|
||||
|
||||
inMaximizeTransition = YES;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)windowDidEndLiveResize:(NSNotification *)aNotification
|
||||
{
|
||||
gboolean maximized = GDK_SURFACE (gdk_surface)->state & GDK_SURFACE_STATE_MAXIMIZED;
|
||||
|
||||
inMaximizeTransition = NO;
|
||||
|
||||
/* Even if this is CSD, we want to be opaque while maximized
|
||||
* to speed up compositing by allowing the display server to
|
||||
* avoid costly blends.
|
||||
*/
|
||||
if (maximized)
|
||||
[self setOpaque:YES];
|
||||
}
|
||||
|
||||
-(NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
|
||||
{
|
||||
return [[window screen] frame].size;
|
||||
}
|
||||
|
||||
-(void)windowWillEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
lastUnfullscreenFrame = [self frame];
|
||||
}
|
||||
|
||||
-(void)windowWillExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
[self setFrame:lastUnfullscreenFrame display:YES];
|
||||
}
|
||||
|
||||
-(void)windowDidExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
}
|
||||
|
||||
-(void)windowDidChangeScreen:(NSNotification *)aNotification
|
||||
{
|
||||
_gdk_macos_surface_monitor_changed (gdk_surface);
|
||||
}
|
||||
|
||||
-(void)setGdkSurface:(GdkMacosSurface *)surface
|
||||
{
|
||||
self->gdk_surface = surface;
|
||||
}
|
||||
|
||||
-(void)setDecorated:(BOOL)decorated
|
||||
{
|
||||
NSWindowStyleMask style_mask = [self styleMask];
|
||||
|
||||
[self setHasShadow:decorated];
|
||||
|
||||
if (decorated)
|
||||
style_mask |= NSWindowStyleMaskTitled;
|
||||
else
|
||||
style_mask &= ~NSWindowStyleMaskTitled;
|
||||
|
||||
[self setStyleMask:style_mask];
|
||||
}
|
||||
|
||||
-(GdkMacosSurface *)gdkSurface
|
||||
{
|
||||
return self->gdk_surface;
|
||||
}
|
||||
|
||||
-(GdkMacosDisplay *)gdkDisplay
|
||||
{
|
||||
return GDK_MACOS_DISPLAY (GDK_SURFACE (self->gdk_surface)->display);
|
||||
}
|
||||
|
||||
-(BOOL)movableByWindowBackground
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,70 +0,0 @@
|
||||
/* GdkMacosWindow.h
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacossurface.h"
|
||||
#include "edgesnapping.h"
|
||||
|
||||
#define GDK_IS_MACOS_WINDOW(obj) ([obj isKindOfClass:[GdkMacosWindow class]])
|
||||
|
||||
@interface GdkMacosWindow : NSWindow {
|
||||
GdkMacosSurface *gdk_surface;
|
||||
|
||||
BOOL inMove;
|
||||
BOOL inShowOrHide;
|
||||
BOOL initialPositionKnown;
|
||||
|
||||
/* Manually triggered move/resize (not by the window manager) */
|
||||
BOOL inManualMove;
|
||||
BOOL inManualResize;
|
||||
BOOL inTrackManualResize;
|
||||
NSPoint initialResizeLocation;
|
||||
NSRect initialResizeFrame;
|
||||
GdkSurfaceEdge resizeEdge;
|
||||
|
||||
EdgeSnapping snapping;
|
||||
|
||||
NSRect lastUnmaximizedFrame;
|
||||
NSRect lastMaximizedFrame;
|
||||
NSRect lastUnfullscreenFrame;
|
||||
BOOL inMaximizeTransition;
|
||||
}
|
||||
|
||||
-(void)beginManualMove;
|
||||
-(void)beginManualResize:(GdkSurfaceEdge)edge;
|
||||
-(void)hide;
|
||||
-(BOOL)isInManualResizeOrMove;
|
||||
-(BOOL)isInMove;
|
||||
-(GdkMacosDisplay *)gdkDisplay;
|
||||
-(GdkMacosSurface *)gdkSurface;
|
||||
-(void)setGdkSurface:(GdkMacosSurface *)surface;
|
||||
-(void)setStyleMask:(NSWindowStyleMask)styleMask;
|
||||
-(void)showAndMakeKey:(BOOL)makeKey;
|
||||
-(BOOL)trackManualMove;
|
||||
-(BOOL)trackManualResize;
|
||||
-(void)setDecorated:(BOOL)decorated;
|
||||
|
||||
@end
|
||||
@@ -1,229 +0,0 @@
|
||||
/* edgesnapping.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkrectangle.h"
|
||||
#include "edgesnapping.h"
|
||||
|
||||
#define LEAVE_THRESHOLD 3.0
|
||||
#define ENTER_THRESHOLD 2.0
|
||||
|
||||
#define X1(r) ((r)->x)
|
||||
#define X2(r) ((r)->x + (r)->width)
|
||||
#define Y1(r) ((r)->y)
|
||||
#define Y2(r) ((r)->y + (r)->height)
|
||||
|
||||
void
|
||||
_edge_snapping_init (EdgeSnapping *self,
|
||||
const GdkRectangle *geometry,
|
||||
const GdkRectangle *workarea,
|
||||
const GdkPoint *pointer_position,
|
||||
const GdkRectangle *window)
|
||||
{
|
||||
g_assert (self != NULL);
|
||||
g_assert (geometry != NULL);
|
||||
g_assert (workarea != NULL);
|
||||
g_assert (pointer_position != NULL);
|
||||
|
||||
self->geometry = *geometry;
|
||||
self->workarea = *workarea;
|
||||
self->last_pointer_position = *pointer_position;
|
||||
self->pointer_offset_in_window.x = pointer_position->x - window->x;
|
||||
self->pointer_offset_in_window.y = pointer_position->y - window->y;
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_left (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
if (change < 0)
|
||||
{
|
||||
if (X1 (window) < X1 (geometry) &&
|
||||
X1 (window) > X1 (geometry) - LEAVE_THRESHOLD &&
|
||||
ABS (change) < LEAVE_THRESHOLD)
|
||||
window->x = geometry->x;
|
||||
}
|
||||
|
||||
/* We don't constrain when returning from left edge */
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_right (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
if (change > 0)
|
||||
{
|
||||
if (X2 (window) > X2 (geometry) &&
|
||||
X2 (window) < X2 (geometry) + LEAVE_THRESHOLD &&
|
||||
ABS (change) < LEAVE_THRESHOLD)
|
||||
window->x = X2 (geometry) - window->width;
|
||||
}
|
||||
|
||||
/* We don't constrain when returning from right edge */
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_top (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
if (change < 0)
|
||||
{
|
||||
if (Y1 (window) < Y1 (geometry))
|
||||
window->y = geometry->y;
|
||||
}
|
||||
|
||||
/* We don't constrain when returning from top edge */
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_bottom (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
if (change > 0)
|
||||
{
|
||||
if (Y2 (window) > Y2 (geometry) &&
|
||||
Y2 (window) < Y2 (geometry) + LEAVE_THRESHOLD &&
|
||||
ABS (change) < LEAVE_THRESHOLD)
|
||||
window->y = Y2 (geometry) - window->height;
|
||||
}
|
||||
else if (change < 0)
|
||||
{
|
||||
if (Y2 (window) < Y2 (geometry) &&
|
||||
Y2 (window) > Y2 (geometry) - ENTER_THRESHOLD &&
|
||||
ABS (change) < ENTER_THRESHOLD)
|
||||
window->y = Y2 (geometry) - window->height;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_horizontal (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
g_assert (self != NULL);
|
||||
g_assert (geometry != NULL);
|
||||
g_assert (window != NULL);
|
||||
g_assert (change != 0);
|
||||
|
||||
if (ABS (X1 (geometry) - X1 (window)) < ABS (X2 (geometry)) - ABS (X2 (window)))
|
||||
edge_snapping_constrain_left (self, change, geometry, window);
|
||||
else
|
||||
edge_snapping_constrain_right (self, change, geometry, window);
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_vertical (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window,
|
||||
gboolean bottom_only)
|
||||
{
|
||||
g_assert (self != NULL);
|
||||
g_assert (geometry != NULL);
|
||||
g_assert (window != NULL);
|
||||
g_assert (change != 0);
|
||||
|
||||
if (!bottom_only &&
|
||||
ABS (Y1 (geometry) - Y1 (window)) < ABS (Y2 (geometry)) - ABS (Y2 (window)))
|
||||
edge_snapping_constrain_top (self, change, geometry, window);
|
||||
else
|
||||
edge_snapping_constrain_bottom (self, change, geometry, window);
|
||||
}
|
||||
|
||||
void
|
||||
_edge_snapping_motion (EdgeSnapping *self,
|
||||
const GdkPoint *pointer_position,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
GdkRectangle new_window;
|
||||
GdkRectangle overlap;
|
||||
GdkPoint change;
|
||||
|
||||
g_assert (self != NULL);
|
||||
g_assert (pointer_position != NULL);
|
||||
|
||||
change.x = pointer_position->x - self->last_pointer_position.x;
|
||||
change.y = pointer_position->y - self->last_pointer_position.y;
|
||||
|
||||
self->last_pointer_position = *pointer_position;
|
||||
|
||||
window->x += change.x;
|
||||
window->y += change.y;
|
||||
|
||||
new_window = *window;
|
||||
|
||||
/* First constrain horizontal */
|
||||
if (change.x)
|
||||
{
|
||||
edge_snapping_constrain_horizontal (self, change.x, &self->workarea, &new_window);
|
||||
if (gdk_rectangle_equal (&new_window, window))
|
||||
edge_snapping_constrain_horizontal (self, change.x, &self->geometry, &new_window);
|
||||
}
|
||||
|
||||
/* Now constrain veritcally */
|
||||
if (change.y)
|
||||
{
|
||||
edge_snapping_constrain_vertical (self, change.y, &self->workarea, &new_window, FALSE);
|
||||
if (new_window.y == window->y)
|
||||
edge_snapping_constrain_vertical (self, change.y, &self->geometry, &new_window, TRUE);
|
||||
}
|
||||
|
||||
/* If the window is not placed in the monitor at all, then we need to
|
||||
* just move the window onto the new screen using the original offset
|
||||
* of the pointer within the window.
|
||||
*/
|
||||
if (!gdk_rectangle_intersect (&self->geometry, &new_window, &overlap))
|
||||
{
|
||||
new_window.x = pointer_position->x - self->pointer_offset_in_window.x;
|
||||
new_window.y = pointer_position->y - self->pointer_offset_in_window.y;
|
||||
}
|
||||
|
||||
/* And finally make sure we aren't underneath the top bar of the
|
||||
* particular monitor.
|
||||
*/
|
||||
if (Y1 (&new_window) < Y1 (&self->workarea))
|
||||
new_window.y = self->workarea.y;
|
||||
|
||||
*window = new_window;
|
||||
}
|
||||
|
||||
void
|
||||
_edge_snapping_set_monitor (EdgeSnapping *self,
|
||||
const GdkRectangle *geometry,
|
||||
const GdkRectangle *workarea)
|
||||
{
|
||||
g_assert (self != NULL);
|
||||
g_assert (geometry != NULL);
|
||||
g_assert (workarea != NULL);
|
||||
|
||||
self->geometry = *geometry;
|
||||
self->workarea = *workarea;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/* edgesnapping.h
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __EDGE_SNAPPING_H__
|
||||
#define __EDGE_SNAPPING_H__
|
||||
|
||||
#include "gdktypes.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkRectangle geometry;
|
||||
GdkRectangle workarea;
|
||||
GdkPoint last_pointer_position;
|
||||
GdkPoint pointer_offset_in_window;
|
||||
} EdgeSnapping;
|
||||
|
||||
void _edge_snapping_init (EdgeSnapping *self,
|
||||
const GdkRectangle *geometry,
|
||||
const GdkRectangle *workarea,
|
||||
const GdkPoint *pointer_position,
|
||||
const GdkRectangle *window);
|
||||
void _edge_snapping_motion (EdgeSnapping *self,
|
||||
const GdkPoint *pointer_position,
|
||||
GdkRectangle *window);
|
||||
void _edge_snapping_set_monitor (EdgeSnapping *self,
|
||||
const GdkRectangle *geometry,
|
||||
const GdkRectangle *workarea);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EDGE_SNAPPING_H__ */
|
||||
@@ -1,254 +0,0 @@
|
||||
/* gdkdisplaylinksource.c
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Christian Hergert <christian@hergert.me>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
#include "gdkdisplaylinksource.h"
|
||||
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
|
||||
static gint64 host_to_frame_clock_time (gint64 host_time);
|
||||
|
||||
static gboolean
|
||||
gdk_display_link_source_prepare (GSource *source,
|
||||
gint *timeout_)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
gint64 now;
|
||||
|
||||
now = g_source_get_time (source);
|
||||
|
||||
if (now < impl->presentation_time)
|
||||
*timeout_ = (impl->presentation_time - now) / 1000L;
|
||||
else
|
||||
*timeout_ = -1;
|
||||
|
||||
return impl->needs_dispatch;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_display_link_source_check (GSource *source)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
return impl->needs_dispatch;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_display_link_source_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
gboolean ret = G_SOURCE_CONTINUE;
|
||||
|
||||
impl->needs_dispatch = FALSE;
|
||||
|
||||
if (callback != NULL)
|
||||
ret = callback (user_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_link_source_finalize (GSource *source)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
|
||||
CVDisplayLinkStop (impl->display_link);
|
||||
CVDisplayLinkRelease (impl->display_link);
|
||||
}
|
||||
|
||||
static GSourceFuncs gdk_display_link_source_funcs = {
|
||||
gdk_display_link_source_prepare,
|
||||
gdk_display_link_source_check,
|
||||
gdk_display_link_source_dispatch,
|
||||
gdk_display_link_source_finalize
|
||||
};
|
||||
|
||||
void
|
||||
gdk_display_link_source_pause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
CVDisplayLinkStop (source->display_link);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_link_source_unpause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
CVDisplayLinkStart (source->display_link);
|
||||
}
|
||||
|
||||
static CVReturn
|
||||
gdk_display_link_source_frame_cb (CVDisplayLinkRef display_link,
|
||||
const CVTimeStamp *inNow,
|
||||
const CVTimeStamp *inOutputTime,
|
||||
CVOptionFlags flagsIn,
|
||||
CVOptionFlags *flagsOut,
|
||||
void *user_data)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = user_data;
|
||||
gint64 presentation_time;
|
||||
gboolean needs_wakeup;
|
||||
|
||||
needs_wakeup = !g_atomic_int_get (&impl->needs_dispatch);
|
||||
|
||||
presentation_time = host_to_frame_clock_time (inOutputTime->hostTime);
|
||||
|
||||
impl->presentation_time = presentation_time;
|
||||
impl->needs_dispatch = TRUE;
|
||||
|
||||
if (needs_wakeup)
|
||||
{
|
||||
NSEvent *event;
|
||||
|
||||
/* Post a message so we'll break out of the message loop.
|
||||
*
|
||||
* We don't use g_main_context_wakeup() here because that
|
||||
* would result in sending a message to the pipe(2) fd in
|
||||
* the select thread which would then send this message as
|
||||
* well. Lots of extra work.
|
||||
*/
|
||||
event = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
|
||||
location: NSZeroPoint
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: 0
|
||||
context: nil
|
||||
subtype: GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP
|
||||
data1: 0
|
||||
data2: 0];
|
||||
|
||||
[NSApp postEvent:event atStart:YES];
|
||||
}
|
||||
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_link_source_new:
|
||||
*
|
||||
* Creates a new #GSource that will activate the dispatch function upon
|
||||
* notification from a CVDisplayLink that a new frame should be drawn.
|
||||
*
|
||||
* Effort is made to keep the transition from the high-priority
|
||||
* CVDisplayLink thread into this GSource lightweight. However, this is
|
||||
* somewhat non-ideal since the best case would be to do the drawing
|
||||
* from the high-priority thread.
|
||||
*
|
||||
* Returns: (transfer full): A newly created #GSource.
|
||||
*/
|
||||
GSource *
|
||||
gdk_display_link_source_new (void)
|
||||
{
|
||||
GdkDisplayLinkSource *impl;
|
||||
GSource *source;
|
||||
CVReturn ret;
|
||||
double period;
|
||||
|
||||
source = g_source_new (&gdk_display_link_source_funcs, sizeof *impl);
|
||||
impl = (GdkDisplayLinkSource *)source;
|
||||
|
||||
/*
|
||||
* Create our link based on currently connected displays.
|
||||
* If there are multiple displays, this will be something that tries
|
||||
* to work for all of them. In the future, we may want to explore multiple
|
||||
* links based on the connected displays.
|
||||
*/
|
||||
ret = CVDisplayLinkCreateWithActiveCGDisplays (&impl->display_link);
|
||||
if (ret != kCVReturnSuccess)
|
||||
{
|
||||
g_warning ("Failed to initialize CVDisplayLink!");
|
||||
return source;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine our nominal period between frames.
|
||||
*/
|
||||
period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
|
||||
if (period == 0.0)
|
||||
period = 1.0 / 60.0;
|
||||
impl->refresh_interval = period * 1000000L;
|
||||
impl->refresh_rate = 1.0 / period * 1000L;
|
||||
|
||||
/*
|
||||
* Wire up our callback to be executed within the high-priority thread.
|
||||
*/
|
||||
CVDisplayLinkSetOutputCallback (impl->display_link,
|
||||
gdk_display_link_source_frame_cb,
|
||||
source);
|
||||
|
||||
g_source_set_name (source, "[gdk] quartz frame clock");
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
static gint64
|
||||
host_to_frame_clock_time (gint64 host_time)
|
||||
{
|
||||
static mach_timebase_info_data_t timebase_info;
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
*
|
||||
* This code is taken from GLib to match g_get_monotonic_time().
|
||||
*/
|
||||
if (G_UNLIKELY (timebase_info.denom == 0))
|
||||
{
|
||||
/* This is a fraction that we must use to scale
|
||||
* mach_absolute_time() by in order to reach nanoseconds.
|
||||
*
|
||||
* We've only ever observed this to be 1/1, but maybe it could be
|
||||
* 1000/1 if mach time is microseconds already, or 1/1000 if
|
||||
* picoseconds. Try to deal nicely with that.
|
||||
*/
|
||||
mach_timebase_info (&timebase_info);
|
||||
|
||||
/* We actually want microseconds... */
|
||||
if (timebase_info.numer % 1000 == 0)
|
||||
timebase_info.numer /= 1000;
|
||||
else
|
||||
timebase_info.denom *= 1000;
|
||||
|
||||
/* We want to make the numer 1 to avoid having to multiply... */
|
||||
if (timebase_info.denom % timebase_info.numer == 0)
|
||||
{
|
||||
timebase_info.denom /= timebase_info.numer;
|
||||
timebase_info.numer = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We could just multiply by timebase_info.numer below, but why
|
||||
* bother for a case that may never actually exist...
|
||||
*
|
||||
* Plus -- performing the multiplication would risk integer
|
||||
* overflow. If we ever actually end up in this situation, we
|
||||
* should more carefully evaluate the correct course of action.
|
||||
*/
|
||||
mach_timebase_info (&timebase_info); /* Get a fresh copy for a better message */
|
||||
g_error ("Got weird mach timebase info of %d/%d. Please file a bug against GLib.",
|
||||
timebase_info.numer, timebase_info.denom);
|
||||
}
|
||||
}
|
||||
|
||||
return host_time / timebase_info.denom;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/* gdkdisplaylinksource.h
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Christian Hergert <christian@hergert.me>
|
||||
*/
|
||||
|
||||
#ifndef GDK_DISPLAY_LINK_SOURCE_H
|
||||
#define GDK_DISPLAY_LINK_SOURCE_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GSource source;
|
||||
|
||||
CVDisplayLinkRef display_link;
|
||||
gint64 refresh_interval;
|
||||
guint refresh_rate;
|
||||
|
||||
volatile gint64 presentation_time;
|
||||
volatile guint needs_dispatch;
|
||||
} GdkDisplayLinkSource;
|
||||
|
||||
GSource *gdk_display_link_source_new (void);
|
||||
void gdk_display_link_source_pause (GdkDisplayLinkSource *source);
|
||||
void gdk_display_link_source_unpause (GdkDisplayLinkSource *source);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GDK_DISPLAY_LINK_SOURCE_H */
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_H__
|
||||
#define __GDK_MACOS_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkmacosdevice.h"
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacosglcontext.h"
|
||||
#include "gdkmacoskeymap.h"
|
||||
#include "gdkmacosmonitor.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
#endif /* __GDK_MACOS_H__ */
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_CAIRO_CONTEXT_PRIVATE_H__
|
||||
#define __GDK_MACOS_CAIRO_CONTEXT_PRIVATE_H__
|
||||
|
||||
#include "gdkcairocontextprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkMacosCairoContext GdkMacosCairoContext;
|
||||
typedef struct _GdkMacosCairoContextClass GdkMacosCairoContextClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_CAIRO_CONTEXT (_gdk_macos_cairo_context_get_type())
|
||||
#define GDK_MACOS_CAIRO_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_CAIRO_CONTEXT, GdkMacosCairoContext))
|
||||
#define GDK_IS_MACOS_CAIRO_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_CAIRO_CONTEXT))
|
||||
|
||||
GType _gdk_macos_cairo_context_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_CAIRO_CONTEXT_PRIVATE_H__ */
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2016 Benjamin Otte
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkconfig.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
#import "GdkMacosCairoView.h"
|
||||
|
||||
#include "gdkmacoscairocontext-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
struct _GdkMacosCairoContext
|
||||
{
|
||||
GdkCairoContext parent_instance;
|
||||
|
||||
cairo_surface_t *window_surface;
|
||||
};
|
||||
|
||||
struct _GdkMacosCairoContextClass
|
||||
{
|
||||
GdkCairoContextClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosCairoContext, _gdk_macos_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
|
||||
|
||||
static cairo_surface_t *
|
||||
create_cairo_surface_for_surface (GdkSurface *surface)
|
||||
{
|
||||
cairo_surface_t *cairo_surface;
|
||||
int scale;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
scale = gdk_surface_get_scale_factor (surface);
|
||||
width = scale * gdk_surface_get_width (surface);
|
||||
height = scale * gdk_surface_get_height (surface);
|
||||
|
||||
cairo_surface = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||
|
||||
if (cairo_surface != NULL)
|
||||
cairo_surface_set_device_scale (cairo_surface, scale, scale);
|
||||
|
||||
return cairo_surface;
|
||||
}
|
||||
|
||||
static cairo_t *
|
||||
_gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)cairo_context;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
return cairo_create (self->window_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
GdkSurface *surface;
|
||||
NSWindow *nswindow;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
if (self->window_surface == NULL)
|
||||
{
|
||||
self->window_surface = create_cairo_surface_for_surface (surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (![nswindow isOpaque])
|
||||
{
|
||||
cairo_t *cr = cairo_create (self->window_surface);
|
||||
gdk_cairo_region (cr, region);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_fill (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
GdkSurface *surface;
|
||||
NSView *nsview;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
g_assert (self->window_surface != NULL);
|
||||
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
if (GDK_IS_MACOS_CAIRO_VIEW (nsview))
|
||||
[(GdkMacosCairoView *)nsview setCairoSurface:self->window_surface
|
||||
withDamage:painted];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_surface_resized (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_class_init (GdkMacosCairoContextClass *klass)
|
||||
{
|
||||
GdkCairoContextClass *cairo_context_class = GDK_CAIRO_CONTEXT_CLASS (klass);
|
||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||
|
||||
draw_context_class->begin_frame = _gdk_macos_cairo_context_begin_frame;
|
||||
draw_context_class->end_frame = _gdk_macos_cairo_context_end_frame;
|
||||
draw_context_class->surface_resized = _gdk_macos_cairo_context_surface_resized;
|
||||
|
||||
cairo_context_class->cairo_create = _gdk_macos_cairo_context_cairo_create;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_init (GdkMacosCairoContext *self)
|
||||
{
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_CLIPBOARD_PRIVATE_H__
|
||||
#define __GDK_MACOS_CLIPBOARD_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkclipboardprivate.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_CLIPBOARD (_gdk_macos_clipboard_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK, MACOS_CLIPBOARD, GdkClipboard)
|
||||
|
||||
GdkClipboard *_gdk_macos_clipboard_new (GdkMacosDisplay *display);
|
||||
void _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self);
|
||||
NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate);
|
||||
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
||||
|
||||
@interface GdkMacosClipboardDataProvider : NSObject <NSPasteboardItemDataProvider>
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
GdkClipboard *clipboard;
|
||||
char **mimeTypes;
|
||||
}
|
||||
|
||||
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
||||
-(NSArray<NSPasteboardType> *)types;
|
||||
|
||||
@end
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_CLIPBOARD_PRIVATE_H__ */
|
||||
@@ -1,576 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
struct _GdkMacosClipboard
|
||||
{
|
||||
GdkClipboard parent_instance;
|
||||
NSPasteboard *pasteboard;
|
||||
NSInteger last_change_count;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GMemoryOutputStream *stream;
|
||||
NSPasteboardItem *item;
|
||||
NSPasteboardType type;
|
||||
GMainContext *main_context;
|
||||
guint done : 1;
|
||||
} WriteRequest;
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK_TYPE_CLIPBOARD)
|
||||
|
||||
static void
|
||||
write_request_free (WriteRequest *wr)
|
||||
{
|
||||
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
||||
g_clear_object (&wr->stream);
|
||||
[wr->item release];
|
||||
g_slice_free (WriteRequest, wr);
|
||||
}
|
||||
|
||||
const char *
|
||||
_gdk_macos_clipboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:NSPasteboardTypeString] ||
|
||||
[type isEqualToString:NSStringPboardType])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:NSPasteboardTypeURL] ||
|
||||
[type isEqualToString:NSPasteboardTypeFileURL])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:NSPasteboardTypeColor])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:NSPasteboardTypeTIFF])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:NSPasteboardTypePNG])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSPasteboardType
|
||||
_gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NULL;
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return NSPasteboardTypeString;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NSPasteboardTypeURL;
|
||||
return NSPasteboardTypeFileURL;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return NSPasteboardTypeColor;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return NSPasteboardTypeTIFF;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return NSPasteboardTypePNG;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_content_formats (GdkContentFormatsBuilder *builder,
|
||||
NSPasteboardType type)
|
||||
{
|
||||
const char *mime_type;
|
||||
|
||||
g_return_if_fail (builder != NULL);
|
||||
g_return_if_fail (type != NULL);
|
||||
|
||||
mime_type = _gdk_macos_clipboard_from_ns_type (type);
|
||||
|
||||
if (mime_type != NULL)
|
||||
gdk_content_formats_builder_add_mime_type (builder, mime_type);
|
||||
}
|
||||
|
||||
static GdkContentFormats *
|
||||
load_offer_formats (GdkMacosClipboard *self)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
for (NSPasteboardType type in [self->pasteboard types])
|
||||
populate_content_formats (builder, type);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&formats);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
NSInteger change_count;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
|
||||
change_count = [self->pasteboard changeCount];
|
||||
|
||||
formats = load_offer_formats (self);
|
||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (self), formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
|
||||
self->last_change_count = change_count;
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
create_stream_from_nsdata (NSData *data)
|
||||
{
|
||||
const guint8 *bytes = [data bytes];
|
||||
gsize len = [data length];
|
||||
|
||||
return g_memory_input_stream_new_from_data (g_memdup (bytes, len), len, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosClipboard *self = (GdkMacosClipboard *)clipboard;
|
||||
GdkContentFormats *offer_formats = NULL;
|
||||
const char *mime_type;
|
||||
GInputStream *stream = NULL;
|
||||
GTask *task = NULL;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
g_assert (formats != NULL);
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _gdk_macos_clipboard_read_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
offer_formats = load_offer_formats (GDK_MACOS_CLIPBOARD (clipboard));
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
||||
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"%s",
|
||||
_("No compatible transfer format found"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
NSString *nsstr = [self->pasteboard stringForType:NSPasteboardTypeString];
|
||||
|
||||
if (nsstr != NULL)
|
||||
{
|
||||
const char *str = [nsstr UTF8String];
|
||||
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
||||
strlen (str) + 1,
|
||||
g_free);
|
||||
}
|
||||
}
|
||||
else if (strcmp (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[self->pasteboard types] containsObject:NSPasteboardTypeFileURL])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [self->pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
gsize n_files = [files count];
|
||||
char *data;
|
||||
guint len;
|
||||
|
||||
for (gsize i = 0; i < n_files; ++i)
|
||||
{
|
||||
NSString* uriString = [files objectAtIndex:i];
|
||||
uriString = [@"file://" stringByAppendingString:uriString];
|
||||
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
g_string_append_printf (str,
|
||||
"%s\r\n",
|
||||
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
len = str->len;
|
||||
data = g_string_free (str, FALSE);
|
||||
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
else if (strcmp (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
NSColorSpace *colorspace;
|
||||
NSColor *nscolor;
|
||||
guint16 color[4];
|
||||
|
||||
colorspace = [NSColorSpace genericRGBColorSpace];
|
||||
nscolor = [[NSColor colorFromPasteboard:self->pasteboard]
|
||||
colorUsingColorSpace:colorspace];
|
||||
|
||||
color[0] = 0xffff * [nscolor redComponent];
|
||||
color[1] = 0xffff * [nscolor greenComponent];
|
||||
color[2] = 0xffff * [nscolor blueComponent];
|
||||
color[3] = 0xffff * [nscolor alphaComponent];
|
||||
|
||||
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:NSPasteboardTypeTIFF];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypePNG];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
||||
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
_("Failed to decode contents with mime-type of '%s'"),
|
||||
mime_type);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_clear_object (&task);
|
||||
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
_gdk_macos_clipboard_read_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = (GTask *)result;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (clipboard));
|
||||
g_assert (G_IS_TASK (task));
|
||||
|
||||
if (out_mime_type != NULL)
|
||||
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_send_to_pasteboard (GdkMacosClipboard *self,
|
||||
GdkContentProvider *content)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosClipboardDataProvider *dataProvider;
|
||||
GdkContentFormats *serializable;
|
||||
NSPasteboardItem *item;
|
||||
const char * const *mime_types;
|
||||
gsize n_mime_types;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (content));
|
||||
|
||||
serializable = gdk_content_provider_ref_storable_formats (content);
|
||||
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
|
||||
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
|
||||
|
||||
dataProvider = [[GdkMacosClipboardDataProvider alloc] initClipboard:GDK_CLIPBOARD (self)
|
||||
mimetypes:mime_types];
|
||||
item = [[NSPasteboardItem alloc] init];
|
||||
[item setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||
|
||||
[self->pasteboard clearContents];
|
||||
if ([self->pasteboard writeObjects:[NSArray arrayWithObject:item]] == NO)
|
||||
g_warning ("Failed to write object to pasteboard");
|
||||
|
||||
self->last_change_count = [self->pasteboard changeCount];
|
||||
|
||||
g_clear_pointer (&serializable, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_clipboard_claim (GdkClipboard *clipboard,
|
||||
GdkContentFormats *formats,
|
||||
gboolean local,
|
||||
GdkContentProvider *provider)
|
||||
{
|
||||
GdkMacosClipboard *self = (GdkMacosClipboard *)clipboard;
|
||||
gboolean ret;
|
||||
|
||||
g_assert (GDK_IS_CLIPBOARD (clipboard));
|
||||
g_assert (formats != NULL);
|
||||
g_assert (!provider || GDK_IS_CONTENT_PROVIDER (provider));
|
||||
|
||||
ret = GDK_CLIPBOARD_CLASS (_gdk_macos_clipboard_parent_class)->claim (clipboard, formats, local, provider);
|
||||
|
||||
if (local)
|
||||
_gdk_macos_clipboard_send_to_pasteboard (self, provider);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_constructed (GObject *object)
|
||||
{
|
||||
GdkMacosClipboard *self = (GdkMacosClipboard *)object;
|
||||
|
||||
if (self->pasteboard == nil)
|
||||
self->pasteboard = [[NSPasteboard generalPasteboard] retain];
|
||||
|
||||
G_OBJECT_CLASS (_gdk_macos_clipboard_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_finalize (GObject *object)
|
||||
{
|
||||
GdkMacosClipboard *self = (GdkMacosClipboard *)object;
|
||||
|
||||
if (self->pasteboard != nil)
|
||||
{
|
||||
[self->pasteboard release];
|
||||
self->pasteboard = nil;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (_gdk_macos_clipboard_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_class_init (GdkMacosClipboardClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkClipboardClass *clipboard_class = GDK_CLIPBOARD_CLASS (klass);
|
||||
|
||||
object_class->constructed = _gdk_macos_clipboard_constructed;
|
||||
object_class->finalize = _gdk_macos_clipboard_finalize;
|
||||
|
||||
clipboard_class->claim = _gdk_macos_clipboard_claim;
|
||||
clipboard_class->read_async = _gdk_macos_clipboard_read_async;
|
||||
clipboard_class->read_finish = _gdk_macos_clipboard_read_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_init (GdkMacosClipboard *self)
|
||||
{
|
||||
}
|
||||
|
||||
GdkClipboard *
|
||||
_gdk_macos_clipboard_new (GdkMacosDisplay *display)
|
||||
{
|
||||
GdkMacosClipboard *self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_CLIPBOARD,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
_gdk_macos_clipboard_load_contents (self);
|
||||
|
||||
return GDK_CLIPBOARD (self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
|
||||
if ([self->pasteboard changeCount] != self->last_change_count)
|
||||
_gdk_macos_clipboard_load_contents (self);
|
||||
}
|
||||
|
||||
@implementation GdkMacosClipboardDataProvider
|
||||
|
||||
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
||||
{
|
||||
[super init];
|
||||
|
||||
self->mimeTypes = g_strdupv ((char **)mime_types);
|
||||
self->clipboard = g_object_ref (gdkClipboard);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
|
||||
g_clear_pointer (&self->mimeTypes, g_strfreev);
|
||||
g_clear_object (&self->clipboard);
|
||||
g_clear_object (&self->cancellable);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
|
||||
{
|
||||
g_clear_object (&self->clipboard);
|
||||
}
|
||||
|
||||
-(NSArray<NSPasteboardType> *)types
|
||||
{
|
||||
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
||||
|
||||
for (guint i = 0; self->mimeTypes[i]; i++)
|
||||
{
|
||||
const char *mime_type = self->mimeTypes[i];
|
||||
NSPasteboardType type;
|
||||
NSPasteboardType alternate = nil;
|
||||
|
||||
if ((type = _gdk_macos_clipboard_to_ns_type (mime_type, &alternate)))
|
||||
{
|
||||
[ret addObject:type];
|
||||
if (alternate)
|
||||
[ret addObject:alternate];
|
||||
}
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
static void
|
||||
on_data_ready_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkClipboard *clipboard = (GdkClipboard *)object;
|
||||
WriteRequest *wr = user_data;
|
||||
GError *error = NULL;
|
||||
NSData *data = nil;
|
||||
|
||||
g_assert (GDK_IS_CLIPBOARD (clipboard));
|
||||
g_assert (G_IS_ASYNC_RESULT (result));
|
||||
g_assert (wr != NULL);
|
||||
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
|
||||
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
|
||||
|
||||
if (gdk_clipboard_write_finish (clipboard, result, &error))
|
||||
{
|
||||
gsize size;
|
||||
gpointer bytes;
|
||||
|
||||
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
|
||||
|
||||
size = g_memory_output_stream_get_size (wr->stream);
|
||||
bytes = g_memory_output_stream_steal_data (wr->stream);
|
||||
data = [[NSData alloc] initWithBytesNoCopy:bytes
|
||||
length:size
|
||||
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to serialize clipboard contents: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
[wr->item setData:data forType:wr->type];
|
||||
|
||||
wr->done = TRUE;
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
-(void) pasteboard:(NSPasteboard *)pasteboard
|
||||
item:(NSPasteboardItem *)item
|
||||
provideDataForType:(NSPasteboardType)type
|
||||
{
|
||||
const char *mime_type = _gdk_macos_clipboard_from_ns_type (type);
|
||||
GMainContext *main_context = g_main_context_default ();
|
||||
WriteRequest *wr;
|
||||
|
||||
if (self->clipboard == NULL || mime_type == NULL)
|
||||
{
|
||||
[item setData:[NSData data] forType:type];
|
||||
return;
|
||||
}
|
||||
|
||||
wr = g_slice_new0 (WriteRequest);
|
||||
wr->item = [item retain];
|
||||
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
||||
wr->type = type;
|
||||
wr->main_context = g_main_context_ref (main_context);
|
||||
wr->done = FALSE;
|
||||
|
||||
gdk_clipboard_write_async (self->clipboard,
|
||||
mime_type,
|
||||
G_OUTPUT_STREAM (wr->stream),
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
on_data_ready_cb,
|
||||
wr);
|
||||
|
||||
/* We're forced to provide data synchronously via this API
|
||||
* so we must block on the main loop. Using another main loop
|
||||
* than the default tends to get us locked up here, so that is
|
||||
* what we'll do for now.
|
||||
*/
|
||||
while (!wr->done)
|
||||
g_main_context_iteration (wr->main_context, TRUE);
|
||||
|
||||
write_request_free (wr);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,181 +0,0 @@
|
||||
/* gdkcursor-macos.c
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
* Copyright (C) 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "gdkmacoscursor-private.h"
|
||||
|
||||
/* OS X only exports a number of cursor types in its public NSCursor interface.
|
||||
* By overriding the private _coreCursorType method, we can tell OS X to load
|
||||
* one of its internal cursors instead (since cursor images are loaded on demand
|
||||
* instead of in advance). WebKit does this too.
|
||||
*/
|
||||
|
||||
@interface gdkCoreCursor : NSCursor {
|
||||
@private
|
||||
int type;
|
||||
BOOL override;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation gdkCoreCursor
|
||||
|
||||
- (long long)_coreCursorType
|
||||
{
|
||||
if (self->override)
|
||||
return self->type;
|
||||
return [super _coreCursorType];
|
||||
}
|
||||
|
||||
#define CUSTOM_CURSOR_CTOR(name, id) \
|
||||
+ (gdkCoreCursor *)name \
|
||||
{ \
|
||||
gdkCoreCursor *obj; \
|
||||
obj = [self new]; \
|
||||
if (obj) { \
|
||||
obj->override = YES; \
|
||||
obj->type = id; \
|
||||
} \
|
||||
return obj; \
|
||||
}
|
||||
CUSTOM_CURSOR_CTOR(gdkHelpCursor, 40)
|
||||
CUSTOM_CURSOR_CTOR(gdkProgressCursor, 4)
|
||||
/* TODO OS X doesn't seem to have a way to get this. There is an undocumented
|
||||
* method +[NSCursor _waitCursor], but it doesn't actually return this cursor,
|
||||
* but rather some odd low-quality non-animating version of this cursor. Use
|
||||
* the progress cursor instead for now.
|
||||
*/
|
||||
CUSTOM_CURSOR_CTOR(gdkWaitCursor, 4)
|
||||
CUSTOM_CURSOR_CTOR(gdkAliasCursor, 2)
|
||||
CUSTOM_CURSOR_CTOR(gdkMoveCursor, 39)
|
||||
/* TODO OS X doesn't seem to provide one; copy the move cursor for now
|
||||
* since it looks similar to what we want. */
|
||||
CUSTOM_CURSOR_CTOR(gdkAllScrollCursor, 39)
|
||||
CUSTOM_CURSOR_CTOR(gdkNEResizeCursor, 29)
|
||||
CUSTOM_CURSOR_CTOR(gdkNWResizeCursor, 33)
|
||||
CUSTOM_CURSOR_CTOR(gdkSEResizeCursor, 35)
|
||||
CUSTOM_CURSOR_CTOR(gdkSWResizeCursor, 37)
|
||||
CUSTOM_CURSOR_CTOR(gdkEWResizeCursor, 28)
|
||||
CUSTOM_CURSOR_CTOR(gdkNSResizeCursor, 32)
|
||||
CUSTOM_CURSOR_CTOR(gdkNESWResizeCursor, 30)
|
||||
CUSTOM_CURSOR_CTOR(gdkNWSEResizeCursor, 34)
|
||||
CUSTOM_CURSOR_CTOR(gdkZoomInCursor, 42)
|
||||
CUSTOM_CURSOR_CTOR(gdkZoomOutCursor, 43)
|
||||
#undef CUSTOM_CURSOR_CTOR
|
||||
|
||||
@end
|
||||
|
||||
struct CursorsByName {
|
||||
const gchar *name;
|
||||
NSString *selector;
|
||||
};
|
||||
|
||||
static const struct CursorsByName cursors_by_name[] = {
|
||||
/* Link & Status */
|
||||
{ "context-menu", @"contextualMenuCursor" },
|
||||
{ "help", @"gdkHelpCursor" },
|
||||
{ "pointer", @"pointingHandCursor" },
|
||||
{ "progress", @"gdkProgressCursor" },
|
||||
{ "wait", @"gdkWaitCursor" },
|
||||
/* Selection */
|
||||
{ "cell", @"crosshairCursor" },
|
||||
{ "crosshair", @"crosshairCursor" },
|
||||
{ "text", @"IBeamCursor" },
|
||||
{ "vertical-text", @"IBeamCursorForVerticalLayout" },
|
||||
/* Drag & Drop */
|
||||
{ "alias", @"gdkAliasCursor" },
|
||||
{ "copy", @"dragCopyCursor" },
|
||||
{ "move", @"gdkMoveCursor" },
|
||||
{ "no-drop", @"operationNotAllowedCursor" },
|
||||
{ "not-allowed", @"operationNotAllowedCursor" },
|
||||
{ "grab", @"openHandCursor" },
|
||||
{ "grabbing", @"closedHandCursor" },
|
||||
/* Resize & Scrolling */
|
||||
{ "all-scroll", @"gdkAllScrollCursor" },
|
||||
{ "col-resize", @"resizeLeftRightCursor" },
|
||||
{ "row-resize", @"resizeUpDownCursor" },
|
||||
|
||||
/* Undocumented cursors to match native resizing */
|
||||
{ "e-resize", @"_windowResizeEastWestCursor" },
|
||||
{ "w-resize", @"_windowResizeEastWestCursor" },
|
||||
{ "n-resize", @"_windowResizeNorthSouthCursor" },
|
||||
{ "s-resize", @"_windowResizeNorthSouthCursor" },
|
||||
|
||||
{ "ne-resize", @"gdkNEResizeCursor" },
|
||||
{ "nw-resize", @"gdkNWResizeCursor" },
|
||||
{ "se-resize", @"gdkSEResizeCursor" },
|
||||
{ "sw-resize", @"gdkSWResizeCursor" },
|
||||
{ "ew-resize", @"gdkEWResizeCursor" },
|
||||
{ "ns-resize", @"gdkNSResizeCursor" },
|
||||
{ "nesw-resize", @"gdkNESWResizeCursor" },
|
||||
{ "nwse-resize", @"gdkNWSEResizeCursor" },
|
||||
/* Zoom */
|
||||
{ "zoom-in", @"gdkZoomInCursor" },
|
||||
{ "zoom-out", @"gdkZoomOutCursor" },
|
||||
};
|
||||
|
||||
static NSCursor *
|
||||
create_blank_cursor (void)
|
||||
{
|
||||
NSCursor *nscursor;
|
||||
NSImage *nsimage;
|
||||
NSSize size = { 1.0, 1.0 };
|
||||
|
||||
nsimage = [[NSImage alloc] initWithSize:size];
|
||||
nscursor = [[NSCursor alloc] initWithImage:nsimage
|
||||
hotSpot:NSMakePoint(0.0, 0.0)];
|
||||
[nsimage release];
|
||||
|
||||
return nscursor;
|
||||
}
|
||||
|
||||
NSCursor *
|
||||
_gdk_macos_cursor_get_ns_cursor (GdkCursor *cursor)
|
||||
{
|
||||
const char *name = NULL;
|
||||
NSCursor *nscursor;
|
||||
SEL selector = @selector(arrowCursor);
|
||||
|
||||
g_return_val_if_fail (!cursor || GDK_IS_CURSOR (cursor), NULL);
|
||||
|
||||
if (cursor != NULL)
|
||||
name = gdk_cursor_get_name (cursor);
|
||||
|
||||
if (name == NULL)
|
||||
goto load_cursor;
|
||||
|
||||
if (strcmp (name, "none") == 0)
|
||||
return create_blank_cursor ();
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (cursors_by_name); i++)
|
||||
{
|
||||
if (strcmp (cursors_by_name[i].name, name) == 0)
|
||||
{
|
||||
selector = NSSelectorFromString (cursors_by_name[i].selector);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
load_cursor:
|
||||
nscursor = [[gdkCoreCursor class] performSelector:selector];
|
||||
[nscursor retain];
|
||||
return nscursor;
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
* Copyright 2010 Kristian Rietveld <kris@gtk.org>
|
||||
* Copyright 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
|
||||
#include "gdkmacoscursor-private.h"
|
||||
#include "gdkmacosdevice.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
struct _GdkMacosDevice
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkMacosDeviceClass
|
||||
{
|
||||
GdkDeviceClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosDevice, gdk_macos_device, GDK_TYPE_DEVICE)
|
||||
|
||||
static void
|
||||
gdk_macos_device_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
NSCursor *nscursor;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (device));
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_assert (!cursor || GDK_IS_CURSOR (cursor));
|
||||
|
||||
nscursor = _gdk_macos_cursor_get_ns_cursor (cursor);
|
||||
|
||||
if (nscursor != NULL)
|
||||
{
|
||||
[nscursor set];
|
||||
[nscursor release];
|
||||
}
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_macos_device_surface_at_position (GdkDevice *device,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *state)
|
||||
{
|
||||
GdkMacosDisplay *display;
|
||||
GdkMacosSurface *surface;
|
||||
NSPoint point;
|
||||
gint x;
|
||||
gint y;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (device));
|
||||
g_assert (win_x != NULL);
|
||||
g_assert (win_y != NULL);
|
||||
|
||||
point = [NSEvent mouseLocation];
|
||||
display = GDK_MACOS_DISPLAY (gdk_device_get_display (device));
|
||||
|
||||
if (state != NULL)
|
||||
*state = (_gdk_macos_display_get_current_keyboard_modifiers (display) |
|
||||
_gdk_macos_display_get_current_mouse_modifiers (display));
|
||||
|
||||
surface = _gdk_macos_display_get_surface_at_display_coords (display, point.x, point.y, &x, &y);
|
||||
|
||||
*win_x = x;
|
||||
*win_y = y;
|
||||
|
||||
return GDK_SURFACE (surface);
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_macos_device_grab (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
gboolean owner_events,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurface *confine_to,
|
||||
GdkCursor *cursor,
|
||||
guint32 time_)
|
||||
{
|
||||
/* Should remain empty */
|
||||
return GDK_GRAB_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_ungrab (GdkDevice *device,
|
||||
guint32 time_)
|
||||
{
|
||||
GdkMacosDevice *self = (GdkMacosDevice *)device;
|
||||
GdkDeviceGrabInfo *grab;
|
||||
GdkDisplay *display;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (self));
|
||||
|
||||
display = gdk_device_get_display (device);
|
||||
grab = _gdk_display_get_last_device_grab (display, device);
|
||||
|
||||
if (grab != NULL)
|
||||
grab->serial_end = 0;
|
||||
|
||||
_gdk_display_device_grab_update (display, device, device, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_get_state (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gdouble x_pos, y_pos;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (device));
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
gdk_surface_get_device_position (surface, device, &x_pos, &y_pos, mask);
|
||||
|
||||
if (axes != NULL)
|
||||
{
|
||||
axes[0] = x_pos;
|
||||
axes[1] = y_pos;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_query_state (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkSurface **child_surface,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
NSPoint point;
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int x_tmp;
|
||||
int y_tmp;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (device));
|
||||
g_assert (!surface || GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
if (child_surface)
|
||||
*child_surface = surface;
|
||||
|
||||
display = gdk_device_get_display (device);
|
||||
point = [NSEvent mouseLocation];
|
||||
_gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display),
|
||||
point.x, point.y,
|
||||
&x_tmp, &y_tmp);
|
||||
|
||||
if (surface)
|
||||
_gdk_macos_surface_get_root_coords (GDK_MACOS_SURFACE (surface), &sx, &sy);
|
||||
|
||||
if (win_x)
|
||||
*win_x = x_tmp - sx;
|
||||
|
||||
if (win_y)
|
||||
*win_y = y_tmp - sy;
|
||||
|
||||
if (mask)
|
||||
*mask = _gdk_macos_display_get_current_keyboard_modifiers (GDK_MACOS_DISPLAY (display)) |
|
||||
_gdk_macos_display_get_current_mouse_modifiers (GDK_MACOS_DISPLAY (display));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_class_init (GdkMacosDeviceClass *klass)
|
||||
{
|
||||
GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
|
||||
|
||||
device_class->get_state = gdk_macos_device_get_state;
|
||||
device_class->grab = gdk_macos_device_grab;
|
||||
device_class->query_state = gdk_macos_device_query_state;
|
||||
device_class->set_surface_cursor = gdk_macos_device_set_surface_cursor;
|
||||
device_class->surface_at_position = gdk_macos_device_surface_at_position;
|
||||
device_class->ungrab = gdk_macos_device_ungrab;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_init (GdkMacosDevice *self)
|
||||
{
|
||||
_gdk_device_add_axis (GDK_DEVICE (self), GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (GDK_DEVICE (self), GDK_AXIS_Y, 0, 0, 1);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DEVICE_H__
|
||||
#define __GDK_MACOS_DEVICE_H__
|
||||
|
||||
#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
|
||||
|
||||
typedef struct _GdkMacosDevice GdkMacosDevice;
|
||||
typedef struct _GdkMacosDeviceClass GdkMacosDeviceClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_DEVICE (gdk_macos_device_get_type())
|
||||
#define GDK_MACOS_DEVICE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DEVICE, GdkMacosDevice))
|
||||
#define GDK_IS_MACOS_DEVICE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DEVICE))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_device_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DEVICE_H__ */
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DISPLAY_PRIVATE_H__
|
||||
#define __GDK_MACOS_DISPLAY_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacoskeymap.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GdkMacosDisplay
|
||||
{
|
||||
GdkDisplay parent_instance;
|
||||
|
||||
char *name;
|
||||
GdkMacosKeymap *keymap;
|
||||
|
||||
/* An list of GdkMacosMonitor. The first instance is always the primary
|
||||
* monitor. This contains the 0,0 coordinate in quartz coordinates, but may
|
||||
* not be 0,0 in GDK coordinates.
|
||||
*/
|
||||
GListStore *monitors;
|
||||
|
||||
/* A queue of surfaces that have been made "main" so that we can update the
|
||||
* main status to the next surface when a window has lost main status (such
|
||||
* as when destroyed). This uses the GdkMacosSurface main link.
|
||||
*/
|
||||
GQueue main_surfaces;
|
||||
|
||||
/* A queue of surfaces sorted by their front-to-back ordering on the screen.
|
||||
* This is updated occasionally when we know that the data we have cached
|
||||
* has been invalidated. This uses the GdkMacosSurface.sorted link.
|
||||
*/
|
||||
GQueue sorted_surfaces;
|
||||
|
||||
/* Our CVDisplayLink based GSource which we use to freeze/thaw the
|
||||
* GdkFrameClock for the surface.
|
||||
*/
|
||||
GSource *frame_source;
|
||||
|
||||
/* A queue of surfaces which we know are awaiting frames to be drawn. This
|
||||
* uses the GdkMacosSurface.frame link.
|
||||
*/
|
||||
GQueue awaiting_frames;
|
||||
|
||||
/* The surface that is receiving keyboard events */
|
||||
GdkMacosSurface *keyboard_surface;
|
||||
|
||||
/* Used to translate from quartz coordinate space to GDK */
|
||||
int width;
|
||||
int height;
|
||||
int min_x;
|
||||
int min_y;
|
||||
int max_x;
|
||||
int max_y;
|
||||
};
|
||||
|
||||
struct _GdkMacosDisplayClass
|
||||
{
|
||||
GdkDisplayClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GdkDisplay *_gdk_macos_display_open (const gchar *display_name);
|
||||
int _gdk_macos_display_get_fd (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_queue_events (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_to_display_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y,
|
||||
int *out_x,
|
||||
int *out_y);
|
||||
void _gdk_macos_display_from_display_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y,
|
||||
int *out_x,
|
||||
int *out_y);
|
||||
NSScreen *_gdk_macos_display_get_screen_at_display_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
GdkMonitor *_gdk_macos_display_get_monitor_at_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
GdkMonitor *_gdk_macos_display_get_monitor_at_display_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
GdkEvent *_gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
NSEvent *event);
|
||||
void _gdk_macos_display_break_all_grabs (GdkMacosDisplay *self,
|
||||
guint32 time);
|
||||
GdkModifierType _gdk_macos_display_get_current_keyboard_modifiers (GdkMacosDisplay *self);
|
||||
GdkModifierType _gdk_macos_display_get_current_mouse_modifiers (GdkMacosDisplay *self);
|
||||
GdkMacosSurface *_gdk_macos_display_get_surface_at_display_coords (GdkMacosDisplay *self,
|
||||
double x,
|
||||
double y,
|
||||
int *surface_x,
|
||||
int *surface_y);
|
||||
void _gdk_macos_display_reload_monitors (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_surface_removed (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_add_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_remove_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_synthesize_motion (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
NSWindow *_gdk_macos_display_find_native_under_pointer (GdkMacosDisplay *self,
|
||||
int *x,
|
||||
int *y);
|
||||
gboolean _gdk_macos_display_get_setting (GdkMacosDisplay *self,
|
||||
const gchar *setting,
|
||||
GValue *value);
|
||||
void _gdk_macos_display_reload_settings (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_surface_resigned_main (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_surface_became_main (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
int _gdk_macos_display_get_nominal_refresh_rate (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_clear_sorting (GdkMacosDisplay *self);
|
||||
const GList *_gdk_macos_display_get_surfaces (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
NSEvent *nsevent);
|
||||
void _gdk_macos_display_warp_pointer (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DISPLAY_PRIVATE_H__ */
|
||||
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
* Copyright © 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright © 1998-2002 Tor Lillqvist
|
||||
* Copyright © 2005-2008 Imendio AB
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *font_name;
|
||||
int xft_dpi;
|
||||
int double_click_time;
|
||||
int cursor_blink_timeout;
|
||||
guint enable_animations : 1;
|
||||
guint shell_shows_desktop : 1;
|
||||
guint shell_shows_menubar : 1;
|
||||
guint primary_button_warps_slider : 1;
|
||||
} GdkMacosSettings;
|
||||
|
||||
static GdkMacosSettings current_settings;
|
||||
static gboolean current_settings_initialized;
|
||||
|
||||
static void
|
||||
_gdk_macos_settings_load (GdkMacosSettings *settings)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString *name;
|
||||
NSInteger ival;
|
||||
float fval;
|
||||
char *str;
|
||||
int pt_size;
|
||||
|
||||
g_assert (settings != NULL);
|
||||
|
||||
settings->shell_shows_desktop = TRUE;
|
||||
settings->shell_shows_menubar = TRUE;
|
||||
settings->enable_animations = TRUE;
|
||||
settings->xft_dpi = 72 * 1024;
|
||||
|
||||
ival = [defaults integerForKey:@"NSTextInsertionPointBlinkPeriod"];
|
||||
if (ival > 0)
|
||||
settings->cursor_blink_timeout = ival;
|
||||
else
|
||||
settings->cursor_blink_timeout = 1000;
|
||||
|
||||
settings->primary_button_warps_slider =
|
||||
[[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollerPagingBehavior"] == YES;
|
||||
|
||||
fval = [defaults floatForKey:@"com.apple.mouse.doubleClickThreshold"];
|
||||
if (fval == 0.0)
|
||||
fval = 0.5;
|
||||
settings->double_click_time = fval * 1000;
|
||||
|
||||
name = [[NSFont systemFontOfSize:0] familyName];
|
||||
pt_size = (gint)[[NSFont userFontOfSize:0] pointSize];
|
||||
/* Let's try to use the "views" font size (12pt) by default. This is
|
||||
* used for lists/text/other "content" which is the largest parts of
|
||||
* apps, using the "regular control" size (13pt) looks a bit out of
|
||||
* place. We might have to tweak this.
|
||||
*
|
||||
* The size has to be hardcoded as there doesn't seem to be a way to
|
||||
* get the views font size programmatically.
|
||||
*/
|
||||
str = g_strdup_printf ("%s %d", [name UTF8String], pt_size);
|
||||
settings->font_name = g_intern_string (str);
|
||||
g_free (str);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_display_get_setting (GdkMacosDisplay *self,
|
||||
const gchar *setting,
|
||||
GValue *value)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (self), FALSE);
|
||||
g_return_val_if_fail (setting != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
if (!current_settings_initialized)
|
||||
{
|
||||
_gdk_macos_settings_load (¤t_settings);
|
||||
current_settings_initialized = TRUE;
|
||||
}
|
||||
|
||||
if (FALSE) {}
|
||||
else if (strcmp (setting, "gtk-enable-animations") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, current_settings.enable_animations);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-xft-dpi") == 0)
|
||||
{
|
||||
g_value_set_int (value, current_settings.xft_dpi);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-cursor-blink-timeout") == 0)
|
||||
{
|
||||
g_value_set_int (value, current_settings.cursor_blink_timeout);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-double-click-time") == 0)
|
||||
{
|
||||
g_value_set_int (value, current_settings.double_click_time);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-font-name") == 0)
|
||||
{
|
||||
g_value_set_static_string (value, current_settings.font_name);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-primary-button-warps-slider") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, current_settings.primary_button_warps_slider);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-shell-shows-desktop") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, current_settings.shell_shows_desktop);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-shell-shows-menubar") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, current_settings.shell_shows_menubar);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_reload_settings (GdkMacosDisplay *self)
|
||||
{
|
||||
GdkMacosSettings old_settings;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
old_settings = current_settings;
|
||||
_gdk_macos_settings_load (¤t_settings);
|
||||
current_settings_initialized = TRUE;
|
||||
|
||||
if (old_settings.xft_dpi != current_settings.xft_dpi)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-xft-dpi");
|
||||
|
||||
if (old_settings.double_click_time != current_settings.double_click_time)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-double-click-time");
|
||||
|
||||
if (old_settings.enable_animations != current_settings.enable_animations)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-enable-animations");
|
||||
|
||||
if (old_settings.font_name != current_settings.font_name)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-font-name");
|
||||
|
||||
if (old_settings.primary_button_warps_slider != current_settings.primary_button_warps_slider)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-primary-button-warps-slider");
|
||||
|
||||
if (old_settings.shell_shows_menubar != current_settings.shell_shows_menubar)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-shell-shows-menubar");
|
||||
|
||||
if (old_settings.shell_shows_desktop != current_settings.shell_shows_desktop)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-shell-shows-desktop");
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DISPLAY_H__
|
||||
#define __GDK_MACOS_DISPLAY_H__
|
||||
|
||||
#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
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkMacosDisplay GdkMacosDisplay;
|
||||
#else
|
||||
typedef GdkDisplay GdkMacosDisplay;
|
||||
#endif
|
||||
typedef struct _GdkMacosDisplayClass GdkMacosDisplayClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_DISPLAY (gdk_macos_display_get_type())
|
||||
#define GDK_MACOS_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DISPLAY, GdkMacosDisplay))
|
||||
#define GDK_IS_MACOS_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DISPLAY))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_display_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DISPLAY_H__ */
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DRAG_PRIVATE_H__
|
||||
#define __GDK_MACOS_DRAG_PRIVATE_H__
|
||||
|
||||
#include "gdkdragprivate.h"
|
||||
|
||||
#include "gdkmacosdragsurface-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_DRAG (gdk_macos_drag_get_type ())
|
||||
#define GDK_MACOS_DRAG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DRAG, GdkMacosDrag))
|
||||
#define GDK_MACOS_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_MACOS_DRAG, GdkMacosDragClass))
|
||||
#define GDK_IS_MACOS_DRAG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DRAG))
|
||||
#define GDK_IS_MACOS_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_MACOS_DRAG))
|
||||
#define GDK_MACOS_DRAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_MACOS_DRAG, GdkMacosDragClass))
|
||||
|
||||
typedef struct _GdkMacosDrag GdkMacosDrag;
|
||||
typedef struct _GdkMacosDragClass GdkMacosDragClass;
|
||||
|
||||
struct _GdkMacosDrag
|
||||
{
|
||||
GdkDrag parent_instance;
|
||||
|
||||
GdkMacosDragSurface *drag_surface;
|
||||
GdkSeat *drag_seat;
|
||||
GdkCursor *cursor;
|
||||
|
||||
int hot_x;
|
||||
int hot_y;
|
||||
|
||||
int last_x;
|
||||
int last_y;
|
||||
|
||||
int start_x;
|
||||
int start_y;
|
||||
|
||||
guint did_update : 1;
|
||||
guint cancelled : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosDragClass
|
||||
{
|
||||
GdkDragClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_macos_drag_get_type (void) G_GNUC_CONST;
|
||||
gboolean _gdk_macos_drag_begin (GdkMacosDrag *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DRAG_PRIVATE_H__ */
|
||||
@@ -1,617 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.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
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkintl.h"
|
||||
|
||||
#include "gdkmacoscursor-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosdrag-private.h"
|
||||
#include "gdkmacosdragsurface-private.h"
|
||||
|
||||
#define BIG_STEP 20
|
||||
#define SMALL_STEP 1
|
||||
#define ANIM_TIME 500000 /* .5 seconds */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkMacosDrag *drag;
|
||||
GdkFrameClock *frame_clock;
|
||||
gint64 start_time;
|
||||
} GdkMacosZoomback;
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosDrag, gdk_macos_drag, GDK_TYPE_DRAG)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DRAG_SURFACE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static double
|
||||
ease_out_cubic (double t)
|
||||
{
|
||||
double p = t - 1;
|
||||
return p * p * p + 1;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_zoomback_destroy (GdkMacosZoomback *zb)
|
||||
{
|
||||
gdk_surface_hide (GDK_SURFACE (zb->drag->drag_surface));
|
||||
g_clear_object (&zb->drag);
|
||||
g_slice_free (GdkMacosZoomback, zb);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_zoomback_timeout (gpointer data)
|
||||
{
|
||||
GdkMacosZoomback *zb = data;
|
||||
GdkFrameClock *frame_clock;
|
||||
GdkMacosDrag *drag;
|
||||
gint64 current_time;
|
||||
double f;
|
||||
double t;
|
||||
|
||||
g_assert (zb != NULL);
|
||||
g_assert (GDK_IS_MACOS_DRAG (zb->drag));
|
||||
|
||||
drag = zb->drag;
|
||||
frame_clock = zb->frame_clock;
|
||||
|
||||
if (!frame_clock)
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
current_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
f = (current_time - zb->start_time) / (double) ANIM_TIME;
|
||||
if (f >= 1.0)
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
t = ease_out_cubic (f);
|
||||
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (drag->drag_surface),
|
||||
(drag->last_x - drag->hot_x) +
|
||||
(drag->start_x - drag->last_x) * t,
|
||||
(drag->last_y - drag->hot_y) +
|
||||
(drag->start_y - drag->last_y) * t);
|
||||
_gdk_macos_surface_set_opacity (GDK_MACOS_SURFACE (drag->drag_surface), 1.0 - f);
|
||||
|
||||
/* Make sure we're topmost */
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (drag->drag_surface));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_macos_drag_get_drag_surface (GdkDrag *drag)
|
||||
{
|
||||
return GDK_SURFACE (GDK_MACOS_DRAG (drag)->drag_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_set_hotspot (GdkDrag *drag,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
int change_x;
|
||||
int change_y;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
change_x = hot_x - self->hot_x;
|
||||
change_y = hot_y - self->hot_y;
|
||||
|
||||
self->hot_x = hot_x;
|
||||
self->hot_y = hot_y;
|
||||
|
||||
if (change_x || change_y)
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
|
||||
GDK_SURFACE (self->drag_surface)->x + change_x,
|
||||
GDK_SURFACE (self->drag_surface)->y + change_y);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_drop_done (GdkDrag *drag,
|
||||
gboolean success)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
GdkMacosZoomback *zb;
|
||||
guint id;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
if (success)
|
||||
{
|
||||
gdk_surface_hide (GDK_SURFACE (self->drag_surface));
|
||||
g_object_unref (drag);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Apple HIG suggests doing a "zoomback" animation of the surface back
|
||||
* towards the original position.
|
||||
*/
|
||||
zb = g_slice_new0 (GdkMacosZoomback);
|
||||
zb->drag = g_object_ref (self);
|
||||
zb->frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self->drag_surface));
|
||||
zb->start_time = gdk_frame_clock_get_frame_time (zb->frame_clock);
|
||||
|
||||
id = g_timeout_add_full (G_PRIORITY_DEFAULT, 17,
|
||||
gdk_macos_zoomback_timeout,
|
||||
zb,
|
||||
(GDestroyNotify) gdk_macos_zoomback_destroy);
|
||||
g_source_set_name_by_id (id, "[gtk] gdk_macos_zoomback_timeout");
|
||||
g_object_unref (drag);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_set_cursor (GdkDrag *drag,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
NSCursor *nscursor;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
g_assert (!cursor || GDK_IS_CURSOR (cursor));
|
||||
|
||||
g_set_object (&self->cursor, cursor);
|
||||
|
||||
nscursor = _gdk_macos_cursor_get_ns_cursor (cursor);
|
||||
|
||||
if (nscursor != NULL)
|
||||
[nscursor set];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_grab (GdkMacosDrag *self)
|
||||
{
|
||||
GdkSeat *seat;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
seat = gdk_device_get_seat (gdk_drag_get_device (GDK_DRAG (self)));
|
||||
|
||||
if (gdk_seat_grab (seat,
|
||||
GDK_SURFACE (self->drag_surface),
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE,
|
||||
self->cursor,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL) != GDK_GRAB_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
g_set_object (&self->drag_seat, seat);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_ungrab (GdkMacosDrag *self)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
display = gdk_drag_get_display (GDK_DRAG (self));
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
if (self->cancelled)
|
||||
return;
|
||||
|
||||
self->cancelled = TRUE;
|
||||
drag_ungrab (self);
|
||||
gdk_drag_drop_done (drag, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_drop_performed (GdkDrag *drag,
|
||||
guint32 time)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
drag_ungrab (self);
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
gdk_drag_drop_done (drag, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_get_current_actions (GdkModifierType state,
|
||||
gint button,
|
||||
GdkDragAction actions,
|
||||
GdkDragAction *suggested_action,
|
||||
GdkDragAction *possible_actions)
|
||||
{
|
||||
*suggested_action = 0;
|
||||
*possible_actions = 0;
|
||||
|
||||
if ((button == GDK_BUTTON_MIDDLE || button == GDK_BUTTON_SECONDARY) && (actions & GDK_ACTION_ASK))
|
||||
{
|
||||
*suggested_action = GDK_ACTION_ASK;
|
||||
*possible_actions = actions;
|
||||
}
|
||||
else if (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))
|
||||
{
|
||||
if ((state & GDK_SHIFT_MASK) && (state & GDK_CONTROL_MASK))
|
||||
{
|
||||
if (actions & GDK_ACTION_LINK)
|
||||
{
|
||||
*suggested_action = GDK_ACTION_LINK;
|
||||
*possible_actions = GDK_ACTION_LINK;
|
||||
}
|
||||
}
|
||||
else if (state & GDK_CONTROL_MASK)
|
||||
{
|
||||
if (actions & GDK_ACTION_COPY)
|
||||
{
|
||||
*suggested_action = GDK_ACTION_COPY;
|
||||
*possible_actions = GDK_ACTION_COPY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (actions & GDK_ACTION_MOVE)
|
||||
{
|
||||
*suggested_action = GDK_ACTION_MOVE;
|
||||
*possible_actions = GDK_ACTION_MOVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*possible_actions = actions;
|
||||
|
||||
if ((state & (GDK_ALT_MASK)) && (actions & GDK_ACTION_ASK))
|
||||
*suggested_action = GDK_ACTION_ASK;
|
||||
else if (actions & GDK_ACTION_COPY)
|
||||
*suggested_action = GDK_ACTION_COPY;
|
||||
else if (actions & GDK_ACTION_MOVE)
|
||||
*suggested_action = GDK_ACTION_MOVE;
|
||||
else if (actions & GDK_ACTION_LINK)
|
||||
*suggested_action = GDK_ACTION_LINK;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_update (GdkDrag *drag,
|
||||
gdouble x_root,
|
||||
gdouble y_root,
|
||||
GdkModifierType mods,
|
||||
guint32 evtime)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
GdkDragAction suggested_action;
|
||||
GdkDragAction possible_actions;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
self->last_x = x_root;
|
||||
self->last_y = y_root;
|
||||
|
||||
gdk_drag_get_current_actions (mods,
|
||||
GDK_BUTTON_PRIMARY,
|
||||
gdk_drag_get_actions (drag),
|
||||
&suggested_action,
|
||||
&possible_actions);
|
||||
|
||||
_gdk_macos_drag_surface_drag_motion (self->drag_surface,
|
||||
x_root - self->hot_x,
|
||||
y_root - self->hot_y,
|
||||
suggested_action,
|
||||
possible_actions,
|
||||
evtime);
|
||||
|
||||
if (!self->did_update)
|
||||
{
|
||||
self->start_x = self->last_x;
|
||||
self->start_y = self->last_y;
|
||||
self->did_update = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_motion_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
double x, y;
|
||||
int x_root, y_root;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (drag));
|
||||
g_assert (event != NULL);
|
||||
|
||||
/* Ignore motion while doing zoomback */
|
||||
if (GDK_MACOS_DRAG (drag)->cancelled)
|
||||
return FALSE;
|
||||
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
x_root = event->surface->x + x;
|
||||
y_root = event->surface->y + y;
|
||||
gdk_drag_update (drag, x_root, y_root,
|
||||
gdk_event_get_modifier_state (event),
|
||||
gdk_event_get_time (event));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_grab_broken_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
gboolean is_implicit = gdk_grab_broken_event_get_implicit (event);
|
||||
GdkSurface *grab_surface = gdk_grab_broken_event_get_grab_surface (event);
|
||||
|
||||
/* Don't cancel if we break the implicit grab from the initial button_press. */
|
||||
if (is_implicit || grab_surface == (GdkSurface *)self->drag_surface)
|
||||
return FALSE;
|
||||
|
||||
if (gdk_event_get_device (event) != gdk_drag_get_device (drag))
|
||||
return FALSE;
|
||||
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_ERROR);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_button_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
g_assert (event != NULL);
|
||||
|
||||
#if 0
|
||||
/* FIXME: Check the button matches */
|
||||
if (event->button != self->button)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_key_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer;
|
||||
gint dx, dy;
|
||||
|
||||
dx = dy = 0;
|
||||
state = gdk_event_get_modifier_state (event);
|
||||
pointer = gdk_device_get_associated_device (gdk_event_get_device (event));
|
||||
|
||||
if (event->event_type == GDK_KEY_PRESS)
|
||||
{
|
||||
guint keyval = gdk_key_event_get_keyval (event);
|
||||
|
||||
switch (keyval)
|
||||
{
|
||||
case GDK_KEY_Escape:
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_USER_CANCELLED);
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_space:
|
||||
case GDK_KEY_Return:
|
||||
case GDK_KEY_ISO_Enter:
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_KP_Space:
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_Up:
|
||||
case GDK_KEY_KP_Up:
|
||||
dy = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Down:
|
||||
case GDK_KEY_KP_Down:
|
||||
dy = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Left:
|
||||
case GDK_KEY_KP_Left:
|
||||
dx = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Right:
|
||||
case GDK_KEY_KP_Right:
|
||||
dx = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The state is not yet updated in the event, so we need
|
||||
* to query it here. We could use XGetModifierMapping, but
|
||||
* that would be overkill.
|
||||
*/
|
||||
_gdk_device_query_state (pointer, NULL, NULL, NULL, NULL, &state);
|
||||
|
||||
if (dx != 0 || dy != 0)
|
||||
{
|
||||
GdkDisplay *display = gdk_event_get_display ((GdkEvent *)event);
|
||||
|
||||
self->last_x += dx;
|
||||
self->last_y += dy;
|
||||
|
||||
_gdk_macos_display_warp_pointer (GDK_MACOS_DISPLAY (display),
|
||||
self->last_x,
|
||||
self->last_y);
|
||||
}
|
||||
|
||||
gdk_drag_update (drag,
|
||||
self->last_x, self->last_y,
|
||||
state,
|
||||
gdk_event_get_time (event));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_drag_handle_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_DRAG (drag));
|
||||
g_assert (event != NULL);
|
||||
|
||||
switch ((guint) event->event_type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
return gdk_dnd_handle_motion_event (drag, event);
|
||||
|
||||
case GDK_BUTTON_RELEASE:
|
||||
return gdk_dnd_handle_button_event (drag, event);
|
||||
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
return gdk_dnd_handle_key_event (drag, event);
|
||||
|
||||
case GDK_GRAB_BROKEN:
|
||||
return gdk_dnd_handle_grab_broken_event (drag, event);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_finalize (GObject *object)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)object;
|
||||
GdkMacosDragSurface *drag_surface = g_steal_pointer (&self->drag_surface);
|
||||
|
||||
g_clear_object (&self->cursor);
|
||||
g_clear_object (&self->drag_seat);
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_drag_parent_class)->finalize (object);
|
||||
|
||||
if (drag_surface)
|
||||
gdk_surface_destroy (GDK_SURFACE (drag_surface));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DRAG_SURFACE:
|
||||
g_value_set_object (value, self->drag_surface);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DRAG_SURFACE:
|
||||
self->drag_surface = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_class_init (GdkMacosDragClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDragClass *drag_class = GDK_DRAG_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_macos_drag_finalize;
|
||||
object_class->get_property = gdk_macos_drag_get_property;
|
||||
object_class->set_property = gdk_macos_drag_set_property;
|
||||
|
||||
drag_class->get_drag_surface = gdk_macos_drag_get_drag_surface;
|
||||
drag_class->set_hotspot = gdk_macos_drag_set_hotspot;
|
||||
drag_class->drop_done = gdk_macos_drag_drop_done;
|
||||
drag_class->set_cursor = gdk_macos_drag_set_cursor;
|
||||
drag_class->cancel = gdk_macos_drag_cancel;
|
||||
drag_class->drop_performed = gdk_macos_drag_drop_performed;
|
||||
drag_class->handle_event = gdk_macos_drag_handle_event;
|
||||
|
||||
properties [PROP_DRAG_SURFACE] =
|
||||
g_param_spec_object ("drag-surface",
|
||||
P_("Drag Surface"),
|
||||
P_("Drag Surface"),
|
||||
GDK_TYPE_MACOS_DRAG_SURFACE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_init (GdkMacosDrag *self)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_drag_begin (GdkMacosDrag *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), FALSE);
|
||||
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self->drag_surface));
|
||||
|
||||
return drag_grab (self);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user