Compare commits
284 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f6ea7c418 | |||
| ba8f39a90a | |||
| 6d17e74d0e | |||
| 9ab78cd215 | |||
| 8ae8fe9e4c | |||
| d63a729ab1 | |||
| 444323244c | |||
| ce44bd7fa4 | |||
| 3568a591f1 | |||
| 1577db0092 | |||
| ea7ab799ad | |||
| 6535af8424 | |||
| 7821cb1417 | |||
| 8c50312abf | |||
| 723010ed09 | |||
| f0affa8886 | |||
| 8b3304820e | |||
| 5592af40ad | |||
| d3268b3af0 | |||
| c5e1c97ca4 | |||
| 7d99339c39 | |||
| 1e2c03beee | |||
| b24e10fa30 | |||
| 173952cbc8 | |||
| b31f4f2bae | |||
| df9d9c1f8a | |||
| 7dcb25bd46 | |||
| d131c8d0e7 | |||
| 0582a4ef1b | |||
| a9b1d4a389 | |||
| ea810f176b | |||
| 262ac4247a | |||
| 8e4f0b9484 | |||
| 7669e6e42e | |||
| a3f14a3395 | |||
| 73b8212bf3 | |||
| 6ba6f361be | |||
| 726909d735 | |||
| 04899e3707 | |||
| 7a27122dab | |||
| 73ce437459 | |||
| ca4ae81170 | |||
| 21a7dfae96 | |||
| 6c188f7c93 | |||
| c30e0f78ad | |||
| 76795ffba9 | |||
| c38c5c4ce1 | |||
| 108aac9ee3 | |||
| c427c2b22a | |||
| 59111d100f | |||
| cee8f78c6e | |||
| 0fc35b2124 | |||
| eebe67cf0a | |||
| b9726901a5 | |||
| df1d2b8417 | |||
| 8b1af398a0 | |||
| 982d73df0b | |||
| 1e55e01692 | |||
| 412fcb0330 | |||
| b8d1c3ab55 | |||
| 4fb519f04d | |||
| 054d69aaf9 | |||
| 1dea6d4fc7 | |||
| 022d19a4c6 | |||
| ef7276c398 | |||
| 0a8ca49b5e | |||
| 74f18f71d3 | |||
| c0d4a6fc81 | |||
| 1dd31d58fb | |||
| 766d4dff76 | |||
| e62f135c6a | |||
| 4788f88840 | |||
| 587bc82c37 | |||
| 750dc8dbe2 | |||
| d490d8f1f3 | |||
| cb2f523994 | |||
| 075a0ccb5e | |||
| db91b6dc61 | |||
| 44ac2d5abb | |||
| d7df56b6cb | |||
| 6a9bc5daef | |||
| b8aa51d522 | |||
| f79c807645 | |||
| d0d2ad9f5b | |||
| 0b8298038a | |||
| 6ef0bb8bea | |||
| 91472b2ecd | |||
| 80ddcf38d4 | |||
| 1477882b31 | |||
| 73f2167fe4 | |||
| 2079c898e7 | |||
| c79c18f39c | |||
| cef7f7f87d | |||
| fdce30d3f8 | |||
| f07397f4dd | |||
| f1751f514c | |||
| 2cbfb0e980 | |||
| 8dd7f5aefe | |||
| 398f49ad31 | |||
| 3d260a950e | |||
| f31667f437 | |||
| 219493c818 | |||
| 06f63764fb | |||
| 1243174e53 | |||
| cc909b160f | |||
| d12dde07c3 | |||
| 5191b6fccd | |||
| 2e6e6c1779 | |||
| a29b8fbef4 | |||
| 5b072e716c | |||
| 49845795d9 | |||
| ab04c74ec9 | |||
| 4744bb9099 | |||
| 91522dda63 | |||
| 095a378dbc | |||
| 0956c30ee5 | |||
| f85448ffbf | |||
| d3852ca33a | |||
| 9d9a730659 | |||
| 3f4cd4190f | |||
| 448a402353 | |||
| 2ee9752822 | |||
| f8a1f796b5 | |||
| 3b5a4cf215 | |||
| 759d53cfa0 | |||
| 814d20d61a | |||
| 6cef520804 | |||
| 8c77491150 | |||
| 709ebcedd4 | |||
| 47e6b88555 | |||
| df58d0acf3 | |||
| 9c2c5665df | |||
| 1be9c6aa3f | |||
| 96d2bf10b9 | |||
| 7a1aefc7f3 | |||
| f7f06f810b | |||
| e02fd80adb | |||
| 4b818495ca | |||
| 1841ec4f8e | |||
| 21708e4352 | |||
| 662bcb34b1 | |||
| f8a19506ab | |||
| 67d1d5ec80 | |||
| 49c6e99970 | |||
| 15242d66e1 | |||
| 94a0bc01f9 | |||
| 677c4b140c | |||
| 838ad5ed6d | |||
| 772ac2b0c5 | |||
| 68b3b66c03 | |||
| 0d1614be63 | |||
| 62b95e33b8 | |||
| dc5c8d2d29 | |||
| 425d5cc7c6 | |||
| baf99bb868 | |||
| 538efd0cc6 | |||
| 9ba184adf7 | |||
| 710b8d7f40 | |||
| a6244a95be | |||
| 133b6f2f23 | |||
| 53a634e23e | |||
| 156935e0e9 | |||
| f31a016efb | |||
| e56eb7b17b | |||
| de694958b5 | |||
| e12a580b0b | |||
| 52e0eef6cb | |||
| 85bf4cf895 | |||
| b06331218d | |||
| 9b165c8bec | |||
| 3fd427cfce | |||
| 0bb9fc65ad | |||
| 3dd6cc405e | |||
| 06860bb2be | |||
| 7ee5779efc | |||
| 53d9445715 | |||
| 54b2727b50 | |||
| a2aefa83bb | |||
| 0854140b22 | |||
| 57a861723c | |||
| b59521bb82 | |||
| 7e8393ba0f | |||
| 9e15f3df75 | |||
| 5c97f09796 | |||
| bf4ec504b2 | |||
| 59aeae3c8e | |||
| 941f22c033 | |||
| 27543120f2 | |||
| 901518ec25 | |||
| 4c9b0d82af | |||
| 2c5f4c5871 | |||
| 8ee44d200d | |||
| 57b7e87d76 | |||
| e424246134 | |||
| ca87048045 | |||
| 5ec9b15d84 | |||
| 6b691bc02d | |||
| abcd83dd78 | |||
| 5d2113ff5d | |||
| 5c086b9d44 | |||
| 8efa612288 | |||
| 928f7faf7d | |||
| 4b4cf36b03 | |||
| 5d821425b3 | |||
| 8b3066127f | |||
| 360239a6c8 | |||
| 80e903afeb | |||
| 62e9ea412a | |||
| 3d4acf6360 | |||
| 0cf1e1e106 | |||
| b23fbe1f39 | |||
| f5e79b9bc5 | |||
| 94e238c467 | |||
| 22f6787283 | |||
| 6255dcd8ec | |||
| 6f80eee962 | |||
| fd0f01bcad | |||
| 0b6e521dc5 | |||
| ad6fe9d6a0 | |||
| 7078765903 | |||
| a73947e54f | |||
| 7525271de1 | |||
| 0bc65f0bde | |||
| 4a0476752c | |||
| 9543a5daeb | |||
| 28b91a4450 | |||
| 6b89d8a199 | |||
| e999016273 | |||
| 7c6e620f16 | |||
| 267d5ae011 | |||
| 08d4bb4785 | |||
| a02e25ffff | |||
| 280bdb0567 | |||
| 1a94e5fb0e | |||
| b6cfe59460 | |||
| 7db2abf918 | |||
| b398af914f | |||
| 29e1dac1ff | |||
| 3af8a658a7 | |||
| b5aeb29146 | |||
| 85b702b0d1 | |||
| 77c57b4b14 | |||
| 10d260ec71 | |||
| 1ac8bb0128 | |||
| 28539ba838 | |||
| f1bb6ef658 | |||
| 24c66f831f | |||
| 87502b4f2e | |||
| 3644d3a100 | |||
| 9e3147f78d | |||
| cc3ecac6d8 | |||
| 72932d2776 | |||
| 58bc9452f6 | |||
| 2a7b5d8229 | |||
| 245546de61 | |||
| a3793ff137 | |||
| 0a98817a6f | |||
| 663fb93af7 | |||
| db42c23c0a | |||
| 33716d1e50 | |||
| 65769fd7a6 | |||
| e6d3f3d91e | |||
| 79a17d5a25 | |||
| c924b48a6c | |||
| 519ff576cd | |||
| 5bc3bed461 | |||
| 442f13ef6f | |||
| 95aeadf36c | |||
| 267ea7552b | |||
| 08f7526f8f | |||
| 0604924c20 | |||
| 5ef2748cef | |||
| 8f8229dcd2 | |||
| a5b5657e96 | |||
| 0f2281e267 | |||
| 994a807819 | |||
| 79f42cec8e | |||
| 0546fd7c8a | |||
| d51e3e835e | |||
| 3d8d4921af | |||
| ba3549fa34 | |||
| 721595edea | |||
| 46d960ddfd | |||
| a439be5161 |
+1
-2
@@ -13,7 +13,7 @@ stages:
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64: &fedora-x86_64-defaults
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v7
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v8
|
||||
stage: build
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
@@ -45,7 +45,6 @@ fedora-x86_64-staticlibs:
|
||||
script:
|
||||
- C:\msys64\usr\bin\pacman --noconfirm -Syyuu
|
||||
- C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/test-msys2.sh"
|
||||
allow_failure: true
|
||||
cache:
|
||||
key: "%CI_JOB_NAME%"
|
||||
<<: *cache-paths
|
||||
|
||||
@@ -53,6 +53,7 @@ RUN dnf -y install \
|
||||
libxkbcommon-devel \
|
||||
libXrandr-devel \
|
||||
libXrender-devel \
|
||||
libXtst-devel \
|
||||
libxslt \
|
||||
mesa-dri-drivers \
|
||||
mesa-libEGL-devel \
|
||||
|
||||
@@ -33,6 +33,10 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
||||
|
||||
# https://gitlab.gnome.org/GNOME/gtk/issues/2243
|
||||
wget "https://gitlab.gnome.org/creiter/gitlab-ci-win32-runner/raw/master/pango/mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
|
||||
pacman --noconfirm -U "mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ maintainers review your contribution.
|
||||
|
||||
Each contribution is reviewed by the core developers of the GTK project.
|
||||
|
||||
The [CODE-OWNERS](./docs/CODE-OWNERS) document contains the list of core
|
||||
The [CODEOWNERS](./docs/CODEOWNERS) document contains the list of core
|
||||
contributors to GTK and the areas for which they are responsible; you
|
||||
should ensure to receive their review and signoff on your changes.
|
||||
|
||||
|
||||
@@ -419,7 +419,7 @@ demo_application_window_load_state (DemoApplicationWindow *win)
|
||||
static void
|
||||
demo_application_window_init (DemoApplicationWindow *window)
|
||||
{
|
||||
GtkWidget *menu;
|
||||
GtkWidget *popover;
|
||||
|
||||
window->width = -1;
|
||||
window->height = -1;
|
||||
@@ -428,8 +428,8 @@ demo_application_window_init (DemoApplicationWindow *window)
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (window));
|
||||
|
||||
menu = gtk_menu_new_from_model (window->toolmenu);
|
||||
gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (window->menutool), menu);
|
||||
popover = gtk_popover_menu_new_from_model (window->menutool, window->toolmenu);
|
||||
gtk_menu_tool_button_set_popover (GTK_MENU_TOOL_BUTTON (window->menutool), popover);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (window),
|
||||
win_entries, G_N_ELEMENTS (win_entries),
|
||||
|
||||
@@ -43,25 +43,17 @@
|
||||
<object class="GtkInfoBar" id="infobar">
|
||||
<property name="visible">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox" id="content_area">
|
||||
<child>
|
||||
<object class="GtkLabel" id="message">
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="message">
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="valign">center</property>
|
||||
<property name="label" translatable="yes">_OK</property>
|
||||
<property name="use-underline">1</property>
|
||||
<signal name="clicked" handler="clicked_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton">
|
||||
<property name="valign">center</property>
|
||||
<property name="label" translatable="yes">_OK</property>
|
||||
<property name="use-underline">1</property>
|
||||
<signal name="clicked" handler="clicked_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
|
||||
@@ -94,6 +94,7 @@ create_page1 (GtkWidget *assistant)
|
||||
GtkWidget *box, *label, *entry;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
g_object_set (box, "margin", 12, NULL);
|
||||
|
||||
label = gtk_label_new ("You must fill out this entry to continue:");
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
@@ -115,10 +116,12 @@ create_page2 (GtkWidget *assistant)
|
||||
{
|
||||
GtkWidget *box, *checkbutton;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
g_object_set (box, "margin", 12, NULL);
|
||||
|
||||
checkbutton = gtk_check_button_new_with_label ("This is optional data, you may continue "
|
||||
"even if you do not check this");
|
||||
gtk_widget_set_valign (checkbutton, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (box), checkbutton);
|
||||
|
||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
|
||||
|
||||
+15
-40
@@ -38,7 +38,22 @@ help_activate (GSimpleAction *action,
|
||||
g_print ("Help not available\n");
|
||||
}
|
||||
|
||||
static void
|
||||
not_implemented (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_print ("Action “%s” not implemented\n", g_action_get_name (G_ACTION (action)));
|
||||
}
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "new", not_implemented, NULL, NULL, NULL },
|
||||
{ "open", not_implemented, NULL, NULL, NULL },
|
||||
{ "save", not_implemented, NULL, NULL, NULL },
|
||||
{ "save-as", not_implemented, NULL, NULL, NULL },
|
||||
{ "copy", not_implemented, NULL, NULL, NULL },
|
||||
{ "cut", not_implemented, NULL, NULL, NULL },
|
||||
{ "paste", not_implemented, NULL, NULL, NULL },
|
||||
{ "quit", quit_activate, NULL, NULL, NULL },
|
||||
{ "about", about_activate, NULL, NULL, NULL },
|
||||
{ "help", help_activate, NULL, NULL, NULL }
|
||||
@@ -50,8 +65,6 @@ do_builder (GtkWidget *do_widget)
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *toolbar;
|
||||
GActionGroup *actions;
|
||||
GtkAccelGroup *accel_group;
|
||||
GtkWidget *item;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
@@ -72,44 +85,6 @@ do_builder (GtkWidget *do_widget)
|
||||
win_entries, G_N_ELEMENTS (win_entries),
|
||||
window);
|
||||
gtk_widget_insert_action_group (window, "win", actions);
|
||||
accel_group = gtk_accel_group_new ();
|
||||
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "new_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_n, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "open_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "save_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_s, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "quit_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "copy_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "cut_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_x, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "paste_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_v, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "help_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_F1, 0, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "about_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_F7, 0, GTK_ACCEL_VISIBLE);
|
||||
|
||||
g_object_set_data_full (G_OBJECT(window), "builder", builder, g_object_unref);
|
||||
}
|
||||
|
||||
@@ -1,551 +0,0 @@
|
||||
/* Change Display
|
||||
*
|
||||
* Demonstrates migrating a window between different displays.
|
||||
* A display is a mouse and keyboard with some number of
|
||||
* associated monitors. The neat thing about having multiple
|
||||
* displays is that they can be on a completely separate
|
||||
* computers, as long as there is a network connection to the
|
||||
* computer where the application is running.
|
||||
*
|
||||
* Only some of the windowing systems where GTK runs have the
|
||||
* concept of multiple displays. (The X Window System is the
|
||||
* main example.) Other windowing systems can only handle one
|
||||
* keyboard and mouse, and combine all monitors into
|
||||
* a single display.
|
||||
*
|
||||
* This is a moderately complex example, and demonstrates:
|
||||
*
|
||||
* - Tracking the currently open displays
|
||||
*
|
||||
* - Changing the display for a window
|
||||
*
|
||||
* - Letting the user choose a window by clicking on it
|
||||
*
|
||||
* - Using GtkListStore and GtkTreeView
|
||||
*
|
||||
* - Using GtkDialog
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* The ChangeDisplayInfo structure corresponds to a toplevel window and
|
||||
* holds pointers to widgets inside the toplevel window along with other
|
||||
* information about the contents of the window.
|
||||
* This is a common organizational structure in real applications.
|
||||
*/
|
||||
typedef struct _ChangeDisplayInfo ChangeDisplayInfo;
|
||||
|
||||
struct _ChangeDisplayInfo
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkSizeGroup *size_group;
|
||||
|
||||
GtkTreeModel *display_model;
|
||||
|
||||
GdkDisplay *current_display;
|
||||
};
|
||||
|
||||
/* These enumerations provide symbolic names for the columns
|
||||
* in the two GtkListStore models.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
DISPLAY_COLUMN_NAME,
|
||||
DISPLAY_COLUMN_DISPLAY,
|
||||
DISPLAY_NUM_COLUMNS
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SCREEN_COLUMN_NUMBER,
|
||||
SCREEN_COLUMN_SCREEN,
|
||||
SCREEN_NUM_COLUMNS
|
||||
};
|
||||
|
||||
/* Finds the toplevel window under the mouse pointer, if any.
|
||||
*/
|
||||
static GtkWidget *
|
||||
find_toplevel_at_pointer (GdkDisplay *display)
|
||||
{
|
||||
GdkSurface *pointer_window;
|
||||
GtkWidget *widget = NULL;
|
||||
|
||||
pointer_window = gdk_device_get_surface_at_position (gtk_get_current_event_device (), NULL, NULL);
|
||||
|
||||
if (pointer_window)
|
||||
widget = GTK_WIDGET (gtk_native_get_for_surface (pointer_window));
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
released_cb (GtkGestureClick *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gboolean *clicked)
|
||||
{
|
||||
*clicked = TRUE;
|
||||
}
|
||||
|
||||
/* Asks the user to click on a window, then waits for them click
|
||||
* the mouse. When the mouse is released, returns the toplevel
|
||||
* window under the pointer, or NULL, if there is none.
|
||||
*/
|
||||
static GtkWidget *
|
||||
query_for_toplevel (GdkDisplay *display,
|
||||
const char *prompt)
|
||||
{
|
||||
GtkWidget *popup, *label, *frame;
|
||||
GdkCursor *cursor;
|
||||
GtkWidget *toplevel = NULL;
|
||||
GdkDevice *device;
|
||||
|
||||
popup = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_window_set_display (GTK_WINDOW (popup), display);
|
||||
gtk_window_set_modal (GTK_WINDOW (popup), TRUE);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
||||
gtk_container_add (GTK_CONTAINER (popup), frame);
|
||||
|
||||
label = gtk_label_new (prompt);
|
||||
g_object_set (label, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
|
||||
gtk_widget_show (popup);
|
||||
cursor = gdk_cursor_new_from_name ("crosshair", NULL);
|
||||
device = gtk_get_current_event_device ();
|
||||
|
||||
if (gdk_seat_grab (gdk_device_get_seat (device),
|
||||
gtk_native_get_surface (GTK_NATIVE (popup)),
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
|
||||
{
|
||||
GtkGesture *gesture = gtk_gesture_click_new ();
|
||||
gboolean clicked = FALSE;
|
||||
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (released_cb), &clicked);
|
||||
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
/* Process events until clicked is set by our button release event handler.
|
||||
* We pass in may_block=TRUE since we want to wait if there
|
||||
* are no events currently.
|
||||
*/
|
||||
while (!clicked)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
gdk_seat_ungrab (gdk_device_get_seat (device));
|
||||
|
||||
toplevel = find_toplevel_at_pointer (display);
|
||||
if (toplevel == popup)
|
||||
toplevel = NULL;
|
||||
}
|
||||
|
||||
g_object_unref (cursor);
|
||||
gtk_widget_destroy (popup);
|
||||
|
||||
return toplevel;
|
||||
}
|
||||
|
||||
/* Prompts the user for a toplevel window to move, and then moves
|
||||
* that window to the currently selected display
|
||||
*/
|
||||
static void
|
||||
query_change_display (ChangeDisplayInfo *info)
|
||||
{
|
||||
GdkDisplay *display = gtk_widget_get_display (info->window);
|
||||
GtkWidget *toplevel;
|
||||
|
||||
toplevel = query_for_toplevel (display,
|
||||
"Please select the toplevel\n"
|
||||
"to move to the new display");
|
||||
|
||||
if (toplevel)
|
||||
gtk_window_set_display (GTK_WINDOW (toplevel), info->current_display);
|
||||
else
|
||||
gdk_display_beep (display);
|
||||
}
|
||||
|
||||
/* Called when the user clicks on a button in our dialog or
|
||||
* closes the dialog through the window manager. Unless the
|
||||
* "Change" button was clicked, we destroy the dialog.
|
||||
*/
|
||||
static void
|
||||
response_cb (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_OK)
|
||||
query_change_display (info);
|
||||
else
|
||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||
}
|
||||
|
||||
/* Called when the user clicks on "Open..." in the display
|
||||
* frame. Prompts for a new display, and then opens a connection
|
||||
* to that display.
|
||||
*/
|
||||
static void
|
||||
open_display_cb (GtkWidget *button,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *display_entry;
|
||||
GtkWidget *dialog_label;
|
||||
gchar *new_screen_name = NULL;
|
||||
GdkDisplay *result = NULL;
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons ("Open Display",
|
||||
GTK_WINDOW (info->window),
|
||||
GTK_DIALOG_MODAL,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("_OK"), GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
||||
display_entry = gtk_entry_new ();
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (display_entry), TRUE);
|
||||
dialog_label =
|
||||
gtk_label_new ("Please enter the name of\nthe new display\n");
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (content_area), dialog_label);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), display_entry);
|
||||
|
||||
gtk_widget_grab_focus (display_entry);
|
||||
|
||||
while (!result)
|
||||
{
|
||||
gint response_id = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
if (response_id != GTK_RESPONSE_OK)
|
||||
break;
|
||||
|
||||
new_screen_name = gtk_editable_get_chars (GTK_EDITABLE (display_entry),
|
||||
0, -1);
|
||||
|
||||
if (strcmp (new_screen_name, "") != 0)
|
||||
{
|
||||
result = gdk_display_open (new_screen_name);
|
||||
if (!result)
|
||||
{
|
||||
gchar *error_msg =
|
||||
g_strdup_printf ("Can't open display:\n\t%s\nplease try another one\n",
|
||||
new_screen_name);
|
||||
gtk_label_set_text (GTK_LABEL (dialog_label), error_msg);
|
||||
g_free (error_msg);
|
||||
}
|
||||
|
||||
g_free (new_screen_name);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
/* Called when the user clicks on the "Close" button in the
|
||||
* "Display" frame. Closes the selected display.
|
||||
*/
|
||||
static void
|
||||
close_display_cb (GtkWidget *button,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
if (info->current_display)
|
||||
gdk_display_close (info->current_display);
|
||||
}
|
||||
|
||||
/* Called when the selected row in the display list changes.
|
||||
* Updates info->current_display, then refills the list of
|
||||
* screens.
|
||||
*/
|
||||
static void
|
||||
display_changed_cb (GtkTreeSelection *selection,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (info->current_display)
|
||||
g_object_unref (info->current_display);
|
||||
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
gtk_tree_model_get (model, &iter,
|
||||
DISPLAY_COLUMN_DISPLAY, &info->current_display,
|
||||
-1);
|
||||
else
|
||||
info->current_display = NULL;
|
||||
}
|
||||
|
||||
/* This function is used both for creating the "Display" and
|
||||
* "Screen" frames, since they have a similar structure. The
|
||||
* caller hooks up the right context for the value returned
|
||||
* in tree_view, and packs any relevant buttons into button_vbox.
|
||||
*/
|
||||
static void
|
||||
create_frame (ChangeDisplayInfo *info,
|
||||
const char *title,
|
||||
GtkWidget **frame,
|
||||
GtkWidget **tree_view,
|
||||
GtkWidget **button_vbox)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkWidget *scrollwin;
|
||||
GtkWidget *hbox;
|
||||
|
||||
*frame = gtk_frame_new (title);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
g_object_set (hbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (*frame), hbox);
|
||||
|
||||
scrollwin = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin),
|
||||
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin),
|
||||
GTK_SHADOW_IN);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), scrollwin);
|
||||
|
||||
*tree_view = gtk_tree_view_new ();
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (*tree_view), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (scrollwin), *tree_view);
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (*tree_view));
|
||||
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
|
||||
|
||||
*button_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), *button_vbox);
|
||||
|
||||
if (!info->size_group)
|
||||
info->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
|
||||
gtk_size_group_add_widget (GTK_SIZE_GROUP (info->size_group), *button_vbox);
|
||||
}
|
||||
|
||||
/* If we have a stack of buttons, it often looks better if their contents
|
||||
* are left-aligned, rather than centered. This function creates a button
|
||||
* and left-aligns it contents.
|
||||
*/
|
||||
GtkWidget *
|
||||
left_align_button_new (const char *label)
|
||||
{
|
||||
GtkWidget *button = gtk_button_new_with_mnemonic (label);
|
||||
GtkWidget *child = gtk_bin_get_child (GTK_BIN (button));
|
||||
|
||||
gtk_widget_set_halign (child, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
/* Creates the "Display" frame in the main window.
|
||||
*/
|
||||
GtkWidget *
|
||||
create_display_frame (ChangeDisplayInfo *info)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *tree_view;
|
||||
GtkWidget *button_vbox;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeSelection *selection;
|
||||
GtkWidget *button;
|
||||
|
||||
create_frame (info, "Display", &frame, &tree_view, &button_vbox);
|
||||
|
||||
button = left_align_button_new ("_Open...");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (open_display_cb), info);
|
||||
gtk_container_add (GTK_CONTAINER (button_vbox), button);
|
||||
|
||||
button = left_align_button_new ("_Close");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (close_display_cb), info);
|
||||
gtk_container_add (GTK_CONTAINER (button_vbox), button);
|
||||
|
||||
info->display_model = (GtkTreeModel *)gtk_list_store_new (DISPLAY_NUM_COLUMNS,
|
||||
G_TYPE_STRING,
|
||||
GDK_TYPE_DISPLAY);
|
||||
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), info->display_model);
|
||||
|
||||
column = gtk_tree_view_column_new_with_attributes ("Name",
|
||||
gtk_cell_renderer_text_new (),
|
||||
"text", DISPLAY_COLUMN_NAME,
|
||||
NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (display_changed_cb), info);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/* Called when one of the currently open displays is closed.
|
||||
* Remove it from our list of displays.
|
||||
*/
|
||||
static void
|
||||
display_closed_cb (GdkDisplay *display,
|
||||
gboolean is_error,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gboolean valid;
|
||||
|
||||
for (valid = gtk_tree_model_get_iter_first (info->display_model, &iter);
|
||||
valid;
|
||||
valid = gtk_tree_model_iter_next (info->display_model, &iter))
|
||||
{
|
||||
GdkDisplay *tmp_display;
|
||||
|
||||
gtk_tree_model_get (info->display_model, &iter,
|
||||
DISPLAY_COLUMN_DISPLAY, &tmp_display,
|
||||
-1);
|
||||
if (tmp_display == display)
|
||||
{
|
||||
gtk_list_store_remove (GTK_LIST_STORE (info->display_model), &iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds a new display to our list of displays, and connects
|
||||
* to the "closed" signal so that we can remove it from the
|
||||
* list of displays again.
|
||||
*/
|
||||
static void
|
||||
add_display (ChangeDisplayInfo *info,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
const gchar *name = gdk_display_get_name (display);
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_list_store_append (GTK_LIST_STORE (info->display_model), &iter);
|
||||
gtk_list_store_set (GTK_LIST_STORE (info->display_model), &iter,
|
||||
DISPLAY_COLUMN_NAME, name,
|
||||
DISPLAY_COLUMN_DISPLAY, display,
|
||||
-1);
|
||||
|
||||
g_signal_connect (display, "closed",
|
||||
G_CALLBACK (display_closed_cb), info);
|
||||
}
|
||||
|
||||
/* Called when a new display is opened
|
||||
*/
|
||||
static void
|
||||
display_opened_cb (GdkDisplayManager *manager,
|
||||
GdkDisplay *display,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
add_display (info, display);
|
||||
}
|
||||
|
||||
/* Adds all currently open displays to our list of displays,
|
||||
* and set up a signal connection so that we'll be notified
|
||||
* when displays are opened in the future as well.
|
||||
*/
|
||||
static void
|
||||
initialize_displays (ChangeDisplayInfo *info)
|
||||
{
|
||||
GdkDisplayManager *manager = gdk_display_manager_get ();
|
||||
GSList *displays = gdk_display_manager_list_displays (manager);
|
||||
GSList *tmp_list;
|
||||
|
||||
for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
|
||||
add_display (info, tmp_list->data);
|
||||
|
||||
g_slist_free (tmp_list);
|
||||
|
||||
g_signal_connect (manager, "display-opened",
|
||||
G_CALLBACK (display_opened_cb), info);
|
||||
}
|
||||
|
||||
/* Cleans up when the toplevel is destroyed; we remove the
|
||||
* connections we use to track currently open displays, then
|
||||
* free the ChangeDisplayInfo structure.
|
||||
*/
|
||||
static void
|
||||
destroy_info (ChangeDisplayInfo *info)
|
||||
{
|
||||
GdkDisplayManager *manager = gdk_display_manager_get ();
|
||||
GSList *displays = gdk_display_manager_list_displays (manager);
|
||||
GSList *tmp_list;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (manager,
|
||||
display_opened_cb,
|
||||
info);
|
||||
|
||||
for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
|
||||
g_signal_handlers_disconnect_by_func (tmp_list->data,
|
||||
display_closed_cb,
|
||||
info);
|
||||
|
||||
g_slist_free (tmp_list);
|
||||
|
||||
g_object_unref (info->size_group);
|
||||
g_object_unref (info->display_model);
|
||||
|
||||
if (info->current_display)
|
||||
g_object_unref (info->current_display);
|
||||
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_cb (GObject *object,
|
||||
ChangeDisplayInfo **info)
|
||||
{
|
||||
destroy_info (*info);
|
||||
*info = NULL;
|
||||
}
|
||||
|
||||
/* Main entry point. If the dialog for this demo doesn't yet exist, creates
|
||||
* it. Otherwise, destroys it.
|
||||
*/
|
||||
GtkWidget *
|
||||
do_changedisplay (GtkWidget *do_widget)
|
||||
{
|
||||
static ChangeDisplayInfo *info = NULL;
|
||||
|
||||
if (!info)
|
||||
{
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *frame;
|
||||
|
||||
info = g_new0 (ChangeDisplayInfo, 1);
|
||||
|
||||
info->window = gtk_dialog_new_with_buttons ("Change Display",
|
||||
GTK_WINDOW (do_widget),
|
||||
0,
|
||||
"Close", GTK_RESPONSE_CLOSE,
|
||||
"Change", GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (info->window), 300, 400);
|
||||
|
||||
g_signal_connect (info->window, "response",
|
||||
G_CALLBACK (response_cb), info);
|
||||
g_signal_connect (info->window, "destroy",
|
||||
G_CALLBACK (destroy_cb), &info);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (info->window));
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
g_object_set (vbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), vbox);
|
||||
|
||||
frame = create_display_frame (info);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
|
||||
initialize_displays (info);
|
||||
|
||||
gtk_widget_show (info->window);
|
||||
return info->window;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_destroy (info->window);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
+47
-29
@@ -164,17 +164,19 @@ drag_data_received (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
copy_image (GtkMenuItem *item,
|
||||
gpointer data)
|
||||
copy_image (GSimpleAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
|
||||
g_print ("copy image\n");
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
|
||||
{
|
||||
g_print ("set clipboard\n");
|
||||
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
|
||||
}
|
||||
|
||||
if (paintable)
|
||||
g_object_unref (paintable);
|
||||
@@ -196,16 +198,12 @@ paste_image_received (GObject *source,
|
||||
}
|
||||
|
||||
static void
|
||||
paste_image (GtkMenuItem *item,
|
||||
gpointer data)
|
||||
paste_image (GSimpleAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
gdk_clipboard_read_texture_async (clipboard,
|
||||
NULL,
|
||||
paste_image_received,
|
||||
data);
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
gdk_clipboard_read_texture_async (clipboard, NULL, paste_image_received, data);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -215,22 +213,23 @@ pressed_cb (GtkGesture *gesture,
|
||||
double y,
|
||||
GtkWidget *image)
|
||||
{
|
||||
GtkWidget *menu;
|
||||
GtkWidget *item;
|
||||
GtkWidget *popover;
|
||||
GMenu *menu;
|
||||
GMenuItem *item;
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
menu = g_menu_new ();
|
||||
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
|
||||
g_menu_append_item (menu, item);
|
||||
|
||||
item = gtk_menu_item_new_with_mnemonic (_("_Copy"));
|
||||
g_signal_connect (item, "activate", G_CALLBACK (copy_image), image);
|
||||
gtk_widget_show (item);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
|
||||
g_menu_append_item (menu, item);
|
||||
|
||||
item = gtk_menu_item_new_with_mnemonic (_("_Paste"));
|
||||
g_signal_connect (item, "activate", G_CALLBACK (paste_image), image);
|
||||
gtk_widget_show (item);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||
popover = gtk_popover_menu_new_from_model (image, G_MENU_MODEL (menu));
|
||||
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &(GdkRectangle) { x, y, 1, 1});
|
||||
gtk_popover_popup (GTK_POPOVER (popover));
|
||||
|
||||
g_object_unref (menu);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -243,6 +242,11 @@ do_clipboard (GtkWidget *do_widget)
|
||||
GtkWidget *entry, *button;
|
||||
GtkWidget *image;
|
||||
GtkGesture *gesture;
|
||||
GActionEntry entries[] = {
|
||||
{ "copy", copy_image, NULL, NULL, NULL },
|
||||
{ "paste", paste_image, NULL, NULL, NULL },
|
||||
};
|
||||
GActionGroup *actions;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
@@ -324,6 +328,13 @@ do_clipboard (GtkWidget *do_widget)
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
|
||||
|
||||
gtk_widget_insert_action_group (image, "clipboard", actions);
|
||||
|
||||
g_object_unref (actions);
|
||||
|
||||
/* Create the second image */
|
||||
image = gtk_image_new_from_icon_name ("process-stop");
|
||||
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||
@@ -348,6 +359,13 @@ do_clipboard (GtkWidget *do_widget)
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
|
||||
|
||||
gtk_widget_insert_action_group (image, "clipboard", actions);
|
||||
|
||||
g_object_unref (actions);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -149,7 +149,6 @@
|
||||
<file>application_demo.c</file>
|
||||
<file>assistant.c</file>
|
||||
<file>builder.c</file>
|
||||
<file>changedisplay.c</file>
|
||||
<file>clipboard.c</file>
|
||||
<file>colorsel.c</file>
|
||||
<file>combobox.c</file>
|
||||
@@ -191,7 +190,6 @@
|
||||
<file>listbox.c</file>
|
||||
<file>list_store.c</file>
|
||||
<file>markup.c</file>
|
||||
<file>menus.c</file>
|
||||
<file>modelbutton.c</file>
|
||||
<file>overlay.c</file>
|
||||
<file>overlay2.c</file>
|
||||
|
||||
+71
-103
@@ -22,6 +22,75 @@
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<menu id="menubar">
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_File</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_New</attribute>
|
||||
<attribute name="action">win.new</attribute>
|
||||
<attribute name="accel"><Primary>n</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Open</attribute>
|
||||
<attribute name="action">win.open</attribute>
|
||||
<attribute name="accel"><Primary>o</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Save</attribute>
|
||||
<attribute name="action">win.save</attribute>
|
||||
<attribute name="accel"><Primary>s</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Save _As</attribute>
|
||||
<attribute name="action">win.save-as</attribute>
|
||||
<attribute name="accel"><Primary>q</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="action">win.quit</attribute>
|
||||
<attribute name="accel"><Primary><Shift>s</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Edit</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Copy</attribute>
|
||||
<attribute name="action">win.copy</attribute>
|
||||
<attribute name="accel"><Primary>c</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Cut</attribute>
|
||||
<attribute name="action">win.cut</attribute>
|
||||
<attribute name="accel"><Primary>x</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Paste</attribute>
|
||||
<attribute name="action">win.paste</attribute>
|
||||
<attribute name="accel"><Primary>v</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<attribute name="action">win.help</attribute>
|
||||
<attribute name="accel">F1</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About</attribute>
|
||||
<attribute name="action">win.about</attribute>
|
||||
<attribute name="accel">F7</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
</menu>
|
||||
<object class="GtkAboutDialog" id="aboutdialog1">
|
||||
<property name="program-name" translatable="yes">Builder demo</property>
|
||||
<property name="logo-icon-name" translatable="yes">gtk3-demo</property>
|
||||
@@ -37,109 +106,8 @@
|
||||
<object class="GtkBox" id="vbox1">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkMenuBar" id="menubar1">
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="a11y-menubar">
|
||||
<property name="AtkObject::accessible-name">The menubar</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="new_item">
|
||||
<property name="label" translatable="yes">_New</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="open_item">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="save_item">
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="save_as_item">
|
||||
<property name="label" translatable="yes">Save _As</property>
|
||||
<property name="use-underline">1</property>
|
||||
<accelerator key="s" modifiers="primary | shift-mask" signal="activate"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="quit_item">
|
||||
<property name="label" translatable="yes">_Quit</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.quit</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="label" translatable="yes">_Edit</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="copy_item">
|
||||
<property name="label" translatable="yes">_Copy</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="cut_item">
|
||||
<property name="label" translatable="yes">_Cut</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="paste_item">
|
||||
<property name="label" translatable="yes">_Paste</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="label" translatable="yes">_Help</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="help_item">
|
||||
<property name="label" translatable="yes">_Help</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.help</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="about_item">
|
||||
<property name="label" translatable="yes">_About</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.about</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkPopoverMenuBar" id="menubar1">
|
||||
<property name="menu-model">menubar</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
+68
-52
@@ -1,6 +1,8 @@
|
||||
/* Drag-and-Drop
|
||||
*
|
||||
* I can't believe its not glade!
|
||||
*
|
||||
* Try right-clicking in the window.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
@@ -92,7 +94,7 @@ deserialize_widget (GtkDemoWidget *demo)
|
||||
static double pos_x, pos_y;
|
||||
|
||||
static void
|
||||
new_label_cb (GtkMenuItem *item,
|
||||
new_label_cb (GtkWidget *button,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFixed *fixed = data;
|
||||
@@ -100,10 +102,12 @@ new_label_cb (GtkMenuItem *item,
|
||||
|
||||
widget = gtk_label_new ("Label");
|
||||
gtk_fixed_put (fixed, widget, pos_x, pos_y);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
new_spinner_cb (GtkMenuItem *item,
|
||||
new_spinner_cb (GtkWidget *button,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFixed *fixed = data;
|
||||
@@ -113,33 +117,39 @@ new_spinner_cb (GtkMenuItem *item,
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "demo");
|
||||
gtk_spinner_start (GTK_SPINNER (widget));
|
||||
gtk_fixed_put (fixed, widget, pos_x, pos_y);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
copy_cb (GtkWidget *child)
|
||||
copy_cb (GtkWidget *button, GtkWidget *child)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
GtkDemoWidget *demo;
|
||||
|
||||
g_print ("Copy %s\n", G_OBJECT_TYPE_NAME (child));
|
||||
|
||||
demo = serialize_widget (child);
|
||||
|
||||
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
|
||||
gdk_clipboard_set (clipboard, GTK_TYPE_DEMO_WIDGET, demo);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
delete_cb (GtkWidget *child)
|
||||
delete_cb (GtkWidget *button, GtkWidget *child)
|
||||
{
|
||||
gtk_widget_destroy (child);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
cut_cb (GtkWidget *child)
|
||||
cut_cb (GtkWidget *button, GtkWidget *child)
|
||||
{
|
||||
copy_cb (child);
|
||||
delete_cb (child);
|
||||
copy_cb (button, child);
|
||||
delete_cb (button, child);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -175,7 +185,7 @@ value_read (GObject *source,
|
||||
}
|
||||
|
||||
static void
|
||||
paste_cb (GtkWidget *fixed)
|
||||
paste_cb (GtkWidget *button, GtkWidget *fixed)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
@@ -187,6 +197,8 @@ paste_cb (GtkWidget *fixed)
|
||||
}
|
||||
else
|
||||
g_print ("Don't know how to handle clipboard contents\n");
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -205,7 +217,7 @@ edit_label_done (GtkWidget *entry, gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
edit_cb (GtkWidget *child)
|
||||
edit_cb (GtkWidget *button, GtkWidget *child)
|
||||
{
|
||||
GtkWidget *fixed = gtk_widget_get_parent (child);
|
||||
int x, y;
|
||||
@@ -219,6 +231,7 @@ edit_cb (GtkWidget *child)
|
||||
g_object_set_data (G_OBJECT (entry), "label", child);
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), gtk_label_get_text (GTK_LABEL (child)));
|
||||
gtk_editable_set_width_chars (GTK_EDITABLE (entry), 12);
|
||||
g_signal_connect (entry, "activate", G_CALLBACK (edit_label_done), NULL);
|
||||
gtk_fixed_put (GTK_FIXED (fixed), entry, x, y);
|
||||
gtk_widget_grab_focus (entry);
|
||||
@@ -230,6 +243,9 @@ edit_cb (GtkWidget *child)
|
||||
g_object_get (child, "active", &active, NULL);
|
||||
g_object_set (child, "active", !active, NULL);
|
||||
}
|
||||
|
||||
if (button)
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -247,65 +263,65 @@ pressed_cb (GtkGesture *gesture,
|
||||
|
||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *box;
|
||||
GtkWidget *item;
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
pos_x = x;
|
||||
pos_y = y;
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
item = gtk_menu_item_new_with_label ("New Label");
|
||||
g_signal_connect (item, "activate", G_CALLBACK (new_label_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_menu_item_new_with_label ("New Spinner");
|
||||
g_signal_connect (item, "activate", G_CALLBACK (new_spinner_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
menu = gtk_popover_new (widget);
|
||||
gtk_popover_set_has_arrow (GTK_POPOVER (menu), FALSE);
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (menu), &(GdkRectangle){ x, y, 1, 1});
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (menu), box);
|
||||
|
||||
item = gtk_separator_menu_item_new ();
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_button_new_with_label ("New Label");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (new_label_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_button_new_with_label ("New Spinner");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (new_spinner_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
|
||||
item = gtk_menu_item_new_with_label ("Edit");
|
||||
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
|
||||
item = gtk_button_new_with_label ("Edit");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (edit_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (edit_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
|
||||
item = gtk_separator_menu_item_new ();
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
|
||||
item = gtk_menu_item_new_with_label ("Cut");
|
||||
item = gtk_button_new_with_label ("Cut");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (cut_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_menu_item_new_with_label ("Copy");
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (cut_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_button_new_with_label ("Copy");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (copy_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_menu_item_new_with_label ("Paste");
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (copy_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_button_new_with_label ("Paste");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
|
||||
gtk_widget_set_sensitive (item,
|
||||
gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_DEMO_WIDGET));
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (paste_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_menu_item_new_with_label ("Delete");
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (paste_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_button_new_with_label ("Delete");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (delete_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (delete_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = 0;
|
||||
rect.height = 0;
|
||||
|
||||
gtk_menu_popup_at_rect (GTK_MENU (menu),
|
||||
gtk_native_get_surface (gtk_widget_get_native (widget)),
|
||||
&rect,
|
||||
GDK_GRAVITY_NORTH_WEST,
|
||||
GDK_GRAVITY_NORTH_WEST,
|
||||
NULL);
|
||||
|
||||
return;
|
||||
gtk_popover_popup (GTK_POPOVER (menu));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +341,7 @@ released_cb (GtkGesture *gesture,
|
||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
if (child != NULL && child != widget)
|
||||
edit_cb (child);
|
||||
edit_cb (NULL, child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1228,7 +1228,7 @@ do_font_features (GtkWidget *do_widget)
|
||||
edit_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "edit_toggle"));
|
||||
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_object_set_data_full (G_OBJECT (entry), "controller", controller, g_object_unref);
|
||||
g_object_set_data_full (G_OBJECT (entry), "controller", g_object_ref (controller), g_object_unref);
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), entry);
|
||||
gtk_widget_add_controller (entry, controller);
|
||||
|
||||
@@ -1337,6 +1337,8 @@ do_font_features (GtkWidget *do_widget)
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
g_object_unref (builder);
|
||||
|
||||
update_display ();
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -414,7 +414,7 @@ draw_menubar (GtkWidget *widget,
|
||||
frame_context = get_style (NULL, "frame");
|
||||
border_context = get_style (frame_context, "border");
|
||||
|
||||
/* This information is taken from the GtkMenuBar docs, see "CSS nodes" */
|
||||
/* This information is taken from the GtkPopoverMenuBar docs, see "CSS nodes" */
|
||||
menubar_context = get_style (NULL, "menubar");
|
||||
hovered_menuitem_context = get_style (menubar_context, "menuitem:hover");
|
||||
menuitem_context = get_style (menubar_context, "menuitem");
|
||||
|
||||
+11
-15
@@ -1,19 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface domain="gtk40">
|
||||
<object class="GtkMenu" id="menu1">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem1">
|
||||
<property name="label" translatable="yes">Email message</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem2">
|
||||
<property name="label" translatable="yes">Embed message</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<menu id="menu1">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Email message</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Embed message</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<template class="GtkMessageRow" parent="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid1">
|
||||
@@ -171,7 +167,7 @@
|
||||
<object class="GtkMenuButton" id="more-button">
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="popup">menu1</property>
|
||||
<property name="menu-model">menu1</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="label" translatable="yes">More...</property>
|
||||
</object>
|
||||
|
||||
@@ -1003,32 +1003,6 @@ row_activated_cb (GtkWidget *tree_view,
|
||||
run_example_for_row (window, model, &iter);
|
||||
}
|
||||
|
||||
static void
|
||||
start_cb (GtkMenuItem *item, GtkWidget *scrollbar)
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
|
||||
adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (scrollbar));
|
||||
gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
|
||||
}
|
||||
|
||||
static void
|
||||
end_cb (GtkMenuItem *item, GtkWidget *scrollbar)
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
|
||||
adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (scrollbar));
|
||||
gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
scrollbar_popup (GtkWidget *scrollbar, GtkWidget *menu)
|
||||
{
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
activate (GApplication *app)
|
||||
{
|
||||
@@ -1037,10 +1011,6 @@ activate (GApplication *app)
|
||||
GtkWidget *widget;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *scrollbar;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *item;
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "run", activate_run, NULL, NULL, NULL }
|
||||
@@ -1062,21 +1032,6 @@ activate (GApplication *app)
|
||||
treeview = (GtkWidget *)gtk_builder_get_object (builder, "treeview");
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
|
||||
|
||||
sw = (GtkWidget *)gtk_builder_get_object (builder, "source-scrolledwindow");
|
||||
scrollbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (sw));
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
|
||||
item = gtk_menu_item_new_with_label ("Start");
|
||||
g_signal_connect (item, "activate", G_CALLBACK (start_cb), scrollbar);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||
|
||||
item = gtk_menu_item_new_with_label ("End");
|
||||
g_signal_connect (item, "activate", G_CALLBACK (end_cb), scrollbar);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||
|
||||
g_signal_connect (scrollbar, "popup-menu", G_CALLBACK (scrollbar_popup), menu);
|
||||
|
||||
load_file (gtk_demos[0].name, gtk_demos[0].filename);
|
||||
|
||||
populate_model (model);
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
/* Menus
|
||||
*
|
||||
* There are several widgets involved in displaying menus. The
|
||||
* GtkMenuBar widget is a menu bar, which normally appears horizontally
|
||||
* at the top of an application, but can also be layed out vertically.
|
||||
* The GtkMenu widget is the actual menu that pops up. Both GtkMenuBar
|
||||
* and GtkMenu are subclasses of GtkMenuShell; a GtkMenuShell contains
|
||||
* menu items (GtkMenuItem). Each menu item contains text and/or images
|
||||
* and can be selected by the user.
|
||||
*
|
||||
* There are several kinds of menu item, including plain GtkMenuItem,
|
||||
* GtkCheckMenuItem which can be checked/unchecked, GtkRadioMenuItem
|
||||
* which is a check menu item that's in a mutually exclusive group,
|
||||
* GtkSeparatorMenuItem which is a separator bar, GtkTearoffMenuItem
|
||||
* which allows a GtkMenu to be torn off, and GtkImageMenuItem which
|
||||
* can place a GtkImage or other widget next to the menu text.
|
||||
*
|
||||
* A GtkMenuItem can have a submenu, which is simply a GtkMenu to pop
|
||||
* up when the menu item is selected. Typically, all menu items in a menu bar
|
||||
* have submenus.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static GtkWidget *
|
||||
create_menu (gint depth)
|
||||
{
|
||||
GtkWidget *menu;
|
||||
GtkRadioMenuItem *last_item;
|
||||
char buf[32];
|
||||
int i, j;
|
||||
|
||||
if (depth < 1)
|
||||
return NULL;
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
last_item = NULL;
|
||||
|
||||
for (i = 0, j = 1; i < 5; i++, j++)
|
||||
{
|
||||
GtkWidget *menu_item;
|
||||
|
||||
sprintf (buf, "item %2d - %d", depth, j);
|
||||
|
||||
menu_item = gtk_radio_menu_item_new_with_label_from_widget (NULL, buf);
|
||||
gtk_radio_menu_item_join_group (GTK_RADIO_MENU_ITEM (menu_item), last_item);
|
||||
last_item = GTK_RADIO_MENU_ITEM (menu_item);
|
||||
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
|
||||
gtk_widget_show (menu_item);
|
||||
if (i == 3)
|
||||
gtk_widget_set_sensitive (menu_item, FALSE);
|
||||
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), create_menu (depth - 1));
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
static void
|
||||
change_orientation (GtkWidget *button,
|
||||
GtkWidget *menubar)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
GtkOrientation orientation;
|
||||
|
||||
parent = gtk_widget_get_parent (menubar);
|
||||
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (parent));
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (parent), 1 - orientation);
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
do_menus (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *box1;
|
||||
GtkWidget *box2;
|
||||
GtkWidget *button;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *menubar;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *menuitem;
|
||||
GtkAccelGroup *accel_group;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Menus");
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK(gtk_widget_destroyed), &window);
|
||||
|
||||
accel_group = gtk_accel_group_new ();
|
||||
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (box), box1);
|
||||
|
||||
menubar = gtk_menu_bar_new ();
|
||||
gtk_widget_set_hexpand (menubar, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box1), menubar);
|
||||
|
||||
menu = create_menu (2);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("test\nline2");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("foo");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("bar");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_container_add (GTK_CONTAINER (box1), box2);
|
||||
|
||||
button = gtk_button_new_with_label ("Flip");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (change_orientation), menubar);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK(gtk_widget_destroy), window);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
gtk_window_set_default_widget (GTK_WINDOW (window), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -4,7 +4,6 @@ demos = files([
|
||||
'application_demo.c',
|
||||
'assistant.c',
|
||||
'builder.c',
|
||||
'changedisplay.c',
|
||||
'clipboard.c',
|
||||
'colorsel.c',
|
||||
'combobox.c',
|
||||
@@ -44,7 +43,6 @@ demos = files([
|
||||
'flowbox.c',
|
||||
'list_store.c',
|
||||
'markup.c',
|
||||
'menus.c',
|
||||
'modelbutton.c',
|
||||
'overlay.c',
|
||||
'overlay2.c',
|
||||
|
||||
@@ -1053,27 +1053,6 @@ row_activated (GtkListBox *box, GtkListBoxRow *row)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_accel (GtkApplication *app, GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *accel_label;
|
||||
const gchar *action;
|
||||
gchar **accels;
|
||||
guint key;
|
||||
GdkModifierType mods;
|
||||
|
||||
accel_label = gtk_bin_get_child (GTK_BIN (widget));
|
||||
g_assert (GTK_IS_ACCEL_LABEL (accel_label));
|
||||
|
||||
action = gtk_actionable_get_action_name (GTK_ACTIONABLE (widget));
|
||||
accels = gtk_application_get_accels_for_action (app, action);
|
||||
|
||||
gtk_accelerator_parse (accels[0], &key, &mods);
|
||||
gtk_accel_label_set_accel (GTK_ACCEL_LABEL (accel_label), key, mods);
|
||||
|
||||
g_strfreev (accels);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkTextView tv;
|
||||
@@ -1863,13 +1842,6 @@ activate (GApplication *app)
|
||||
g_object_set_data (G_OBJECT (widget2), "range_to_spin", widget3);
|
||||
g_object_set_data (G_OBJECT (widget), "print_button", widget4);
|
||||
|
||||
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "quitmenuitem")));
|
||||
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "deletemenuitem")));
|
||||
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "searchmenuitem")));
|
||||
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "darkmenuitem")));
|
||||
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "aboutmenuitem")));
|
||||
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "bgmenuitem")));
|
||||
|
||||
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "tooltextview");
|
||||
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "toolbutton1");
|
||||
|
||||
@@ -1500,6 +1500,10 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="value">.5</property>
|
||||
<property name="halign">center</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1515,6 +1519,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<signal name="query-tooltip" handler="on_scale_button_query_tooltip" swapped="no"/>
|
||||
<signal name="value-changed" handler="on_scale_button_value_changed" swapped="no"/>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
@@ -1809,260 +1814,6 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="menu-model">menu_bar_model</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuBar">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem1">
|
||||
<property name="label" translatable="yes">File</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu1">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem101">
|
||||
<property name="label" translatable="yes">_New</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem102">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem103">
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem104">
|
||||
<property name="label" translatable="yes">Save _As</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="separatormenuitem1"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="quitmenuitem">
|
||||
<property name="label" translatable="yes">_Quit</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">app.quit</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem2">
|
||||
<property name="label" translatable="yes">Edit</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu2">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem106">
|
||||
<property name="label" translatable="yes">Cu_t</property>
|
||||
<property name="can-focus">1</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem107">
|
||||
<property name="label" translatable="yes">_Copy</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem108">
|
||||
<property name="label" translatable="yes">_Paste</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="deletemenuitem">
|
||||
<property name="label" translatable="yes">_Delete</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.delete</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="searchmenuitem">
|
||||
<property name="label" translatable="yes">_Search</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.search</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="checksmenuitem">
|
||||
<property name="label">_Checks</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="checkssubmenu">
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="checkmenuitem1">
|
||||
<property name="label">_Check</property>
|
||||
<property name="active">1</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="checkmenuitem2">
|
||||
<property name="label">_Check</property>
|
||||
<property name="active">1</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="checkmenuitem3">
|
||||
<property name="label">_Check</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="checkmenuitem4">
|
||||
<property name="label">_Check</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="checkmenuitem5">
|
||||
<property name="label">_Check</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="checkmenuitem6">
|
||||
<property name="label">_Check</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="radiosmenuitem">
|
||||
<property name="label">_Radios</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="radiossubmenu">
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="radiomenuitem1">
|
||||
<property name="label">_Radio</property>
|
||||
<property name="active">1</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="radiomenuitem2">
|
||||
<property name="label">_Radio</property>
|
||||
<property name="active">1</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="radiomenuitem3">
|
||||
<property name="label">_Radio</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="radiomenuitem4">
|
||||
<property name="label">_Radio</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="radiomenuitem5">
|
||||
<property name="label">_Radio</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="radiomenuitem6">
|
||||
<property name="label">_Radio</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem3">
|
||||
<property name="label" translatable="yes">View</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="view-menu">
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="darkmenuitem">
|
||||
<property name="label">_Dark theme</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.dark</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="toolbarmenuitem">
|
||||
<property name="label">_Toolbar</property>
|
||||
<property name="active">1</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.toolbar</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="statusbarmenuitem">
|
||||
<property name="label">_Statusbar</property>
|
||||
<property name="active">1</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.statusbar</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="bgmenuitem">
|
||||
<property name="label">_Select Background</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.background</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem4">
|
||||
<property name="label" translatable="yes">Help</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu3">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="aboutmenuitem">
|
||||
<property name="label" translatable="yes">_About</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">app.about</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolbar" id="toolbar">
|
||||
<child>
|
||||
|
||||
@@ -544,8 +544,6 @@ GdkSeatCapabilities
|
||||
GdkGrabStatus
|
||||
GdkSeatGrabPrepareFunc
|
||||
gdk_seat_get_display
|
||||
gdk_seat_grab
|
||||
gdk_seat_ungrab
|
||||
gdk_seat_get_capabilities
|
||||
gdk_seat_get_pointer
|
||||
gdk_seat_get_keyboard
|
||||
|
||||
@@ -30,6 +30,7 @@ GskRenderNodeType
|
||||
gsk_render_node_get_node_type
|
||||
gsk_render_node_draw
|
||||
GskSerializationError
|
||||
GskParseErrorFunc
|
||||
gsk_render_node_serialize
|
||||
gsk_render_node_deserialize
|
||||
gsk_render_node_write_to_file
|
||||
|
||||
@@ -314,8 +314,8 @@
|
||||
be connected to an action just by setting the ::action-name
|
||||
property. If the action has a parameter, you will also need
|
||||
to set the ::action-target property.
|
||||
Widgets that implement GtkAction include GtkSwitch, GtkButton,
|
||||
GtkMenuItem and their respective subclasses.
|
||||
Widgets that implement GtkActionable include GtkSwitch, GtkButton,
|
||||
and their respective subclasses.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
||||
@@ -217,12 +217,6 @@
|
||||
<title>Menus, Combo Box, Toolbar</title>
|
||||
<xi:include href="xml/gtkcombobox.xml" />
|
||||
<xi:include href="xml/gtkcomboboxtext.xml" />
|
||||
<xi:include href="xml/gtkmenu.xml" />
|
||||
<xi:include href="xml/gtkmenubar.xml" />
|
||||
<xi:include href="xml/gtkmenuitem.xml" />
|
||||
<xi:include href="xml/gtkradiomenuitem.xml" />
|
||||
<xi:include href="xml/gtkcheckmenuitem.xml" />
|
||||
<xi:include href="xml/gtkseparatormenuitem.xml" />
|
||||
<xi:include href="xml/gtktoolshell.xml" />
|
||||
<xi:include href="xml/gtktoolbar.xml" />
|
||||
<xi:include href="xml/gtktoolitem.xml" />
|
||||
@@ -311,7 +305,6 @@
|
||||
<xi:include href="xml/gtkwidget.xml" />
|
||||
<xi:include href="xml/gtkcontainer.xml" />
|
||||
<xi:include href="xml/gtkbin.xml" />
|
||||
<xi:include href="xml/gtkmenushell.xml" />
|
||||
<xi:include href="xml/gtkrange.xml" />
|
||||
<xi:include href="xml/gtkimcontext.xml" />
|
||||
<xi:include href="xml/gtknativedialog.xml" />
|
||||
|
||||
@@ -674,34 +674,6 @@ GTK_CHECK_BUTTON_GET_CLASS
|
||||
gtk_check_button_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkcheckmenuitem</FILE>
|
||||
GtkCheckMenuItem
|
||||
GtkCheckMenuItemClass
|
||||
<TITLE>GtkCheckMenuItem</TITLE>
|
||||
gtk_check_menu_item_new
|
||||
gtk_check_menu_item_new_with_label
|
||||
gtk_check_menu_item_new_with_mnemonic
|
||||
gtk_check_menu_item_get_active
|
||||
gtk_check_menu_item_set_active
|
||||
gtk_check_menu_item_toggled
|
||||
gtk_check_menu_item_get_inconsistent
|
||||
gtk_check_menu_item_set_inconsistent
|
||||
gtk_check_menu_item_set_draw_as_radio
|
||||
gtk_check_menu_item_get_draw_as_radio
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_CHECK_MENU_ITEM
|
||||
GTK_IS_CHECK_MENU_ITEM
|
||||
GTK_TYPE_CHECK_MENU_ITEM
|
||||
GTK_CHECK_MENU_ITEM_CLASS
|
||||
GTK_IS_CHECK_MENU_ITEM_CLASS
|
||||
GTK_CHECK_MENU_ITEM_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkCheckMenuItemPrivate
|
||||
gtk_check_menu_item_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkcolorbutton</FILE>
|
||||
<TITLE>GtkColorButton</TITLE>
|
||||
@@ -1830,79 +1802,15 @@ GTK_MAP_LIST_MODEL_GET_CLASS
|
||||
gtk_map_list_model_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmenu</FILE>
|
||||
<TITLE>GtkMenu</TITLE>
|
||||
GtkMenu
|
||||
gtk_menu_new
|
||||
gtk_menu_new_from_model
|
||||
GtkPopoverMenuFlags
|
||||
gtk_menu_reorder_child
|
||||
gtk_menu_popup_at_rect
|
||||
gtk_menu_popup_at_widget
|
||||
gtk_menu_popup_at_pointer
|
||||
gtk_menu_set_accel_group
|
||||
gtk_menu_get_accel_group
|
||||
gtk_menu_set_accel_path
|
||||
gtk_menu_get_accel_path
|
||||
gtk_menu_set_monitor
|
||||
gtk_menu_get_monitor
|
||||
gtk_menu_place_on_monitor
|
||||
gtk_menu_set_reserve_toggle_size
|
||||
gtk_menu_get_reserve_toggle_size
|
||||
<SUBSECTION>
|
||||
gtk_menu_popdown
|
||||
gtk_menu_reposition
|
||||
gtk_menu_get_active
|
||||
gtk_menu_set_active
|
||||
gtk_menu_attach_to_widget
|
||||
gtk_menu_detach
|
||||
gtk_menu_get_attach_widget
|
||||
gtk_menu_get_for_attach_widget
|
||||
GtkMenuDetachFunc
|
||||
<SUBSECTION Standard>
|
||||
GTK_MENU
|
||||
GTK_IS_MENU
|
||||
GTK_TYPE_MENU
|
||||
GTK_MENU_CLASS
|
||||
GTK_IS_MENU_CLASS
|
||||
GTK_MENU_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkMenuPrivate
|
||||
gtk_menu_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmenubar</FILE>
|
||||
<TITLE>GtkMenuBar</TITLE>
|
||||
GtkMenuBar
|
||||
gtk_menu_bar_new
|
||||
gtk_menu_bar_new_from_model
|
||||
<SUBSECTION Standard>
|
||||
GTK_MENU_BAR
|
||||
GTK_IS_MENU_BAR
|
||||
GTK_TYPE_MENU_BAR
|
||||
GTK_MENU_BAR_CLASS
|
||||
GTK_IS_MENU_BAR_CLASS
|
||||
GTK_MENU_BAR_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkMenuBarPrivate
|
||||
gtk_menu_bar_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmenubutton</FILE>
|
||||
<TITLE>GtkMenuButton</TITLE>
|
||||
GtkMenuButton
|
||||
gtk_menu_button_new
|
||||
gtk_menu_button_set_popup
|
||||
gtk_menu_button_get_popup
|
||||
gtk_menu_button_set_popover
|
||||
gtk_menu_button_get_popover
|
||||
gtk_menu_button_set_menu_model
|
||||
gtk_menu_button_get_menu_model
|
||||
gtk_menu_button_set_use_popover
|
||||
gtk_menu_button_get_use_popover
|
||||
GtkArrowType
|
||||
gtk_menu_button_set_direction
|
||||
gtk_menu_button_get_direction
|
||||
@@ -1916,6 +1824,7 @@ gtk_menu_button_set_relief
|
||||
gtk_menu_button_get_relief
|
||||
gtk_menu_button_popup
|
||||
gtk_menu_button_popdown
|
||||
GtkMenuButtonCreatePopupFunc
|
||||
gtk_menu_button_set_create_popup_func
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_MENU_BUTTON
|
||||
@@ -1929,72 +1838,6 @@ GtkMenuButtonPrivate
|
||||
gtk_menu_button_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmenuitem</FILE>
|
||||
<TITLE>GtkMenuItem</TITLE>
|
||||
GtkMenuItem
|
||||
GtkMenuItemClass
|
||||
gtk_menu_item_new
|
||||
gtk_menu_item_new_with_label
|
||||
gtk_menu_item_new_with_mnemonic
|
||||
gtk_menu_item_get_label
|
||||
gtk_menu_item_set_label
|
||||
gtk_menu_item_get_use_underline
|
||||
gtk_menu_item_set_use_underline
|
||||
gtk_menu_item_set_submenu
|
||||
gtk_menu_item_get_submenu
|
||||
gtk_menu_item_set_accel_path
|
||||
gtk_menu_item_get_accel_path
|
||||
gtk_menu_item_select
|
||||
gtk_menu_item_deselect
|
||||
gtk_menu_item_activate
|
||||
gtk_menu_item_toggle_size_request
|
||||
gtk_menu_item_toggle_size_allocate
|
||||
gtk_menu_item_get_reserve_indicator
|
||||
gtk_menu_item_set_reserve_indicator
|
||||
<SUBSECTION Standard>
|
||||
GTK_MENU_ITEM
|
||||
GTK_IS_MENU_ITEM
|
||||
GTK_TYPE_MENU_ITEM
|
||||
GTK_MENU_ITEM_CLASS
|
||||
GTK_IS_MENU_ITEM_CLASS
|
||||
GTK_MENU_ITEM_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkMenuItemPrivate
|
||||
gtk_menu_item_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmenushell</FILE>
|
||||
<TITLE>GtkMenuShell</TITLE>
|
||||
GtkMenuShell
|
||||
gtk_menu_shell_append
|
||||
gtk_menu_shell_prepend
|
||||
gtk_menu_shell_insert
|
||||
gtk_menu_shell_deactivate
|
||||
gtk_menu_shell_select_item
|
||||
gtk_menu_shell_select_first
|
||||
gtk_menu_shell_deselect
|
||||
gtk_menu_shell_activate_item
|
||||
gtk_menu_shell_cancel
|
||||
gtk_menu_shell_set_take_focus
|
||||
gtk_menu_shell_get_take_focus
|
||||
gtk_menu_shell_get_selected_item
|
||||
gtk_menu_shell_get_parent_shell
|
||||
gtk_menu_shell_bind_model
|
||||
GtkMenuDirectionType
|
||||
<SUBSECTION Standard>
|
||||
GTK_MENU_SHELL
|
||||
GTK_IS_MENU_SHELL
|
||||
GTK_TYPE_MENU_SHELL
|
||||
GTK_MENU_SHELL_CLASS
|
||||
GTK_IS_MENU_SHELL_CLASS
|
||||
GTK_MENU_SHELL_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkMenuShellPrivate
|
||||
gtk_menu_shell_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmessagedialog</FILE>
|
||||
<TITLE>GtkMessageDialog</TITLE>
|
||||
@@ -2257,31 +2100,6 @@ GtkRadioButtonPrivate
|
||||
gtk_radio_button_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkradiomenuitem</FILE>
|
||||
<TITLE>GtkRadioMenuItem</TITLE>
|
||||
GtkRadioMenuItem
|
||||
gtk_radio_menu_item_new
|
||||
gtk_radio_menu_item_new_with_label
|
||||
gtk_radio_menu_item_new_with_mnemonic
|
||||
gtk_radio_menu_item_new_from_widget
|
||||
gtk_radio_menu_item_new_with_label_from_widget
|
||||
gtk_radio_menu_item_new_with_mnemonic_from_widget
|
||||
gtk_radio_menu_item_set_group
|
||||
gtk_radio_menu_item_get_group
|
||||
gtk_radio_menu_item_join_group
|
||||
<SUBSECTION Standard>
|
||||
GTK_RADIO_MENU_ITEM
|
||||
GTK_IS_RADIO_MENU_ITEM
|
||||
GTK_TYPE_RADIO_MENU_ITEM
|
||||
GTK_RADIO_MENU_ITEM_CLASS
|
||||
GTK_IS_RADIO_MENU_ITEM_CLASS
|
||||
GTK_RADIO_MENU_ITEM_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkRadioMenuItemPrivate
|
||||
gtk_radio_menu_item_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkrange</FILE>
|
||||
<TITLE>GtkRange</TITLE>
|
||||
@@ -2588,22 +2406,6 @@ gtk_separator_get_type
|
||||
GtkSeparatorPrivate
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkseparatormenuitem</FILE>
|
||||
<TITLE>GtkSeparatorMenuItem</TITLE>
|
||||
GtkSeparatorMenuItem
|
||||
gtk_separator_menu_item_new
|
||||
<SUBSECTION Standard>
|
||||
GTK_SEPARATOR_MENU_ITEM
|
||||
GTK_SEPARATOR_MENU_ITEM_CLASS
|
||||
GTK_SEPARATOR_MENU_ITEM_GET_CLASS
|
||||
GTK_IS_SEPARATOR_MENU_ITEM
|
||||
GTK_IS_SEPARATOR_MENU_ITEM_CLASS
|
||||
GTK_TYPE_SEPARATOR_MENU_ITEM
|
||||
<SUBSECTION Private>
|
||||
gtk_separator_menu_item_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtksettings</FILE>
|
||||
<TITLE>GtkSettings</TITLE>
|
||||
@@ -3278,9 +3080,8 @@ gtk_tool_item_get_orientation
|
||||
gtk_tool_item_get_toolbar_style
|
||||
gtk_tool_item_get_text_alignment
|
||||
gtk_tool_item_get_text_orientation
|
||||
gtk_tool_item_retrieve_proxy_menu_item
|
||||
gtk_tool_item_get_proxy_menu_item
|
||||
gtk_tool_item_set_proxy_menu_item
|
||||
gtk_tool_item_set_overflow_text
|
||||
gtk_tool_item_get_overflow_text
|
||||
gtk_tool_item_rebuild_menu
|
||||
gtk_tool_item_toolbar_reconfigured
|
||||
gtk_tool_item_get_text_size_group
|
||||
@@ -3354,8 +3155,8 @@ GtkToolButtonPrivate
|
||||
<TITLE>GtkMenuToolButton</TITLE>
|
||||
GtkMenuToolButton
|
||||
gtk_menu_tool_button_new
|
||||
gtk_menu_tool_button_set_menu
|
||||
gtk_menu_tool_button_get_menu
|
||||
gtk_menu_tool_button_set_popover
|
||||
gtk_menu_tool_button_get_popover
|
||||
gtk_menu_tool_button_set_arrow_tooltip_text
|
||||
gtk_menu_tool_button_set_arrow_tooltip_markup
|
||||
|
||||
@@ -3898,9 +3699,6 @@ gtk_tree_view_get_search_equal_func
|
||||
gtk_tree_view_set_search_equal_func
|
||||
gtk_tree_view_get_search_entry
|
||||
gtk_tree_view_set_search_entry
|
||||
GtkTreeViewSearchPositionFunc
|
||||
gtk_tree_view_get_search_position_func
|
||||
gtk_tree_view_set_search_position_func
|
||||
gtk_tree_view_get_fixed_height_mode
|
||||
gtk_tree_view_set_fixed_height_mode
|
||||
gtk_tree_view_get_hover_selection
|
||||
|
||||
@@ -44,7 +44,6 @@ gtk_cell_renderer_text_get_type
|
||||
gtk_cell_renderer_toggle_get_type
|
||||
gtk_cell_view_get_type
|
||||
gtk_check_button_get_type
|
||||
gtk_check_menu_item_get_type
|
||||
gtk_color_button_get_type
|
||||
gtk_color_chooser_get_type
|
||||
gtk_color_chooser_dialog_get_type
|
||||
@@ -119,11 +118,7 @@ gtk_map_list_model_get_type
|
||||
gtk_media_controls_get_type
|
||||
gtk_media_file_get_type
|
||||
gtk_media_stream_get_type
|
||||
gtk_menu_bar_get_type
|
||||
gtk_menu_button_get_type
|
||||
gtk_menu_get_type
|
||||
gtk_menu_item_get_type
|
||||
gtk_menu_shell_get_type
|
||||
gtk_menu_tool_button_get_type
|
||||
gtk_message_dialog_get_type
|
||||
gtk_mount_operation_get_type
|
||||
@@ -152,7 +147,6 @@ gtk_print_settings_get_type
|
||||
@DISABLE_ON_W32@gtk_print_unix_dialog_get_type
|
||||
gtk_progress_bar_get_type
|
||||
gtk_radio_button_get_type
|
||||
gtk_radio_menu_item_get_type
|
||||
gtk_radio_tool_button_get_type
|
||||
gtk_range_get_type
|
||||
gtk_recent_manager_get_type
|
||||
@@ -167,7 +161,6 @@ gtk_search_bar_get_type
|
||||
gtk_search_entry_get_type
|
||||
gtk_selection_model_get_type
|
||||
gtk_separator_get_type
|
||||
gtk_separator_menu_item_get_type
|
||||
gtk_separator_tool_item_get_type
|
||||
gtk_settings_get_type
|
||||
gtk_shortcut_label_get_type
|
||||
@@ -206,7 +199,6 @@ gtk_tool_button_get_type
|
||||
gtk_tool_item_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_model_filter_get_type
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
private_headers = [
|
||||
'imm-extra.h',
|
||||
'gtkbitmaskprivateimpl.h',
|
||||
'gdkpixbufutilsprivate.h',
|
||||
'gtkaccelgroupprivate.h',
|
||||
'gtkaccelmapprivate.h',
|
||||
@@ -15,7 +17,6 @@ private_headers = [
|
||||
'gtkbuttonprivate.h',
|
||||
'gtkcellareaboxcontextprivate.h',
|
||||
'gtkcheckbuttonprivate.h',
|
||||
'gtkcheckmenuitemprivate.h',
|
||||
'gtkcolorchooserprivate.h',
|
||||
'gtkcoloreditorprivate.h',
|
||||
'gtkcolorplaneprivate.h',
|
||||
@@ -35,6 +36,7 @@ private_headers = [
|
||||
'gtkcssarrayvalueprivate.h',
|
||||
'gtkcssbgsizevalueprivate.h',
|
||||
'gtkcssbordervalueprivate.h',
|
||||
'gtkcssboxesprivate.h',
|
||||
'gtkcsscalcvalueprivate.h',
|
||||
'gtkcsscolorvalueprivate.h',
|
||||
'gtkcsscornervalueprivate.h',
|
||||
@@ -135,9 +137,6 @@ private_headers = [
|
||||
'gtkmagnifierprivate.h',
|
||||
'gtkmediafileprivate.h',
|
||||
'gtkmenubuttonprivate.h',
|
||||
'gtkmenuitemprivate.h',
|
||||
'gtkmenuprivate.h',
|
||||
'gtkmenushellprivate.h',
|
||||
'gtkmodulesprivate.h',
|
||||
'gtkmountoperationprivate.h',
|
||||
'gtknativedialogprivate.h',
|
||||
|
||||
@@ -305,6 +305,18 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using grabs</title>
|
||||
<para>
|
||||
GTK 4 no longer provides the gdk_device_grab() or gdk_seat_grab() apis.
|
||||
</para>
|
||||
<para>
|
||||
If you need to dismiss a popup when the user clicks outside (a common
|
||||
use for grabs), you can use the GdkSurface #GdkSurface:autohide property instead.
|
||||
GtkPopover also has a #GtkPopover:autohide property.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to coordinate API changes</title>
|
||||
<para>
|
||||
@@ -673,7 +685,7 @@
|
||||
<section>
|
||||
<title>Adapt to changes in the API of GtkEntry, GtkSearchEntry and GtkSpinButton</title>
|
||||
<para>
|
||||
The GtkEditable has been made more useful, and the core functionality of
|
||||
The GtkEditable interface has been made more useful, and the core functionality of
|
||||
GtkEntry has been broken out as a GtkText widget. GtkEntry, GtkSearchEntry,
|
||||
GtkSpinButton and the new GtkPasswordEntry now use a GtkText widget internally
|
||||
and implement GtkEditable. In particular, this means that it is no longer
|
||||
@@ -851,6 +863,46 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>GtkMenu, GtkMenuBar and GtkMenuItem are gone</title>
|
||||
<para>
|
||||
These widgets were heavily relying on X11-centric concepts such as
|
||||
override-redirect windows and grabs, and were hard to adjust to other
|
||||
windowing systems.
|
||||
</para>
|
||||
<para>
|
||||
Menus can already be replaced using GtkPopoverMenu in GTK 3. Additionally,
|
||||
GTK 4 introduces GtkPopoverMenuBar to replace menubars. These new widgets
|
||||
can only be constructed from menu models, so the porting effort involves
|
||||
switching to menu models and actions.
|
||||
</para>
|
||||
<para>
|
||||
Since menus are gone, GtkMenuButton and GtkMenuToolButton also lost their
|
||||
ability to show menus, and need to be used with popovers in GTK 4.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>GtkToolbar overflow handling has changed</title>
|
||||
<para>
|
||||
The handling of overflow in toolbars has been simplified.
|
||||
Instead of creating a proxy menuitem and setting it with
|
||||
gtk_tool_item_set_proxy_menu_item(), you simply provide
|
||||
a label for the overflow menu with gtk_tool_item_set_overflow_text().
|
||||
GTK will figure out itself whether to create a check- or
|
||||
radioitem as proxy.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Stop using custom tooltip windows</title>
|
||||
<para>
|
||||
Tooltips no longer use GtkWindows in GTK 4, and it is no longer
|
||||
possible to provide a custom window for tooltips. Replacing the content
|
||||
of the tooltip with a custom widget is still possible, with
|
||||
gtk_tooltip_set_custom().
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -162,9 +162,6 @@
|
||||
<link linkend="GtkPaned">
|
||||
<inlinegraphic fileref="panes.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkMenuBar">
|
||||
<inlinegraphic fileref="menubar.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkToolbar">
|
||||
<inlinegraphic fileref="toolbar.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
|
||||
+2
-29
@@ -152,8 +152,8 @@ create_menu_button (void)
|
||||
image = gtk_image_new ();
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (image), "emblem-system-symbolic");
|
||||
gtk_container_add (GTK_CONTAINER (widget), image);
|
||||
menu = gtk_menu_new ();
|
||||
gtk_menu_button_set_popup (GTK_MENU_BUTTON (widget), menu);
|
||||
menu = gtk_popover_new (NULL);
|
||||
gtk_menu_button_set_popover (GTK_MENU_BUTTON (widget), menu);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), widget);
|
||||
@@ -800,32 +800,6 @@ create_toolbar (void)
|
||||
return new_widget_info ("toolbar", widget, SMALL);
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_menubar (void)
|
||||
{
|
||||
GtkWidget *widget, *vbox, *item;
|
||||
|
||||
widget = gtk_menu_bar_new ();
|
||||
|
||||
item = gtk_menu_item_new_with_mnemonic ("_File");
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (widget), item);
|
||||
|
||||
item = gtk_menu_item_new_with_mnemonic ("_Edit");
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (widget), item);
|
||||
|
||||
item = gtk_menu_item_new_with_mnemonic ("_Help");
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (widget), item);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
|
||||
gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), widget);
|
||||
gtk_container_add (GTK_CONTAINER (vbox),
|
||||
gtk_label_new ("Menu Bar"));
|
||||
|
||||
return new_widget_info ("menubar", vbox, SMALL);
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_message_dialog (void)
|
||||
{
|
||||
@@ -1438,7 +1412,6 @@ get_all_widgets (void)
|
||||
retval = g_list_prepend (retval, create_image ());
|
||||
retval = g_list_prepend (retval, create_label ());
|
||||
retval = g_list_prepend (retval, create_link_button ());
|
||||
retval = g_list_prepend (retval, create_menubar ());
|
||||
retval = g_list_prepend (retval, create_message_dialog ());
|
||||
retval = g_list_prepend (retval, create_notebook ());
|
||||
retval = g_list_prepend (retval, create_panes ());
|
||||
|
||||
@@ -24,8 +24,21 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
|
||||
#include <gio/gunixfdlist.h>
|
||||
|
||||
#ifndef O_PATH
|
||||
#define O_PATH 0
|
||||
#endif
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#else
|
||||
#define HAVE_O_CLOEXEC 1
|
||||
#endif
|
||||
|
||||
#include "filetransferportalprivate.h"
|
||||
|
||||
static GDBusProxy *file_transfer_proxy = NULL;
|
||||
@@ -158,6 +171,10 @@ add_files (GDBusProxy *proxy,
|
||||
g_object_unref (fd_list);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef HAVE_O_CLOEXEC
|
||||
fcntl (fd, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
fd_in = g_unix_fd_list_append (fd_list, fd, &error);
|
||||
close (fd);
|
||||
|
||||
@@ -339,3 +356,5 @@ file_transfer_portal_retrieve_files_finish (GAsyncResult *result,
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* G_OS_UNIX */
|
||||
|
||||
@@ -14,7 +14,6 @@ G_BEGIN_DECLS
|
||||
#mesondefine GDK_WINDOWING_BROADWAY
|
||||
#mesondefine GDK_WINDOWING_WAYLAND
|
||||
#mesondefine GDK_WINDOWING_WIN32
|
||||
#mesondefine GDK_WINDOWING_MIR
|
||||
|
||||
#mesondefine GDK_RENDERING_VULKAN
|
||||
|
||||
|
||||
@@ -691,6 +691,7 @@ string_deserializer (GdkContentDeserializer *deserializer)
|
||||
g_object_unref (filter);
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static void
|
||||
portal_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
@@ -777,6 +778,7 @@ portal_file_deserializer (GdkContentDeserializer *deserializer)
|
||||
deserializer);
|
||||
g_object_unref (output);
|
||||
}
|
||||
#endif /* G_OS_UNIX */
|
||||
|
||||
static void
|
||||
file_uri_deserializer_finish (GObject *source,
|
||||
@@ -852,7 +854,6 @@ init (void)
|
||||
static gboolean initialized = FALSE;
|
||||
GSList *formats, *f;
|
||||
const char *charset;
|
||||
gboolean has_portal;
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
@@ -905,24 +906,31 @@ init (void)
|
||||
|
||||
g_slist_free (formats);
|
||||
|
||||
has_portal = file_transfer_portal_available ();
|
||||
#ifdef G_OS_UNIX
|
||||
gboolean has_portal = file_transfer_portal_available ();
|
||||
if (has_portal)
|
||||
gdk_content_register_deserializer ("application/vnd.portal.files",
|
||||
GDK_TYPE_FILE_LIST,
|
||||
portal_file_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
gdk_content_register_deserializer ("text/uri-list",
|
||||
GDK_TYPE_FILE_LIST,
|
||||
file_uri_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
if (has_portal)
|
||||
gdk_content_register_deserializer ("application/vnd.portal.files",
|
||||
G_TYPE_FILE,
|
||||
portal_file_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
gdk_content_register_deserializer ("text/uri-list",
|
||||
G_TYPE_FILE,
|
||||
file_uri_deserializer,
|
||||
|
||||
@@ -347,7 +347,7 @@ gdk_content_provider_write_mime_type_finish (GdkContentProvider *provider,
|
||||
* @error: a #GError location to store the error occurring, or %NULL to
|
||||
* ignore.
|
||||
*
|
||||
* Gets the convtents of @provider stored in @value.
|
||||
* Gets the contents of @provider stored in @value.
|
||||
*
|
||||
* The @value will have been initialized to the #GType the value should be
|
||||
* provided in. This given #GType does not need to be listed in the formats
|
||||
|
||||
@@ -432,7 +432,7 @@ lookup_serializer (const char *mime_type,
|
||||
|
||||
/**
|
||||
* gdk_content_formats_union_serialize_gtypes:
|
||||
* @formats: a #GdkContentFormats
|
||||
* @formats: (transfer full): a #GdkContentFormats
|
||||
*
|
||||
* Add GTypes for the mime types in @formats for which serializers are
|
||||
* registered.
|
||||
@@ -467,7 +467,7 @@ gdk_content_formats_union_serialize_gtypes (GdkContentFormats *formats)
|
||||
|
||||
/**
|
||||
* gdk_content_formats_union_serialize_mime_types:
|
||||
* @formats: a #GdkContentFormats
|
||||
* @formats: (transfer full): a #GdkContentFormats
|
||||
*
|
||||
* Add mime types for GTypes in @formats for which serializers are
|
||||
* registered.
|
||||
@@ -702,6 +702,7 @@ file_serializer_finish (GObject *source,
|
||||
gdk_content_serializer_return_success (serializer);
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static void
|
||||
portal_ready (GObject *object,
|
||||
GAsyncResult *result,
|
||||
@@ -758,6 +759,7 @@ portal_file_serializer (GdkContentSerializer *serializer)
|
||||
file_transfer_portal_register_files ((const char **)files->pdata, TRUE, portal_ready, serializer);
|
||||
gdk_content_serializer_set_task_data (serializer, files, (GDestroyNotify)g_ptr_array_unref);
|
||||
}
|
||||
#endif /* G_OS_UNIX */
|
||||
|
||||
static void
|
||||
file_uri_serializer (GdkContentSerializer *serializer)
|
||||
@@ -866,7 +868,6 @@ init (void)
|
||||
static gboolean initialized = FALSE;
|
||||
GSList *formats, *f;
|
||||
const char *charset;
|
||||
gboolean has_portal;
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
@@ -922,7 +923,8 @@ init (void)
|
||||
|
||||
g_slist_free (formats);
|
||||
|
||||
has_portal = file_transfer_portal_available ();
|
||||
#ifdef G_OS_UNIX
|
||||
gboolean has_portal = file_transfer_portal_available ();
|
||||
|
||||
if (has_portal)
|
||||
gdk_content_register_serializer (G_TYPE_FILE,
|
||||
@@ -930,6 +932,8 @@ init (void)
|
||||
portal_file_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
gdk_content_register_serializer (G_TYPE_FILE,
|
||||
"text/uri-list",
|
||||
file_uri_serializer,
|
||||
@@ -940,12 +944,16 @@ init (void)
|
||||
file_text_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
if (has_portal)
|
||||
gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
|
||||
"application/vnd.portal.files",
|
||||
portal_file_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
|
||||
"text/uri-list",
|
||||
file_uri_serializer,
|
||||
|
||||
+14
-1
@@ -448,7 +448,10 @@ gdk_drop_get_surface (GdkDrop *self)
|
||||
* Returns the possible actions for this #GdkDrop. If this value
|
||||
* contains multiple actions - ie gdk_drag_action_is_unique()
|
||||
* returns %FALSE for the result - gdk_drag_finish() must choose
|
||||
* the action to use when accepting the drop.
|
||||
* the action to use when accepting the drop. This will only
|
||||
* happen if you passed %GDK_ACTION_ASK as one of the possible
|
||||
* actions in gdk_drag_status(). %GDK_ACTION_ASK itself will not
|
||||
* be included in the actions returned by this function.
|
||||
*
|
||||
* This value may change over the lifetime of the #GdkDrop both
|
||||
* as a response to source side actions as well as to calls to
|
||||
@@ -938,6 +941,9 @@ gdk_drop_emit_motion_event (GdkDrop *self,
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
int x, y;
|
||||
|
||||
gdk_surface_get_origin (priv->surface, &x, &y);
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_MOTION);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
@@ -945,6 +951,8 @@ gdk_drop_emit_motion_event (GdkDrop *self,
|
||||
event->dnd.time = time;
|
||||
event->dnd.x_root = x_root;
|
||||
event->dnd.y_root = y_root;
|
||||
event->dnd.x = x_root - x;
|
||||
event->dnd.y = y_root - y;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
@@ -976,6 +984,9 @@ gdk_drop_emit_drop_event (GdkDrop *self,
|
||||
{
|
||||
GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
|
||||
GdkEvent *event;
|
||||
int x, y;
|
||||
|
||||
gdk_surface_get_origin (priv->surface, &x, &y);
|
||||
|
||||
event = gdk_event_new (GDK_DROP_START);
|
||||
event->any.surface = g_object_ref (priv->surface);
|
||||
@@ -983,6 +994,8 @@ gdk_drop_emit_drop_event (GdkDrop *self,
|
||||
event->dnd.time = time;
|
||||
event->dnd.x_root = x_root;
|
||||
event->dnd.y_root = y_root;
|
||||
event->dnd.x = x_root - x;
|
||||
event->dnd.y = y_root - y;
|
||||
gdk_event_set_device (event, priv->device);
|
||||
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
|
||||
@@ -947,6 +947,13 @@ gdk_event_get_coords (const GdkEvent *event,
|
||||
x = event->touchpad_pinch.x;
|
||||
y = event->touchpad_pinch.y;
|
||||
break;
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
x = event->dnd.x;
|
||||
y = event->dnd.y;
|
||||
break;
|
||||
default:
|
||||
fetched = FALSE;
|
||||
break;
|
||||
|
||||
@@ -418,7 +418,9 @@ struct _GdkEventDND {
|
||||
GdkDrop *drop;
|
||||
|
||||
guint32 time;
|
||||
gshort x_root, y_root;
|
||||
double x_root, y_root;
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+2
-1
@@ -955,7 +955,8 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
if (priv->use_es < 0)
|
||||
priv->use_es = !epoxy_is_desktop_gl ();
|
||||
|
||||
priv->has_debug_output = epoxy_has_gl_extension ("GL_ARB_debug_output");
|
||||
priv->has_debug_output = epoxy_has_gl_extension ("GL_ARB_debug_output") ||
|
||||
epoxy_has_gl_extension ("GL_KHR_debug");
|
||||
|
||||
#ifdef G_ENABLE_CONSISTENCY_CHECKS
|
||||
if (priv->has_debug_output)
|
||||
|
||||
@@ -266,6 +266,16 @@ void gdk_surface_get_geometry (GdkSurface *surface,
|
||||
|
||||
GdkGLContext *gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
|
||||
|
||||
GdkGrabStatus gdk_seat_grab (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
GdkSeatCapabilities capabilities,
|
||||
gboolean owner_events,
|
||||
GdkCursor *cursor,
|
||||
const GdkEvent *event,
|
||||
GdkSeatGrabPrepareFunc prepare_func,
|
||||
gpointer prepare_func_data);
|
||||
void gdk_seat_ungrab (GdkSeat *seat);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_INTERNALS_H__ */
|
||||
|
||||
+12
-9
@@ -100,7 +100,7 @@ gdk_rgba_free (GdkRGBA *rgba)
|
||||
gboolean
|
||||
gdk_rgba_is_clear (const GdkRGBA *rgba)
|
||||
{
|
||||
return rgba->alpha < ((double) 0x00ff / (double) 0xffff);
|
||||
return rgba->alpha < ((float) 0x00ff / (float) 0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +115,7 @@ gdk_rgba_is_clear (const GdkRGBA *rgba)
|
||||
gboolean
|
||||
gdk_rgba_is_opaque (const GdkRGBA *rgba)
|
||||
{
|
||||
return rgba->alpha > ((double)0xff00 / (double)0xffff);
|
||||
return rgba->alpha > ((float)0xff00 / (float)0xffff);
|
||||
}
|
||||
|
||||
#define SKIP_WHITESPACES(s) while (*(s) == ' ') (s)++;
|
||||
@@ -398,23 +398,25 @@ gdk_rgba_to_string (const GdkRGBA *rgba)
|
||||
|
||||
static gboolean
|
||||
parse_color_channel_value (GtkCssParser *parser,
|
||||
double *value,
|
||||
float *value,
|
||||
gboolean is_percentage)
|
||||
{
|
||||
double dvalue;
|
||||
|
||||
if (is_percentage)
|
||||
{
|
||||
if (!gtk_css_parser_consume_percentage (parser, value))
|
||||
if (!gtk_css_parser_consume_percentage (parser, &dvalue))
|
||||
return FALSE;
|
||||
|
||||
*value = CLAMP (*value, 0.0, 100.0) / 100.0;
|
||||
*value = CLAMP (dvalue, 0.0, 100.0) / 100.0;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!gtk_css_parser_consume_number (parser, value))
|
||||
if (!gtk_css_parser_consume_number (parser, &dvalue))
|
||||
return FALSE;
|
||||
|
||||
*value = CLAMP (*value, 0.0, 255.0) / 255.0;
|
||||
*value = CLAMP (dvalue, 0.0, 255.0) / 255.0;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -425,6 +427,7 @@ parse_color_channel (GtkCssParser *parser,
|
||||
gpointer data)
|
||||
{
|
||||
GdkRGBA *rgba = data;
|
||||
double dvalue;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
@@ -450,10 +453,10 @@ parse_color_channel (GtkCssParser *parser,
|
||||
return 1;
|
||||
|
||||
case 3:
|
||||
if (!gtk_css_parser_consume_number (parser, &rgba->alpha))
|
||||
if (!gtk_css_parser_consume_number (parser, &dvalue))
|
||||
return 0;
|
||||
|
||||
rgba->alpha = CLAMP (rgba->alpha, 0.0, 1.0);
|
||||
rgba->alpha = CLAMP (dvalue, 0.0, 1.0);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
|
||||
+4
-4
@@ -36,10 +36,10 @@ G_BEGIN_DECLS
|
||||
|
||||
struct _GdkRGBA
|
||||
{
|
||||
gdouble red;
|
||||
gdouble green;
|
||||
gdouble blue;
|
||||
gdouble alpha;
|
||||
float red;
|
||||
float green;
|
||||
float blue;
|
||||
float alpha;
|
||||
};
|
||||
|
||||
#define GDK_TYPE_RGBA (gdk_rgba_get_type ())
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "gdkseatprivate.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
/**
|
||||
* SECTION:gdkseat
|
||||
|
||||
@@ -82,18 +82,6 @@ struct _GdkSeat
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_seat_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkGrabStatus gdk_seat_grab (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
GdkSeatCapabilities capabilities,
|
||||
gboolean owner_events,
|
||||
GdkCursor *cursor,
|
||||
const GdkEvent *event,
|
||||
GdkSeatGrabPrepareFunc prepare_func,
|
||||
gpointer prepare_func_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_seat_ungrab (GdkSeat *seat);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_seat_get_display (GdkSeat *seat);
|
||||
|
||||
|
||||
+5
-4
@@ -3614,7 +3614,6 @@ gdk_surface_flush_events (GdkFrameClock *clock,
|
||||
_gdk_display_pause_events (surface->display);
|
||||
|
||||
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS);
|
||||
|
||||
surface->frame_clock_events_paused = TRUE;
|
||||
}
|
||||
|
||||
@@ -3624,9 +3623,11 @@ gdk_surface_resume_events (GdkFrameClock *clock,
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (data);
|
||||
|
||||
_gdk_display_unpause_events (surface->display);
|
||||
|
||||
surface->frame_clock_events_paused = FALSE;
|
||||
if (surface->frame_clock_events_paused)
|
||||
{
|
||||
_gdk_display_unpause_events (surface->display);
|
||||
surface->frame_clock_events_paused = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+4
-3
@@ -568,11 +568,12 @@ typedef enum
|
||||
* @GDK_ACTION_MOVE: Move the data, i.e. first copy it, then delete
|
||||
* it from the source using the DELETE target of the X selection protocol.
|
||||
* @GDK_ACTION_LINK: Add a link to the data. Note that this is only
|
||||
* useful if source and destination agree on what it means.
|
||||
* useful if source and destination agree on what it means, and is not
|
||||
* supported on all platforms.
|
||||
* @GDK_ACTION_ASK: Ask the user what to do with the data.
|
||||
*
|
||||
* Used in #GdkDrag to indicate what the destination
|
||||
* should do with the dropped data.
|
||||
* Used in #GdkDrop and #GdkDrag to indicate the actions that the
|
||||
* destination can and should do with the dropped data.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
|
||||
@@ -55,9 +55,6 @@ _gdk_quartz_display_open (const gchar *display_name)
|
||||
if (_gdk_display != NULL)
|
||||
return NULL;
|
||||
|
||||
/* Initialize application */
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
_gdk_display = g_object_new (gdk_quartz_display_get_type (), NULL);
|
||||
_gdk_device_manager = _gdk_device_manager_new (_gdk_display);
|
||||
|
||||
@@ -67,6 +64,8 @@ _gdk_quartz_display_open (const gchar *display_name)
|
||||
|
||||
_gdk_quartz_events_init ();
|
||||
|
||||
/* Initialize application */
|
||||
[NSApplication sharedApplication];
|
||||
#if 0
|
||||
/* FIXME: Remove the #if 0 when we have these functions */
|
||||
_gdk_quartz_dnd_init ();
|
||||
|
||||
@@ -2710,7 +2710,6 @@ gdk_surface_impl_quartz_class_init (GdkSurfaceImplQuartzClass *klass)
|
||||
impl_class->set_decorations = gdk_quartz_surface_set_decorations;
|
||||
impl_class->get_decorations = gdk_quartz_surface_get_decorations;
|
||||
impl_class->set_functions = gdk_quartz_surface_set_functions;
|
||||
impl_class->set_functions = gdk_quartz_surface_set_functions;
|
||||
impl_class->begin_resize_drag = gdk_quartz_surface_begin_resize_drag;
|
||||
impl_class->begin_move_drag = gdk_quartz_surface_begin_move_drag;
|
||||
impl_class->set_opacity = gdk_quartz_surface_set_opacity;
|
||||
|
||||
@@ -1258,6 +1258,8 @@ data_device_enter (void *data,
|
||||
seat->pending_offer = NULL;
|
||||
|
||||
seat->drop = gdk_wayland_drop_new (device, seat->drag, formats, dest_surface, offer, serial);
|
||||
gdk_wayland_drop_set_source_actions (seat->drop, seat->pending_source_actions);
|
||||
gdk_wayland_drop_set_action (seat->drop, seat->pending_action);
|
||||
|
||||
gdk_wayland_seat_discard_pending_offer (seat);
|
||||
|
||||
@@ -1296,6 +1298,7 @@ data_device_motion (void *data,
|
||||
wl_fixed_t y)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
int origin_x, origin_y;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("data device motion, data_device = %p, time = %d, x = %f, y = %f",
|
||||
@@ -1308,10 +1311,12 @@ data_device_motion (void *data,
|
||||
seat->pointer_info.surface_x = wl_fixed_to_double (x);
|
||||
seat->pointer_info.surface_y = wl_fixed_to_double (y);
|
||||
|
||||
gdk_surface_get_origin (gdk_drop_get_surface (seat->drop), &origin_x, &origin_y);
|
||||
|
||||
gdk_drop_emit_motion_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
origin_x + seat->pointer_info.surface_x,
|
||||
origin_y + seat->pointer_info.surface_y,
|
||||
time);
|
||||
}
|
||||
|
||||
@@ -1320,14 +1325,17 @@ data_device_drop (void *data,
|
||||
struct wl_data_device *data_device)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
int origin_x, origin_y;
|
||||
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("data device drop, data device %p", data_device));
|
||||
|
||||
gdk_surface_get_origin (gdk_drop_get_surface (seat->drop), &origin_x, &origin_y);
|
||||
|
||||
gdk_drop_emit_drop_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
origin_x + seat->pointer_info.surface_x,
|
||||
origin_y + seat->pointer_info.surface_y,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ gdk_wayland_drag_drop_done (GdkDrag *drag,
|
||||
GdkWaylandDrag *drag_wayland = GDK_WAYLAND_DRAG (drag);
|
||||
GdkDevice *device = gdk_drag_get_device (drag);
|
||||
|
||||
gdk_wayland_seat_set_drag (gdk_device_get_seat (device), drag);
|
||||
gdk_wayland_seat_set_drag (gdk_device_get_seat (device), NULL);
|
||||
|
||||
if (success)
|
||||
{
|
||||
@@ -340,6 +340,7 @@ gdk_wayland_drag_create_data_source (GdkDrag *drag)
|
||||
GdkDisplay *display = gdk_drag_get_display (drag);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
const char *const *mimetypes;
|
||||
GdkContentFormats *formats;
|
||||
gsize i, n_mimetypes;
|
||||
|
||||
drag_wayland->data_source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager);
|
||||
@@ -347,11 +348,20 @@ gdk_wayland_drag_create_data_source (GdkDrag *drag)
|
||||
&data_source_listener,
|
||||
drag);
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (gdk_drag_get_formats (drag), &n_mimetypes);
|
||||
formats = gdk_content_formats_ref (gdk_drag_get_formats (drag));
|
||||
formats = gdk_content_formats_union_serialize_mime_types (formats);
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (formats, &n_mimetypes);
|
||||
|
||||
GDK_DISPLAY_NOTE (gdk_drag_get_display (drag), EVENTS,
|
||||
{char *s = g_strjoinv (" ", (char **)mimetypes);
|
||||
g_message ("create data source, mime types=%s", s);
|
||||
g_free (s);});
|
||||
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
{
|
||||
wl_data_source_offer (drag_wayland->data_source, mimetypes[i]);
|
||||
}
|
||||
wl_data_source_offer (drag_wayland->data_source, mimetypes[i]);
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
}
|
||||
|
||||
GdkDrag *
|
||||
|
||||
@@ -51,7 +51,6 @@ struct _GdkWaylandDrop
|
||||
struct wl_data_offer *offer;
|
||||
uint32_t source_actions;
|
||||
uint32_t action;
|
||||
GdkDragAction selected_action;
|
||||
uint32_t serial;
|
||||
};
|
||||
|
||||
@@ -116,43 +115,43 @@ gdk_wayland_drop_drop_set_status (GdkWaylandDrop *drop_wayland,
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_commit_status (GdkWaylandDrop *wayland_drop)
|
||||
gdk_wayland_drop_commit_status (GdkWaylandDrop *wayland_drop,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
uint32_t dnd_actions;
|
||||
|
||||
display = gdk_drop_get_display (GDK_DROP (wayland_drop));
|
||||
|
||||
dnd_actions = gdk_to_wl_actions (wayland_drop->selected_action);
|
||||
|
||||
if (GDK_WAYLAND_DISPLAY (display)->data_device_manager_version >=
|
||||
WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION)
|
||||
{
|
||||
if (gdk_drag_action_is_unique (wayland_drop->selected_action))
|
||||
{
|
||||
wl_data_offer_set_actions (wayland_drop->offer, dnd_actions, dnd_actions);
|
||||
}
|
||||
uint32_t dnd_actions;
|
||||
uint32_t preferred_action;
|
||||
|
||||
dnd_actions = gdk_to_wl_actions (actions);
|
||||
|
||||
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
|
||||
preferred_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
else if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
|
||||
preferred_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
else if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
preferred_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
else
|
||||
{
|
||||
wl_data_offer_set_actions (wayland_drop->offer,
|
||||
dnd_actions | WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK,
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK);
|
||||
}
|
||||
preferred_action = 0;
|
||||
|
||||
wl_data_offer_set_actions (wayland_drop->offer, dnd_actions, preferred_action);
|
||||
}
|
||||
|
||||
gdk_wayland_drop_drop_set_status (wayland_drop, wayland_drop->selected_action != 0);
|
||||
gdk_wayland_drop_drop_set_status (wayland_drop, actions != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_status (GdkDrop *drop,
|
||||
GdkDragAction action)
|
||||
GdkDragAction actions)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop;
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
|
||||
wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
wayland_drop->selected_action = action;
|
||||
|
||||
gdk_wayland_drop_commit_status (wayland_drop);
|
||||
gdk_wayland_drop_commit_status (wayland_drop, actions);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -163,11 +162,9 @@ gdk_wayland_drop_finish (GdkDrop *drop,
|
||||
GdkDisplay *display = gdk_drop_get_display (drop);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
wayland_drop->selected_action = action;
|
||||
|
||||
if (action)
|
||||
{
|
||||
gdk_wayland_drop_commit_status (wayland_drop);
|
||||
gdk_wayland_drop_commit_status (wayland_drop, action);
|
||||
|
||||
if (display_wayland->data_device_manager_version >=
|
||||
WL_DATA_OFFER_FINISH_SINCE_VERSION)
|
||||
@@ -288,7 +285,8 @@ gdk_wayland_drop_update_actions (GdkWaylandDrop *drop)
|
||||
GdkDragAction gdk_actions = 0;
|
||||
uint32_t wl_actions;
|
||||
|
||||
if (drop->action & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
if (drop->action == 0 ||
|
||||
drop->action & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
wl_actions = drop->source_actions;
|
||||
else
|
||||
wl_actions = drop->action;
|
||||
|
||||
+20
-38
@@ -590,29 +590,27 @@ gsk_gl_driver_create_texture (GskGLDriver *self,
|
||||
return t->texture_id;
|
||||
}
|
||||
|
||||
static int
|
||||
create_render_target (GskGLDriver *self,
|
||||
int texture_id,
|
||||
gboolean add_depth_buffer,
|
||||
gboolean add_stencil_buffer)
|
||||
void
|
||||
gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
int width,
|
||||
int height,
|
||||
int *out_texture_id,
|
||||
int *out_render_target_id)
|
||||
{
|
||||
GLuint fbo_id, depth_stencil_buffer_id;
|
||||
Texture *t;
|
||||
GLuint fbo_id;
|
||||
Texture *texture;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), -1);
|
||||
g_return_val_if_fail (self->in_frame, -1);
|
||||
g_return_if_fail (self->in_frame);
|
||||
|
||||
t = gsk_gl_driver_get_texture (self, texture_id);
|
||||
if (t == NULL)
|
||||
return -1;
|
||||
|
||||
if (t->fbo.fbo_id != 0)
|
||||
fbo_clear (&t->fbo);
|
||||
texture = create_texture (self, width, height);
|
||||
gsk_gl_driver_bind_source_texture (self, texture->texture_id);
|
||||
gsk_gl_driver_init_texture_empty (self, texture->texture_id, GL_NEAREST, GL_NEAREST);
|
||||
|
||||
glGenFramebuffers (1, &fbo_id);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t->texture_id, 0);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture_id, 0);
|
||||
|
||||
#if 0
|
||||
if (add_depth_buffer || add_stencil_buffer)
|
||||
{
|
||||
glGenRenderbuffersEXT (1, &depth_stencil_buffer_id);
|
||||
@@ -638,34 +636,18 @@ create_render_target (GskGLDriver *self,
|
||||
if (add_stencil_buffer)
|
||||
glFramebufferRenderbufferEXT (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, depth_stencil_buffer_id);
|
||||
texture->fbo.depth_stencil_id = depth_stencil_buffer_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
t->fbo.fbo_id = fbo_id;
|
||||
t->fbo.depth_stencil_id = depth_stencil_buffer_id;
|
||||
texture->fbo.fbo_id = fbo_id;
|
||||
|
||||
g_assert_cmphex (glCheckFramebufferStatus (GL_FRAMEBUFFER), ==, GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, self->default_fbo.fbo_id);
|
||||
|
||||
return fbo_id;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
int width,
|
||||
int height,
|
||||
int *out_texture_id,
|
||||
int *out_render_target_id)
|
||||
{
|
||||
int texture_id, render_target;
|
||||
|
||||
texture_id = gsk_gl_driver_create_texture (self, width, height);
|
||||
gsk_gl_driver_bind_source_texture (self, texture_id);
|
||||
gsk_gl_driver_init_texture_empty (self, texture_id, GL_NEAREST, GL_NEAREST);
|
||||
|
||||
render_target = create_render_target (self, texture_id, FALSE, FALSE);
|
||||
|
||||
*out_texture_id = texture_id;
|
||||
*out_render_target_id = render_target;
|
||||
*out_texture_id = texture->texture_id;
|
||||
*out_render_target_id = fbo_id;
|
||||
}
|
||||
|
||||
/* Mark the texture permanent, meaning it won'e be reused by the GLDriver.
|
||||
|
||||
@@ -195,10 +195,15 @@ upload_glyph (GlyphCacheKey *key,
|
||||
{
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, r.stride / 4);
|
||||
glBindTexture (GL_TEXTURE_2D, value->texture_id);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
r.x, r.y, r.width, r.height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
r.data);
|
||||
|
||||
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
r.data);
|
||||
else
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
r.data);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
g_free (r.data);
|
||||
}
|
||||
|
||||
+19
-12
@@ -83,7 +83,7 @@ gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
|
||||
}
|
||||
|
||||
if (self->timestamp % MAX_FRAME_AGE == 0)
|
||||
{
|
||||
{
|
||||
g_hash_table_iter_init (&iter, self->icons);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
|
||||
{
|
||||
@@ -134,6 +134,7 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
int packed_y = 0;
|
||||
cairo_surface_t *surface;
|
||||
unsigned char *surface_data;
|
||||
guint gl_format;
|
||||
|
||||
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
|
||||
|
||||
@@ -155,30 +156,37 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
surface_data = cairo_image_surface_get_data (surface);
|
||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||
"Uploading texture");
|
||||
|
||||
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
|
||||
gl_format = GL_RGBA;
|
||||
else
|
||||
gl_format = GL_BGRA;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
|
||||
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + 1, packed_y + 1,
|
||||
width, height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
gl_format,
|
||||
GL_UNSIGNED_BYTE,
|
||||
surface_data);
|
||||
/* Padding top */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + 1, packed_y,
|
||||
width, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
gl_format, GL_UNSIGNED_BYTE,
|
||||
surface_data);
|
||||
/* Padding left */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y + 1,
|
||||
1, height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
gl_format, GL_UNSIGNED_BYTE,
|
||||
surface_data);
|
||||
/* Padding top left */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y,
|
||||
1, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
gl_format, GL_UNSIGNED_BYTE,
|
||||
surface_data);
|
||||
|
||||
/* Padding right */
|
||||
@@ -187,13 +195,13 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + width + 1, packed_y + 1,
|
||||
1, height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
gl_format, GL_UNSIGNED_BYTE,
|
||||
surface_data);
|
||||
/* Padding top right */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + width + 1, packed_y,
|
||||
1, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
gl_format, GL_UNSIGNED_BYTE,
|
||||
surface_data);
|
||||
/* Padding bottom */
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
@@ -202,13 +210,13 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + 1, packed_y + 1 + height,
|
||||
width, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
gl_format, GL_UNSIGNED_BYTE,
|
||||
surface_data);
|
||||
/* Padding bottom left */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y + 1 + height,
|
||||
1, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
gl_format, GL_UNSIGNED_BYTE,
|
||||
surface_data);
|
||||
/* Padding bottom right */
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
|
||||
@@ -216,9 +224,8 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + 1 + width, packed_y + 1 + height,
|
||||
1, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
gl_format, GL_UNSIGNED_BYTE,
|
||||
surface_data);
|
||||
|
||||
/* Reset this */
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
@@ -239,7 +246,7 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
char *filename = g_strdup_printf ("atlas_%u_%d.png", atlas->texture_id, k++);
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
|
||||
glGetTexImage (GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
|
||||
glGetTexImage (GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
|
||||
s = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, atlas->width, atlas->height, stride);
|
||||
cairo_surface_write_to_png (s, filename);
|
||||
|
||||
|
||||
+308
-543
File diff suppressed because it is too large
Load Diff
+79
-55
@@ -8,6 +8,46 @@ rect_equal (const graphene_rect_t *a,
|
||||
return memcmp (a, b, sizeof (graphene_rect_t)) == 0;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
rounded_rect_equal (const GskRoundedRect *r1,
|
||||
const GskRoundedRect *r2)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!r1)
|
||||
return FALSE;
|
||||
|
||||
if (r1->bounds.origin.x != r2->bounds.origin.x ||
|
||||
r1->bounds.origin.y != r2->bounds.origin.y ||
|
||||
r1->bounds.size.width != r2->bounds.size.width ||
|
||||
r1->bounds.size.height != r2->bounds.size.height)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < 4; i ++)
|
||||
if (r1->corner[i].width != r2->corner[i].width ||
|
||||
r1->corner[i].height != r2->corner[i].height)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
rounded_rect_corners_equal (const GskRoundedRect *r1,
|
||||
const GskRoundedRect *r2)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!r1)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < 4; i ++)
|
||||
if (r1->corner[i].width != r2->corner[i].width ||
|
||||
r1->corner[i].height != r2->corner[i].height)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline ProgramState *
|
||||
get_current_program_state (RenderOpBuilder *builder)
|
||||
{
|
||||
@@ -41,16 +81,6 @@ ops_finish (RenderOpBuilder *builder)
|
||||
builder->current_viewport = GRAPHENE_RECT_INIT (0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rgba_to_float (const GdkRGBA *c,
|
||||
float *f)
|
||||
{
|
||||
f[0] = c->red;
|
||||
f[1] = c->green;
|
||||
f[2] = c->blue;
|
||||
f[3] = c->alpha;
|
||||
}
|
||||
|
||||
/* Debugging only! */
|
||||
void
|
||||
ops_dump_framebuffer (RenderOpBuilder *builder,
|
||||
@@ -97,15 +127,12 @@ static void
|
||||
extract_matrix_metadata (GskTransform *transform,
|
||||
OpsMatrixMetadata *md)
|
||||
{
|
||||
float dummy;
|
||||
|
||||
switch (gsk_transform_get_category (transform))
|
||||
{
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
md->scale_x = 1;
|
||||
md->scale_y = 1;
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
gsk_transform_to_translate (transform, &md->translate_x, &md->translate_y);
|
||||
md->scale_x = 1;
|
||||
md->scale_y = 1;
|
||||
break;
|
||||
@@ -113,7 +140,7 @@ extract_matrix_metadata (GskTransform *transform,
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
gsk_transform_to_affine (transform,
|
||||
&md->scale_x, &md->scale_y,
|
||||
&md->translate_x, &md->translate_y);
|
||||
&dummy, &dummy);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
@@ -129,9 +156,6 @@ extract_matrix_metadata (GskTransform *transform,
|
||||
|
||||
/* TODO: 90% sure this is incorrect. But we should never hit this code
|
||||
* path anyway. */
|
||||
md->translate_x = graphene_matrix_get_value (&m, 3, 0);
|
||||
md->translate_y = graphene_matrix_get_value (&m, 3, 1);
|
||||
|
||||
graphene_vec3_init (&col1,
|
||||
graphene_matrix_get_value (&m, 0, 0),
|
||||
graphene_matrix_get_value (&m, 1, 0),
|
||||
@@ -156,17 +180,13 @@ ops_transform_bounds_modelview (const RenderOpBuilder *builder,
|
||||
const graphene_rect_t *src,
|
||||
graphene_rect_t *dst)
|
||||
{
|
||||
const MatrixStackEntry *head;
|
||||
|
||||
g_assert (builder->mv_stack != NULL);
|
||||
g_assert (builder->mv_stack->len >= 1);
|
||||
|
||||
head = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
|
||||
|
||||
gsk_transform_transform_bounds (builder->current_modelview, src, dst);
|
||||
|
||||
dst->origin.x += builder->dx * head->metadata.scale_x;
|
||||
dst->origin.y += builder->dy * head->metadata.scale_y;
|
||||
dst->origin.x += builder->dx * builder->scale_x;
|
||||
dst->origin.y += builder->dy * builder->scale_y;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -205,11 +225,6 @@ void
|
||||
ops_set_program (RenderOpBuilder *builder,
|
||||
const Program *program)
|
||||
{
|
||||
/* The tricky part about this is that we want to initialize all uniforms of a program
|
||||
* to the current value from the builder, but only once. */
|
||||
static const GskRoundedRect empty_clip;
|
||||
static const graphene_matrix_t empty_matrix;
|
||||
static const graphene_rect_t empty_rect;
|
||||
OpProgram *op;
|
||||
ProgramState *program_state;
|
||||
|
||||
@@ -223,9 +238,7 @@ ops_set_program (RenderOpBuilder *builder,
|
||||
|
||||
program_state = &builder->program_state[program->index];
|
||||
|
||||
/* If the projection is not yet set for this program, we use the current one. */
|
||||
if (memcmp (&empty_matrix, &program_state->projection, sizeof (graphene_matrix_t)) == 0 ||
|
||||
memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0)
|
||||
if (memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0)
|
||||
{
|
||||
OpMatrix *opm;
|
||||
|
||||
@@ -245,8 +258,7 @@ ops_set_program (RenderOpBuilder *builder,
|
||||
program_state->modelview = gsk_transform_ref (builder->current_modelview);
|
||||
}
|
||||
|
||||
if (rect_equal (&empty_rect, &program_state->viewport) ||
|
||||
!rect_equal (&builder->current_viewport, &program_state->viewport))
|
||||
if (!rect_equal (&builder->current_viewport, &program_state->viewport))
|
||||
{
|
||||
OpViewport *opv;
|
||||
|
||||
@@ -255,13 +267,13 @@ ops_set_program (RenderOpBuilder *builder,
|
||||
program_state->viewport = builder->current_viewport;
|
||||
}
|
||||
|
||||
if (memcmp (&empty_clip, &program_state->clip, sizeof (GskRoundedRect)) == 0 ||
|
||||
memcmp (&builder->current_clip, &program_state->clip, sizeof (GskRoundedRect)) != 0)
|
||||
if (!rounded_rect_equal (builder->current_clip, &program_state->clip))
|
||||
{
|
||||
OpClip *opc;
|
||||
|
||||
opc = ops_begin (builder, OP_CHANGE_CLIP);
|
||||
opc->clip = *builder->current_clip;
|
||||
opc->send_corners = !rounded_rect_corners_equal (builder->current_clip, &program_state->clip);
|
||||
program_state->clip = *builder->current_clip;
|
||||
}
|
||||
|
||||
@@ -283,15 +295,25 @@ ops_set_clip (RenderOpBuilder *builder,
|
||||
OpClip *op;
|
||||
|
||||
if (current_program_state &&
|
||||
memcmp (¤t_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
|
||||
rounded_rect_equal (¤t_program_state->clip, clip))
|
||||
return;
|
||||
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_CLIP)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_CLIP);
|
||||
{
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_CLIP);
|
||||
op->send_corners = !current_program_state ||
|
||||
!rounded_rect_corners_equal (¤t_program_state->clip, clip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the op before sent the corners, this one needs, too */
|
||||
op->send_corners |= !current_program_state ||
|
||||
!rounded_rect_corners_equal (¤t_program_state->clip, clip);
|
||||
}
|
||||
|
||||
op->clip = *clip;
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
if (current_program_state)
|
||||
current_program_state->clip = *clip;
|
||||
}
|
||||
|
||||
@@ -343,7 +365,6 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
|
||||
GskTransform *transform)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
graphene_matrix_t matrix;
|
||||
OpMatrix *op;
|
||||
|
||||
#if 0
|
||||
@@ -353,12 +374,10 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
|
||||
return;
|
||||
#endif
|
||||
|
||||
gsk_transform_to_matrix (transform, &matrix);
|
||||
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_MODELVIEW)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_MODELVIEW);
|
||||
|
||||
op->matrix = matrix;
|
||||
gsk_transform_to_matrix (transform, &op->matrix);
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
{
|
||||
@@ -597,7 +616,7 @@ ops_set_color (RenderOpBuilder *builder,
|
||||
current_program_state->color = *color;
|
||||
|
||||
op = ops_begin (builder, OP_CHANGE_COLOR);
|
||||
op->rgba = *color;
|
||||
op->rgba = color;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -620,8 +639,8 @@ ops_set_color_matrix (RenderOpBuilder *builder,
|
||||
current_program_state->color_matrix.offset = *offset;
|
||||
|
||||
op = ops_begin (builder, OP_CHANGE_COLOR_MATRIX);
|
||||
op->matrix = *matrix;
|
||||
op->offset = *offset;
|
||||
op->matrix = matrix;
|
||||
op->offset = offset;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -668,19 +687,17 @@ ops_set_border_color (RenderOpBuilder *builder,
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
OpBorder *op;
|
||||
float fcolor[4];
|
||||
|
||||
rgba_to_float (color, fcolor);
|
||||
|
||||
if (memcmp (fcolor, ¤t_program_state->border.color, sizeof fcolor) == 0)
|
||||
if (gdk_rgba_equal (color, ¤t_program_state->border.color))
|
||||
return;
|
||||
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_BORDER_COLOR);
|
||||
memcpy (op->color, fcolor, sizeof (float[4]));
|
||||
memcpy (current_program_state->border.color, fcolor, sizeof (float[4]));
|
||||
op->color = color;
|
||||
|
||||
current_program_state->border.color = *color;
|
||||
}
|
||||
|
||||
void
|
||||
GskQuadVertex *
|
||||
ops_draw (RenderOpBuilder *builder,
|
||||
const GskQuadVertex vertex_data[GL_N_VERTICES])
|
||||
{
|
||||
@@ -697,7 +714,14 @@ ops_draw (RenderOpBuilder *builder,
|
||||
op->vao_size = GL_N_VERTICES;
|
||||
}
|
||||
|
||||
g_array_append_vals (builder->vertices, vertex_data, GL_N_VERTICES);
|
||||
if (vertex_data)
|
||||
{
|
||||
g_array_append_vals (builder->vertices, vertex_data, GL_N_VERTICES);
|
||||
return NULL; /* Better not use this on the caller side */
|
||||
}
|
||||
|
||||
g_array_set_size (builder->vertices, builder->vertices->len + GL_N_VERTICES);
|
||||
return &g_array_index (builder->vertices, GskQuadVertex, builder->vertices->len - GL_N_VERTICES);
|
||||
}
|
||||
|
||||
/* The offset is only valid for the current modelview.
|
||||
|
||||
@@ -15,12 +15,8 @@
|
||||
#define GL_N_VERTICES 6
|
||||
#define GL_N_PROGRAMS 13
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float translate_x;
|
||||
float translate_y;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
|
||||
@@ -44,14 +40,10 @@ struct _Program
|
||||
int position_location;
|
||||
int uv_location;
|
||||
int alpha_location;
|
||||
int blend_mode_location;
|
||||
int viewport_location;
|
||||
int projection_location;
|
||||
int modelview_location;
|
||||
int clip_location;
|
||||
int clip_corner_widths_location;
|
||||
int clip_corner_heights_location;
|
||||
|
||||
int clip_rect_location;
|
||||
union {
|
||||
struct {
|
||||
int color_location;
|
||||
@@ -66,7 +58,6 @@ struct _Program
|
||||
struct {
|
||||
int num_color_stops_location;
|
||||
int color_stops_location;
|
||||
int color_offsets_location;
|
||||
int start_point_location;
|
||||
int end_point_location;
|
||||
} linear_gradient;
|
||||
@@ -79,19 +70,13 @@ struct _Program
|
||||
int color_location;
|
||||
int spread_location;
|
||||
int offset_location;
|
||||
int outline_location;
|
||||
int corner_widths_location;
|
||||
int corner_heights_location;
|
||||
int outline_rect_location;
|
||||
} inset_shadow;
|
||||
struct {
|
||||
int outline_location;
|
||||
int corner_widths_location;
|
||||
int corner_heights_location;
|
||||
int outline_rect_location;
|
||||
} outset_shadow;
|
||||
struct {
|
||||
int outline_location;
|
||||
int corner_widths_location;
|
||||
int corner_heights_location;
|
||||
int outline_rect_location;
|
||||
int color_location;
|
||||
int spread_location;
|
||||
int offset_location;
|
||||
@@ -99,9 +84,7 @@ struct _Program
|
||||
struct {
|
||||
int color_location;
|
||||
int widths_location;
|
||||
int outline_location;
|
||||
int corner_widths_location;
|
||||
int corner_heights_location;
|
||||
int outline_rect_location;
|
||||
} border;
|
||||
struct {
|
||||
int source2_location;
|
||||
@@ -135,7 +118,7 @@ typedef struct
|
||||
} color_matrix;
|
||||
struct {
|
||||
float widths[4];
|
||||
float color[4];
|
||||
GdkRGBA color;
|
||||
GskRoundedRect outline;
|
||||
} border;
|
||||
};
|
||||
@@ -230,7 +213,7 @@ void ops_set_border_width (RenderOpBuilder *builder,
|
||||
void ops_set_border_color (RenderOpBuilder *builder,
|
||||
const GdkRGBA *color);
|
||||
|
||||
void ops_draw (RenderOpBuilder *builder,
|
||||
GskQuadVertex * ops_draw (RenderOpBuilder *builder,
|
||||
const GskQuadVertex vertex_data[GL_N_VERTICES]);
|
||||
|
||||
void ops_offset (RenderOpBuilder *builder,
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskglshaderbuilderprivate.h"
|
||||
|
||||
#include "gskdebugprivate.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
void
|
||||
gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
|
||||
const char *vs_preamble_resource_path,
|
||||
const char *fs_preamble_resource_path)
|
||||
{
|
||||
memset (self, 0, sizeof (*self));
|
||||
|
||||
self->vs_preamble = g_resources_lookup_data (vs_preamble_resource_path, 0, NULL);
|
||||
self->fs_preamble = g_resources_lookup_data (fs_preamble_resource_path, 0, NULL);
|
||||
|
||||
g_assert (self->vs_preamble);
|
||||
g_assert (self->fs_preamble);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_shader_builder_finish (GskGLShaderBuilder *self)
|
||||
{
|
||||
g_bytes_unref (self->vs_preamble);
|
||||
g_bytes_unref (self->fs_preamble);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_shader_builder_set_glsl_version (GskGLShaderBuilder *self,
|
||||
int version)
|
||||
{
|
||||
self->version = version;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_shader_error (int shader_id,
|
||||
GError **error)
|
||||
{
|
||||
int status;
|
||||
int log_len;
|
||||
char *buffer;
|
||||
int code_len;
|
||||
char *code;
|
||||
|
||||
glGetShaderiv (shader_id, GL_COMPILE_STATUS, &status);
|
||||
|
||||
if (G_LIKELY (status == GL_TRUE))
|
||||
return TRUE;
|
||||
|
||||
glGetShaderiv (shader_id, GL_INFO_LOG_LENGTH, &log_len);
|
||||
buffer = g_malloc0 (log_len + 1);
|
||||
glGetShaderInfoLog (shader_id, log_len, NULL, buffer);
|
||||
|
||||
glGetShaderiv (shader_id, GL_SHADER_SOURCE_LENGTH, &code_len);
|
||||
code = g_malloc0 (code_len + 1);
|
||||
glGetShaderSource (shader_id, code_len, NULL, code);
|
||||
|
||||
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_COMPILATION_FAILED,
|
||||
"Compilation failure in shader.\nError message: %s\n\nSource code:\n%s\n\n",
|
||||
buffer,
|
||||
code);
|
||||
|
||||
g_free (buffer);
|
||||
g_free (code);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
const char *resource_path,
|
||||
GError **error)
|
||||
{
|
||||
|
||||
GBytes *source_bytes = g_resources_lookup_data (resource_path, 0, NULL);
|
||||
char version_buffer[64];
|
||||
const char *source;
|
||||
const char *vertex_shader_start;
|
||||
const char *fragment_shader_start;
|
||||
int vertex_id;
|
||||
int fragment_id;
|
||||
int program_id = -1;
|
||||
int status;
|
||||
|
||||
g_assert (source_bytes);
|
||||
|
||||
source = g_bytes_get_data (source_bytes, NULL);
|
||||
vertex_shader_start = strstr (source, "VERTEX_SHADER");
|
||||
fragment_shader_start = strstr (source, "FRAGMENT_SHADER");
|
||||
|
||||
g_assert (vertex_shader_start);
|
||||
g_assert (fragment_shader_start);
|
||||
|
||||
/* They both start at the next newline */
|
||||
vertex_shader_start = strstr (vertex_shader_start, "\n");
|
||||
fragment_shader_start = strstr (fragment_shader_start, "\n");
|
||||
|
||||
g_snprintf (version_buffer, sizeof (version_buffer),
|
||||
"#version %d\n", self->version);
|
||||
|
||||
vertex_id = glCreateShader (GL_VERTEX_SHADER);
|
||||
glShaderSource (vertex_id, 7,
|
||||
(const char *[]) {
|
||||
version_buffer,
|
||||
self->debugging ? "#define GSK_DEBUG 1\n" : "",
|
||||
self->legacy ? "#define GSK_LEGACY 1\n" : "",
|
||||
self->gl3 ? "#define GSK_GL3 1\n" : "",
|
||||
self->gles ? "#define GSK_GLES 1\n" : "",
|
||||
g_bytes_get_data (self->vs_preamble, NULL),
|
||||
vertex_shader_start
|
||||
},
|
||||
(int[]) {
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
fragment_shader_start - vertex_shader_start
|
||||
});
|
||||
glCompileShader (vertex_id);
|
||||
|
||||
if (!check_shader_error (vertex_id, error))
|
||||
{
|
||||
glDeleteShader (vertex_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
|
||||
glShaderSource (fragment_id, 7,
|
||||
(const char *[]) {
|
||||
version_buffer,
|
||||
self->debugging ? "#define GSK_DEBUG 1\n" : "",
|
||||
self->legacy ? "#define GSK_LEGACY 1\n" : "",
|
||||
self->gl3 ? "#define GSK_GL3 1\n" : "",
|
||||
self->gles ? "#define GSK_GLES 1\n" : "",
|
||||
g_bytes_get_data (self->fs_preamble, NULL),
|
||||
fragment_shader_start
|
||||
},
|
||||
(int[]) {
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
});
|
||||
glCompileShader (fragment_id);
|
||||
|
||||
if (!check_shader_error (fragment_id, error))
|
||||
{
|
||||
glDeleteShader (fragment_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
program_id = glCreateProgram ();
|
||||
glAttachShader (program_id, vertex_id);
|
||||
glAttachShader (program_id, fragment_id);
|
||||
glLinkProgram (program_id);
|
||||
|
||||
glGetProgramiv (program_id, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
int log_len = 0;
|
||||
|
||||
glGetProgramiv (program_id, GL_INFO_LOG_LENGTH, &log_len);
|
||||
|
||||
buffer = g_malloc0 (log_len + 1);
|
||||
glGetProgramInfoLog (program_id, log_len, NULL, buffer);
|
||||
|
||||
g_warning ("Linking failure in shader:\n%s", buffer);
|
||||
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_LINK_FAILED,
|
||||
"Linking failure in shader: %s", buffer);
|
||||
|
||||
g_free (buffer);
|
||||
|
||||
glDeleteProgram (program_id);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
glDetachShader (program_id, vertex_id);
|
||||
glDeleteShader (vertex_id);
|
||||
|
||||
glDetachShader (program_id, fragment_id);
|
||||
glDeleteShader (fragment_id);
|
||||
|
||||
out:
|
||||
g_bytes_unref (source_bytes);
|
||||
|
||||
return program_id;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef __GSK_SHADER_BUILDER_PRIVATE_H__
|
||||
#define __GSK_SHADER_BUILDER_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GBytes *vs_preamble;
|
||||
GBytes *fs_preamble;
|
||||
|
||||
int version;
|
||||
|
||||
guint debugging: 1;
|
||||
guint gles: 1;
|
||||
guint gl3: 1;
|
||||
guint legacy: 1;
|
||||
|
||||
} GskGLShaderBuilder;
|
||||
|
||||
|
||||
void gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
|
||||
const char *vs_preamble_resource_path,
|
||||
const char *fs_preamble_resource_path);
|
||||
void gsk_gl_shader_builder_finish (GskGLShaderBuilder *self);
|
||||
|
||||
void gsk_gl_shader_builder_set_glsl_version (GskGLShaderBuilder *self,
|
||||
int version);
|
||||
|
||||
int gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
const char *resource_path,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SHADER_BUILDER_PRIVATE_H__ */
|
||||
@@ -166,7 +166,8 @@ gsk_gl_texture_atlases_pack (GskGLTextureAtlases *self,
|
||||
g_ptr_array_add (self->atlases, atlas);
|
||||
|
||||
/* Pack it onto that one, which surely has enough space... */
|
||||
gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y);
|
||||
if (!gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y))
|
||||
g_assert_not_reached ();
|
||||
|
||||
GSK_NOTE(GLYPH_CACHE, g_message ("adding new atlas"));
|
||||
}
|
||||
@@ -304,5 +305,5 @@ gsk_gl_texture_atlas_realize (GskGLTextureAtlas *atlas)
|
||||
atlas->texture_id = create_shared_texture (atlas->width, atlas->height);
|
||||
gdk_gl_context_label_object_printf (gdk_gl_context_get_current (),
|
||||
GL_TEXTURE, atlas->texture_id,
|
||||
"Glyph atlas %d", atlas->texture_id);
|
||||
"Texture atlas %d", atlas->texture_id);
|
||||
}
|
||||
|
||||
@@ -1,332 +0,0 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskshaderbuilderprivate.h"
|
||||
|
||||
#include "gskdebugprivate.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
struct _GskShaderBuilder
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *resource_base_path;
|
||||
char *vertex_preamble;
|
||||
char *fragment_preamble;
|
||||
|
||||
|
||||
int common_vertex_shader_id;
|
||||
|
||||
int version;
|
||||
|
||||
GPtrArray *defines;
|
||||
|
||||
/* We reuse this one for all the shaders */
|
||||
GString *shader_code;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GskShaderBuilder, gsk_shader_builder, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gsk_shader_builder_finalize (GObject *gobject)
|
||||
{
|
||||
GskShaderBuilder *self = GSK_SHADER_BUILDER (gobject);
|
||||
|
||||
g_free (self->resource_base_path);
|
||||
g_free (self->vertex_preamble);
|
||||
g_free (self->fragment_preamble);
|
||||
g_string_free (self->shader_code, TRUE);
|
||||
|
||||
g_clear_pointer (&self->defines, g_ptr_array_unref);
|
||||
|
||||
if (self->common_vertex_shader_id > 0)
|
||||
glDeleteShader (self->common_vertex_shader_id);
|
||||
|
||||
G_OBJECT_CLASS (gsk_shader_builder_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_shader_builder_class_init (GskShaderBuilderClass *klass)
|
||||
{
|
||||
G_OBJECT_CLASS (klass)->finalize = gsk_shader_builder_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_shader_builder_init (GskShaderBuilder *self)
|
||||
{
|
||||
self->defines = g_ptr_array_new_with_free_func (g_free);
|
||||
self->shader_code = g_string_new (NULL);
|
||||
}
|
||||
|
||||
GskShaderBuilder *
|
||||
gsk_shader_builder_new (void)
|
||||
{
|
||||
return g_object_new (GSK_TYPE_SHADER_BUILDER, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_shader_builder_set_resource_base_path (GskShaderBuilder *builder,
|
||||
const char *base_path)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
|
||||
|
||||
g_free (builder->resource_base_path);
|
||||
builder->resource_base_path = g_strdup (base_path);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_shader_builder_set_vertex_preamble (GskShaderBuilder *builder,
|
||||
const char *vertex_preamble)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
|
||||
|
||||
g_free (builder->vertex_preamble);
|
||||
builder->vertex_preamble = g_strdup (vertex_preamble);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_shader_builder_set_fragment_preamble (GskShaderBuilder *builder,
|
||||
const char *fragment_preamble)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
|
||||
|
||||
g_free (builder->fragment_preamble);
|
||||
builder->fragment_preamble = g_strdup (fragment_preamble);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_shader_builder_set_version (GskShaderBuilder *builder,
|
||||
int version)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
|
||||
|
||||
builder->version = version;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_shader_builder_add_define (GskShaderBuilder *builder,
|
||||
const char *define_name,
|
||||
const char *define_value)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
|
||||
g_return_if_fail (define_name != NULL && *define_name != '\0');
|
||||
g_return_if_fail (define_value != NULL && *define_value != '\0');
|
||||
|
||||
g_ptr_array_add (builder->defines, g_strdup (define_name));
|
||||
g_ptr_array_add (builder->defines, g_strdup (define_value));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
lookup_shader_code (GString *code,
|
||||
const char *base_path,
|
||||
const char *shader_file,
|
||||
GError **error)
|
||||
{
|
||||
GBytes *source;
|
||||
char *path;
|
||||
|
||||
if (base_path != NULL)
|
||||
path = g_build_filename (base_path, shader_file, NULL);
|
||||
else
|
||||
path = g_strdup (shader_file);
|
||||
|
||||
source = g_resources_lookup_data (path, 0, error);
|
||||
g_free (path);
|
||||
|
||||
if (source == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_string_append (code, g_bytes_get_data (source, NULL));
|
||||
|
||||
g_bytes_unref (source);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
gsk_shader_builder_compile_shader (GskShaderBuilder *builder,
|
||||
int shader_type,
|
||||
const char *shader_preamble,
|
||||
const char *shader_source,
|
||||
GError **error)
|
||||
{
|
||||
GString *code;
|
||||
const char *source;
|
||||
int shader_id;
|
||||
int status;
|
||||
int i;
|
||||
|
||||
/* Clear possibly previously set shader code */
|
||||
g_string_erase (builder->shader_code, 0, -1);
|
||||
code = builder->shader_code;
|
||||
|
||||
if (builder->version > 0)
|
||||
{
|
||||
g_string_append_printf (code, "#version %d\n", builder->version);
|
||||
g_string_append_c (code, '\n');
|
||||
}
|
||||
|
||||
for (i = 0; i < builder->defines->len; i += 2)
|
||||
{
|
||||
const char *name = g_ptr_array_index (builder->defines, i);
|
||||
const char *value = g_ptr_array_index (builder->defines, i + 1);
|
||||
|
||||
g_string_append (code, "#define");
|
||||
g_string_append_c (code, ' ');
|
||||
g_string_append (code, name);
|
||||
g_string_append_c (code, ' ');
|
||||
g_string_append (code, value);
|
||||
g_string_append_c (code, '\n');
|
||||
}
|
||||
|
||||
g_string_append_c (code, '\n');
|
||||
|
||||
if (!lookup_shader_code (code, builder->resource_base_path, shader_preamble, error))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_string_append_c (code, '\n');
|
||||
|
||||
if (!lookup_shader_code (code, builder->resource_base_path, shader_source, error))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
source = code->str;
|
||||
|
||||
shader_id = glCreateShader (shader_type);
|
||||
glShaderSource (shader_id, 1, (const GLchar **) &source, NULL);
|
||||
glCompileShader (shader_id);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_DEBUG_CHECK (SHADERS))
|
||||
{
|
||||
g_print ("*** Compiling %s shader from '%s' + '%s' ***\n"
|
||||
"%s\n",
|
||||
shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
|
||||
shader_preamble, shader_source,
|
||||
source);
|
||||
}
|
||||
#endif
|
||||
|
||||
glGetShaderiv (shader_id, GL_COMPILE_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
int log_len;
|
||||
char *buffer;
|
||||
|
||||
glGetShaderiv (shader_id, GL_INFO_LOG_LENGTH, &log_len);
|
||||
|
||||
buffer = g_malloc0 (log_len + 1);
|
||||
glGetShaderInfoLog (shader_id, log_len, NULL, buffer);
|
||||
|
||||
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_COMPILATION_FAILED,
|
||||
"Compilation failure in %s shader:\n%s",
|
||||
shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
|
||||
buffer);
|
||||
g_free (buffer);
|
||||
|
||||
glDeleteShader (shader_id);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return shader_id;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_shader_builder_set_common_vertex_shader (GskShaderBuilder *self,
|
||||
const char *vertex_shader,
|
||||
GError **error)
|
||||
{
|
||||
int shader_id;
|
||||
|
||||
|
||||
shader_id = gsk_shader_builder_compile_shader (self,
|
||||
GL_VERTEX_SHADER,
|
||||
self->vertex_preamble,
|
||||
vertex_shader,
|
||||
error);
|
||||
|
||||
g_assert (shader_id > 0);
|
||||
self->common_vertex_shader_id = shader_id;
|
||||
}
|
||||
|
||||
int
|
||||
gsk_shader_builder_create_program (GskShaderBuilder *builder,
|
||||
const char *fragment_shader,
|
||||
const char *vertex_shader,
|
||||
GError **error)
|
||||
{
|
||||
int vertex_id;
|
||||
int fragment_id;
|
||||
int program_id;
|
||||
int status;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SHADER_BUILDER (builder), -1);
|
||||
g_return_val_if_fail (fragment_shader != NULL, -1);
|
||||
g_return_val_if_fail (builder->common_vertex_shader_id != 0, -1);
|
||||
|
||||
if (vertex_shader == NULL)
|
||||
vertex_id = builder->common_vertex_shader_id;
|
||||
else
|
||||
vertex_id = gsk_shader_builder_compile_shader (builder, GL_VERTEX_SHADER,
|
||||
builder->vertex_preamble,
|
||||
vertex_shader,
|
||||
error);
|
||||
if (vertex_id < 0)
|
||||
return -1;
|
||||
|
||||
fragment_id = gsk_shader_builder_compile_shader (builder, GL_FRAGMENT_SHADER,
|
||||
builder->fragment_preamble,
|
||||
fragment_shader,
|
||||
error);
|
||||
if (fragment_id < 0)
|
||||
{
|
||||
glDeleteShader (vertex_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
program_id = glCreateProgram ();
|
||||
glAttachShader (program_id, vertex_id);
|
||||
glAttachShader (program_id, fragment_id);
|
||||
glLinkProgram (program_id);
|
||||
|
||||
glGetProgramiv (program_id, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
int log_len = 0;
|
||||
|
||||
glGetProgramiv (program_id, GL_INFO_LOG_LENGTH, &log_len);
|
||||
|
||||
buffer = g_malloc0 (log_len + 1);
|
||||
glGetProgramInfoLog (program_id, log_len, NULL, buffer);
|
||||
|
||||
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_LINK_FAILED,
|
||||
"Linking failure in shader:\n%s", buffer);
|
||||
g_free (buffer);
|
||||
|
||||
glDeleteProgram (program_id);
|
||||
program_id = -1;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (vertex_id > 0)
|
||||
{
|
||||
/* We delete the common vertex shader when destroying the shader builder */
|
||||
glDetachShader (program_id, vertex_id);
|
||||
}
|
||||
|
||||
if (fragment_id > 0)
|
||||
{
|
||||
glDetachShader (program_id, fragment_id);
|
||||
glDeleteShader (fragment_id);
|
||||
}
|
||||
|
||||
return program_id;
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#ifndef __GSK_SHADER_BUILDER_PRIVATE_H__
|
||||
#define __GSK_SHADER_BUILDER_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_SHADER_BUILDER (gsk_shader_builder_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GskShaderBuilder, gsk_shader_builder, GSK, SHADER_BUILDER, GObject)
|
||||
|
||||
GskShaderBuilder * gsk_shader_builder_new (void);
|
||||
|
||||
void gsk_shader_builder_set_version (GskShaderBuilder *builder,
|
||||
int version);
|
||||
void gsk_shader_builder_set_resource_base_path (GskShaderBuilder *builder,
|
||||
const char *base_path);
|
||||
void gsk_shader_builder_set_vertex_preamble (GskShaderBuilder *builder,
|
||||
const char *shader_preamble);
|
||||
void gsk_shader_builder_set_fragment_preamble (GskShaderBuilder *builder,
|
||||
const char *shader_preamble);
|
||||
|
||||
void gsk_shader_builder_add_define (GskShaderBuilder *builder,
|
||||
const char *define_name,
|
||||
const char *define_value);
|
||||
|
||||
void gsk_shader_builder_set_common_vertex_shader (GskShaderBuilder *self,
|
||||
const char *vertex_shader,
|
||||
GError **error);
|
||||
|
||||
int gsk_shader_builder_create_program (GskShaderBuilder *builder,
|
||||
const char *fragment_shader,
|
||||
const char *vertex_shader,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SHADER_BUILDER_PRIVATE_H__ */
|
||||
+8
-10
@@ -77,7 +77,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
const GdkRGBA *rgba;
|
||||
} OpColor;
|
||||
|
||||
typedef struct
|
||||
@@ -88,6 +88,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
GskRoundedRect clip;
|
||||
guint send_corners: 1;
|
||||
} OpClip;
|
||||
|
||||
typedef struct
|
||||
@@ -108,8 +109,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float color_offsets[8];
|
||||
float color_stops[4 * 8];
|
||||
const GskColorStop *color_stops;
|
||||
graphene_point_t start_point;
|
||||
graphene_point_t end_point;
|
||||
int n_color_stops;
|
||||
@@ -117,8 +117,8 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
graphene_vec4_t offset;
|
||||
const graphene_matrix_t *matrix;
|
||||
const graphene_vec4_t *offset;
|
||||
} OpColorMatrix;
|
||||
|
||||
typedef struct
|
||||
@@ -130,18 +130,16 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float outline[4];
|
||||
float corner_widths[4];
|
||||
float corner_heights[4];
|
||||
GskRoundedRect outline;
|
||||
float spread;
|
||||
float offset[2];
|
||||
float color[4];
|
||||
const GdkRGBA *color;
|
||||
} OpShadow;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float widths[4];
|
||||
float color[4];
|
||||
const GdkRGBA *color;
|
||||
GskRoundedRect outline;
|
||||
} OpBorder;
|
||||
|
||||
|
||||
+7
-7
@@ -41,7 +41,7 @@ typedef struct _GskShadow GskShadow;
|
||||
|
||||
struct _GskColorStop
|
||||
{
|
||||
double offset;
|
||||
float offset;
|
||||
GdkRGBA color;
|
||||
};
|
||||
|
||||
@@ -210,11 +210,11 @@ GskTransform * gsk_transform_node_get_transform (GskRenderNode
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_opacity_node_new (GskRenderNode *child,
|
||||
double opacity);
|
||||
float opacity);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_opacity_node_get_child (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gsk_opacity_node_get_opacity (GskRenderNode *node);
|
||||
float gsk_opacity_node_get_opacity (GskRenderNode *node);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_color_matrix_node_new (GskRenderNode *child,
|
||||
@@ -280,13 +280,13 @@ GskBlendMode gsk_blend_node_get_blend_mode (GskRenderNode
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_cross_fade_node_new (GskRenderNode *start,
|
||||
GskRenderNode *end,
|
||||
double progress);
|
||||
float progress);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_cross_fade_node_get_start_child (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_cross_fade_node_get_end_child (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gsk_cross_fade_node_get_progress (GskRenderNode *node);
|
||||
float gsk_cross_fade_node_get_progress (GskRenderNode *node);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_text_node_new (PangoFont *font,
|
||||
@@ -307,11 +307,11 @@ const graphene_point_t *gsk_text_node_get_offset (GskRenderNode
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_blur_node_new (GskRenderNode *child,
|
||||
double radius);
|
||||
float radius);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_blur_node_get_child (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gsk_blur_node_get_radius (GskRenderNode *node);
|
||||
float gsk_blur_node_get_radius (GskRenderNode *node);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -2197,7 +2197,7 @@ struct _GskOpacityNode
|
||||
GskRenderNode render_node;
|
||||
|
||||
GskRenderNode *child;
|
||||
double opacity;
|
||||
float opacity;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -2267,7 +2267,7 @@ static const GskRenderNodeClass GSK_OPACITY_NODE_CLASS = {
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_opacity_node_new (GskRenderNode *child,
|
||||
double opacity)
|
||||
float opacity)
|
||||
{
|
||||
GskOpacityNode *self;
|
||||
|
||||
@@ -2301,7 +2301,7 @@ gsk_opacity_node_get_child (GskRenderNode *node)
|
||||
return self->child;
|
||||
}
|
||||
|
||||
double
|
||||
float
|
||||
gsk_opacity_node_get_opacity (GskRenderNode *node)
|
||||
{
|
||||
GskOpacityNode *self = (GskOpacityNode *) node;
|
||||
@@ -3278,7 +3278,7 @@ struct _GskCrossFadeNode
|
||||
|
||||
GskRenderNode *start;
|
||||
GskRenderNode *end;
|
||||
double progress;
|
||||
float progress;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -3352,7 +3352,7 @@ static const GskRenderNodeClass GSK_CROSS_FADE_NODE_CLASS = {
|
||||
GskRenderNode *
|
||||
gsk_cross_fade_node_new (GskRenderNode *start,
|
||||
GskRenderNode *end,
|
||||
double progress)
|
||||
float progress)
|
||||
{
|
||||
GskCrossFadeNode *self;
|
||||
|
||||
@@ -3390,7 +3390,7 @@ gsk_cross_fade_node_get_end_child (GskRenderNode *node)
|
||||
return self->end;
|
||||
}
|
||||
|
||||
double
|
||||
float
|
||||
gsk_cross_fade_node_get_progress (GskRenderNode *node)
|
||||
{
|
||||
GskCrossFadeNode *self = (GskCrossFadeNode *) node;
|
||||
@@ -3634,7 +3634,7 @@ struct _GskBlurNode
|
||||
GskRenderNode render_node;
|
||||
|
||||
GskRenderNode *child;
|
||||
double radius;
|
||||
float radius;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -3882,7 +3882,7 @@ static const GskRenderNodeClass GSK_BLUR_NODE_CLASS = {
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_blur_node_new (GskRenderNode *child,
|
||||
double radius)
|
||||
float radius)
|
||||
{
|
||||
GskBlurNode *self;
|
||||
float clip_radius = gsk_cairo_blur_compute_pixels (radius);
|
||||
@@ -3911,7 +3911,7 @@ gsk_blur_node_get_child (GskRenderNode *node)
|
||||
return self->child;
|
||||
}
|
||||
|
||||
double
|
||||
float
|
||||
gsk_blur_node_get_radius (GskRenderNode *node)
|
||||
{
|
||||
GskBlurNode *self = (GskBlurNode *) node;
|
||||
|
||||
@@ -433,9 +433,13 @@ parse_stops (GtkCssParser *parser,
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!gtk_css_parser_consume_number (parser, &stop.offset))
|
||||
double dval;
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &dval))
|
||||
goto error;
|
||||
|
||||
stop.offset = dval;
|
||||
|
||||
if (!gdk_rgba_parser_parse (parser, &stop.color))
|
||||
goto error;
|
||||
|
||||
|
||||
+75
-23
@@ -685,16 +685,54 @@ gsk_rotate_transform_finalize (GskTransform *self)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
_sincos (float deg,
|
||||
float *out_s,
|
||||
float *out_c)
|
||||
{
|
||||
if (deg == 90.0)
|
||||
{
|
||||
*out_c = 0.0;
|
||||
*out_s = 1.0;
|
||||
}
|
||||
else if (deg == 180.0)
|
||||
{
|
||||
*out_c = -1.0;
|
||||
*out_s = 0.0;
|
||||
}
|
||||
else if (deg == 270.0)
|
||||
{
|
||||
*out_c = 0.0;
|
||||
*out_s = -1.0;
|
||||
}
|
||||
else if (deg == 0.0)
|
||||
{
|
||||
*out_c = 1.0;
|
||||
*out_s = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float angle = deg * M_PI / 180.0;
|
||||
|
||||
#ifdef HAVE_SINCOSF
|
||||
sincosf (angle, out_s, out_c);
|
||||
#else
|
||||
*out_s = sinf (angle);
|
||||
*out_c = cosf (angle);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_rotate_transform_to_matrix (GskTransform *transform,
|
||||
graphene_matrix_t *out_matrix)
|
||||
{
|
||||
GskRotateTransform *self = (GskRotateTransform *) transform;
|
||||
float rad, c, s;
|
||||
float c, s;
|
||||
|
||||
_sincos (self->angle, &s, &c);
|
||||
|
||||
rad = self->angle * M_PI / 180.f;
|
||||
c = cosf (rad);
|
||||
s = sinf (rad);
|
||||
graphene_matrix_init_from_2d (out_matrix,
|
||||
c, s,
|
||||
-s, c,
|
||||
@@ -711,14 +749,12 @@ gsk_rotate_transform_apply_2d (GskTransform *transform,
|
||||
float *out_dy)
|
||||
{
|
||||
GskRotateTransform *self = (GskRotateTransform *) transform;
|
||||
float s, c, rad, xx, xy, yx, yy;
|
||||
float s, c, xx, xy, yx, yy;
|
||||
|
||||
if (fmodf (self->angle, 360.0f) == 0.0)
|
||||
return;
|
||||
|
||||
rad = self->angle * G_PI / 180.0f;
|
||||
s = sinf (rad);
|
||||
c = cosf (rad);
|
||||
_sincos (self->angle, &s, &c);
|
||||
|
||||
xx = c * *out_xx + s * *out_xy;
|
||||
yx = c * *out_yx + s * *out_yy;
|
||||
@@ -785,6 +821,22 @@ static const GskTransformClass GSK_ROTATE_TRANSFORM_CLASS =
|
||||
gsk_rotate_transform_equal,
|
||||
};
|
||||
|
||||
static inline float
|
||||
normalize_angle (float angle)
|
||||
{
|
||||
float f;
|
||||
|
||||
if (angle >= 0 && angle < 360)
|
||||
return angle;
|
||||
|
||||
f = angle - (360 * ((int)(angle / 360.0)));
|
||||
|
||||
if (f < 0)
|
||||
f = 360 + f;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_transform_rotate:
|
||||
* @next: (allow-none) (transfer full): the next transform
|
||||
@@ -815,7 +867,7 @@ gsk_transform_rotate (GskTransform *next,
|
||||
GSK_TRANSFORM_CATEGORY_2D,
|
||||
next);
|
||||
|
||||
result->angle = angle;
|
||||
result->angle = normalize_angle (angle);
|
||||
|
||||
return &result->parent;
|
||||
}
|
||||
@@ -938,7 +990,7 @@ gsk_transform_rotate_3d (GskTransform *next,
|
||||
GSK_TRANSFORM_CATEGORY_3D,
|
||||
next);
|
||||
|
||||
result->angle = angle;
|
||||
result->angle = normalize_angle (angle);
|
||||
graphene_vec3_init_from_vec3 (&result->axis, axis);
|
||||
|
||||
return &result->parent;
|
||||
@@ -1033,9 +1085,9 @@ gsk_scale_transform_equal (GskTransform *first_transform,
|
||||
GskScaleTransform *first = (GskScaleTransform *) first_transform;
|
||||
GskScaleTransform *second = (GskScaleTransform *) second_transform;
|
||||
|
||||
return G_APPROX_VALUE (first->factor_x, second->factor_x, 0.01f) &&
|
||||
G_APPROX_VALUE (first->factor_y, second->factor_y, 0.01f) &&
|
||||
G_APPROX_VALUE (first->factor_z, second->factor_z, 0.01f);
|
||||
return G_APPROX_VALUE (first->factor_x, second->factor_x, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (first->factor_y, second->factor_y, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (first->factor_z, second->factor_z, FLT_EPSILON);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1620,10 +1672,10 @@ gsk_transform_equal (GskTransform *first,
|
||||
if (first == NULL || second == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!gsk_transform_equal (first->next, second->next))
|
||||
if (first->transform_class != second->transform_class)
|
||||
return FALSE;
|
||||
|
||||
if (first->transform_class != second->transform_class)
|
||||
if (!gsk_transform_equal (first->next, second->next))
|
||||
return FALSE;
|
||||
|
||||
return first->transform_class->equal (first, second);
|
||||
@@ -1686,7 +1738,10 @@ gsk_transform_transform_bounds (GskTransform *self,
|
||||
float dx, dy;
|
||||
|
||||
gsk_transform_to_translate (self, &dx, &dy);
|
||||
graphene_rect_offset_r (rect, dx, dy, out_rect);
|
||||
out_rect->origin.x = rect->origin.x + dx;
|
||||
out_rect->origin.y = rect->origin.y + dy;
|
||||
out_rect->size.width = rect->size.width;
|
||||
out_rect->size.height = rect->size.height;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1696,13 +1751,10 @@ gsk_transform_transform_bounds (GskTransform *self,
|
||||
|
||||
gsk_transform_to_affine (self, &scale_x, &scale_y, &dx, &dy);
|
||||
|
||||
*out_rect = *rect;
|
||||
out_rect->origin.x *= scale_x;
|
||||
out_rect->origin.y *= scale_y;
|
||||
out_rect->size.width *= scale_x;
|
||||
out_rect->size.height *= scale_y;
|
||||
out_rect->origin.x += dx;
|
||||
out_rect->origin.y += dy;
|
||||
out_rect->origin.x = (rect->origin.x * scale_x) + dx;
|
||||
out_rect->origin.y = (rect->origin.y * scale_y) + dy;
|
||||
out_rect->size.width = rect->size.width * scale_x;
|
||||
out_rect->size.height = rect->size.height * scale_y;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+16
-21
@@ -1,24 +1,19 @@
|
||||
gsk_private_gl_shaders = [
|
||||
'resources/glsl/blit.fs.glsl',
|
||||
'resources/glsl/blit.vs.glsl',
|
||||
'resources/glsl/color.fs.glsl',
|
||||
'resources/glsl/coloring.fs.glsl',
|
||||
'resources/glsl/color_matrix.fs.glsl',
|
||||
'resources/glsl/linear_gradient.fs.glsl',
|
||||
'resources/glsl/blur.fs.glsl',
|
||||
'resources/glsl/inset_shadow.fs.glsl',
|
||||
'resources/glsl/outset_shadow.fs.glsl',
|
||||
'resources/glsl/unblurred_outset_shadow.fs.glsl',
|
||||
'resources/glsl/border.fs.glsl',
|
||||
'resources/glsl/cross_fade.fs.glsl',
|
||||
'resources/glsl/blend.fs.glsl',
|
||||
'resources/glsl/repeat.fs.glsl',
|
||||
'resources/glsl/es2_common.fs.glsl',
|
||||
'resources/glsl/es2_common.vs.glsl',
|
||||
'resources/glsl/gl3_common.fs.glsl',
|
||||
'resources/glsl/gl3_common.vs.glsl',
|
||||
'resources/glsl/gl_common.fs.glsl',
|
||||
'resources/glsl/gl_common.vs.glsl',
|
||||
'resources/glsl/preamble.fs.glsl',
|
||||
'resources/glsl/preamble.vs.glsl',
|
||||
'resources/glsl/border.glsl',
|
||||
'resources/glsl/blit.glsl',
|
||||
'resources/glsl/coloring.glsl',
|
||||
'resources/glsl/color.glsl',
|
||||
'resources/glsl/linear_gradient.glsl',
|
||||
'resources/glsl/color_matrix.glsl',
|
||||
'resources/glsl/blur.glsl',
|
||||
'resources/glsl/inset_shadow.glsl',
|
||||
'resources/glsl/outset_shadow.glsl',
|
||||
'resources/glsl/unblurred_outset_shadow.glsl',
|
||||
'resources/glsl/cross_fade.glsl',
|
||||
'resources/glsl/blend.glsl',
|
||||
'resources/glsl/repeat.glsl',
|
||||
]
|
||||
|
||||
gsk_public_sources = files([
|
||||
@@ -38,7 +33,7 @@ gsk_private_sources = files([
|
||||
'gskdebug.c',
|
||||
'gskprivate.c',
|
||||
'gskprofiler.c',
|
||||
'gl/gskshaderbuilder.c',
|
||||
'gl/gskglshaderbuilder.c',
|
||||
'gl/gskglprofiler.c',
|
||||
'gl/gskglglyphcache.c',
|
||||
'gl/gskglimage.c',
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
// VERTEX_SHADER:
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform int u_mode;
|
||||
uniform sampler2D u_source2;
|
||||
|
||||
@@ -264,73 +272,39 @@ void main() {
|
||||
|
||||
vec4 result;
|
||||
if (u_mode == 0)
|
||||
{
|
||||
result = normal(top_color, bottom_color);
|
||||
}
|
||||
result = normal(top_color, bottom_color);
|
||||
else if (u_mode == 1)
|
||||
{
|
||||
result = multiply(top_color, bottom_color);
|
||||
}
|
||||
result = multiply(top_color, bottom_color);
|
||||
else if (u_mode == 2)
|
||||
{
|
||||
result = screen(top_color, bottom_color);
|
||||
}
|
||||
result = screen(top_color, bottom_color);
|
||||
else if (u_mode == 3)
|
||||
{
|
||||
result = overlay(top_color, bottom_color);
|
||||
}
|
||||
result = overlay(top_color, bottom_color);
|
||||
else if (u_mode == 4)
|
||||
{
|
||||
result = darken(top_color, bottom_color);
|
||||
}
|
||||
result = darken(top_color, bottom_color);
|
||||
else if (u_mode == 5)
|
||||
{
|
||||
result = lighten(top_color, bottom_color);
|
||||
}
|
||||
result = lighten(top_color, bottom_color);
|
||||
else if (u_mode == 6)
|
||||
{
|
||||
result = color_dodge(top_color, bottom_color);
|
||||
}
|
||||
result = color_dodge(top_color, bottom_color);
|
||||
else if (u_mode == 7)
|
||||
{
|
||||
result = color_burn(top_color, bottom_color);
|
||||
}
|
||||
result = color_burn(top_color, bottom_color);
|
||||
else if (u_mode == 8)
|
||||
{
|
||||
result = hard_light(top_color, bottom_color);
|
||||
}
|
||||
result = hard_light(top_color, bottom_color);
|
||||
else if (u_mode == 9)
|
||||
{
|
||||
result = soft_light(top_color, bottom_color);
|
||||
}
|
||||
result = soft_light(top_color, bottom_color);
|
||||
else if (u_mode == 10)
|
||||
{
|
||||
result = difference(top_color, bottom_color);
|
||||
}
|
||||
result = difference(top_color, bottom_color);
|
||||
else if (u_mode == 11)
|
||||
{
|
||||
result = exclusion(top_color, bottom_color);
|
||||
}
|
||||
result = exclusion(top_color, bottom_color);
|
||||
else if (u_mode == 12)
|
||||
{
|
||||
result = color(top_color, bottom_color);
|
||||
}
|
||||
result = color(top_color, bottom_color);
|
||||
else if (u_mode == 13)
|
||||
{
|
||||
result = hue(top_color, bottom_color);
|
||||
}
|
||||
result = hue(top_color, bottom_color);
|
||||
else if (u_mode == 14)
|
||||
{
|
||||
result = saturation(top_color, bottom_color);
|
||||
}
|
||||
result = saturation(top_color, bottom_color);
|
||||
else if (u_mode == 15)
|
||||
{
|
||||
result = luminosity(top_color, bottom_color);
|
||||
}
|
||||
result = luminosity(top_color, bottom_color);
|
||||
else
|
||||
{
|
||||
discard;
|
||||
}
|
||||
discard;
|
||||
|
||||
setOutputColor(result * u_alpha);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
void main() {
|
||||
vec4 diffuse = Texture(u_source, vUv);
|
||||
|
||||
setOutputColor(diffuse * u_alpha);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// VERTEX_SHADER:
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
void main() {
|
||||
vec4 diffuse = Texture(u_source, vUv);
|
||||
|
||||
setOutputColor(diffuse * u_alpha);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
uniform float u_blur_radius;
|
||||
uniform vec2 u_blur_size;
|
||||
uniform vec2 u_blur_dir;
|
||||
|
||||
const float PI = 3.14159265;
|
||||
const float RADIUS_MULTIPLIER = 3.0;
|
||||
|
||||
// blur_radius 0 is NOT supported and MUST be caught before.
|
||||
|
||||
// Partially from http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
|
||||
void main() {
|
||||
float sigma = u_blur_radius; // *shrug*
|
||||
float blur_radius = u_blur_radius * RADIUS_MULTIPLIER;
|
||||
vec3 incrementalGaussian;
|
||||
incrementalGaussian.x = 1.0 / (sqrt(2.0 * PI) * sigma);
|
||||
incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
|
||||
incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
|
||||
|
||||
vec2 pixel_step = vec2(1.0) / u_blur_size;
|
||||
|
||||
float coefficientSum = 0;
|
||||
vec4 sum = Texture(u_source, vUv) * incrementalGaussian.x;
|
||||
coefficientSum += incrementalGaussian.x;
|
||||
incrementalGaussian.xy *= incrementalGaussian.yz;
|
||||
|
||||
int pixels_per_side = int(floor(blur_radius / 2.0));
|
||||
for (int i = 1; i <= pixels_per_side; i++) {
|
||||
vec2 p = i * pixel_step * u_blur_dir;
|
||||
|
||||
sum += Texture(u_source, vUv - p) * incrementalGaussian.x;
|
||||
sum += Texture(u_source, vUv + p) * incrementalGaussian.x;
|
||||
|
||||
coefficientSum += 2.0 * incrementalGaussian.x;
|
||||
incrementalGaussian.xy *= incrementalGaussian.yz;
|
||||
}
|
||||
|
||||
setOutputColor(sum / coefficientSum);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform float u_blur_radius;
|
||||
uniform vec2 u_blur_size;
|
||||
uniform vec2 u_blur_dir;
|
||||
|
||||
_OUT_ vec2 pixel_step;
|
||||
_OUT_ float pixels_per_side;
|
||||
_OUT_ vec3 initial_gaussian;
|
||||
|
||||
const float PI = 3.14159265;
|
||||
const float RADIUS_MULTIPLIER = 3.0;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
|
||||
pixel_step = (vec2(1.0) / u_blur_size) * u_blur_dir;
|
||||
pixels_per_side = floor(u_blur_radius * RADIUS_MULTIPLIER / 2.0);
|
||||
|
||||
float sigma = u_blur_radius; // *shrug*
|
||||
initial_gaussian.x = 1.0 / (sqrt(2.0 * PI) * sigma);
|
||||
initial_gaussian.y = exp(-0.5 / (sigma * sigma));
|
||||
initial_gaussian.z = initial_gaussian.y * initial_gaussian.y;
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform float u_blur_radius;
|
||||
uniform vec2 u_blur_size;
|
||||
|
||||
_IN_ vec2 pixel_step;
|
||||
_IN_ float pixels_per_side;
|
||||
_IN_ vec3 initial_gaussian;
|
||||
|
||||
// blur_radius 0 is NOT supported and MUST be caught before.
|
||||
|
||||
// Partially from http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
|
||||
void main() {
|
||||
vec3 incrementalGaussian = initial_gaussian;
|
||||
|
||||
float coefficientSum = 0.0;
|
||||
vec4 sum = Texture(u_source, vUv) * incrementalGaussian.x;
|
||||
coefficientSum += incrementalGaussian.x;
|
||||
incrementalGaussian.xy *= incrementalGaussian.yz;
|
||||
|
||||
vec2 p = pixel_step;
|
||||
for (int i = 1; i <= int(pixels_per_side); i++) {
|
||||
sum += Texture(u_source, vUv - p) * incrementalGaussian.x;
|
||||
sum += Texture(u_source, vUv + p) * incrementalGaussian.x;
|
||||
|
||||
coefficientSum += 2.0 * incrementalGaussian.x;
|
||||
incrementalGaussian.xy *= incrementalGaussian.yz;
|
||||
|
||||
p += pixel_step;
|
||||
}
|
||||
|
||||
setOutputColor(sum / coefficientSum);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
uniform vec4 u_color;
|
||||
uniform vec4 u_widths;
|
||||
|
||||
uniform vec4 u_outline;
|
||||
uniform vec4 u_corner_widths;
|
||||
uniform vec4 u_corner_heights;
|
||||
|
||||
void main() {
|
||||
vec4 bounds = u_outline;
|
||||
|
||||
bounds.z = bounds.x + bounds.z;
|
||||
bounds.w = bounds.y + bounds.w;
|
||||
|
||||
vec4 f = gl_FragCoord;
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect routside = RoundedRect (bounds, u_corner_widths, u_corner_heights);
|
||||
RoundedRect rinside = rounded_rect_shrink (routside, u_widths);
|
||||
|
||||
float alpha = clamp (rounded_rect_coverage (routside, f.xy) -
|
||||
rounded_rect_coverage (rinside, f.xy),
|
||||
0.0, 1.0);
|
||||
|
||||
/* Pre-multiply */
|
||||
vec4 color = u_color;
|
||||
color.rgb *= color.a;
|
||||
|
||||
setOutputColor (color * alpha * u_alpha);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform vec4 u_color;
|
||||
|
||||
_OUT_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
final_color = u_color;
|
||||
final_color.rgb *= final_color.a; // pre-multiply
|
||||
final_color *= u_alpha;
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform vec4 u_widths;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_IN_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect outside = create_rect(u_outline_rect);
|
||||
RoundedRect inside = rounded_rect_shrink (outside, u_widths);
|
||||
|
||||
float alpha = clamp (rounded_rect_coverage (outside, f.xy) -
|
||||
rounded_rect_coverage (inside, f.xy),
|
||||
0.0, 1.0);
|
||||
|
||||
setOutputColor(final_color * alpha);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
uniform vec4 u_color;
|
||||
|
||||
void main() {
|
||||
vec4 color = u_color;
|
||||
|
||||
// Pre-multiply alpha
|
||||
color.rgb *= color.a;
|
||||
setOutputColor(color * u_alpha);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform vec4 u_color;
|
||||
|
||||
_OUT_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
final_color = u_color;
|
||||
// Pre-multiply alpha
|
||||
final_color.rgb *= final_color.a;
|
||||
final_color *= u_alpha;
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
_IN_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
setOutputColor(final_color);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
// VERTEX_SHADER:
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform mat4 u_color_matrix;
|
||||
uniform vec4 u_color_offset;
|
||||
|
||||
void main() {
|
||||
vec4 diffuse = Texture(u_source, vUv);
|
||||
vec4 color;
|
||||
|
||||
color = diffuse;
|
||||
vec4 color = Texture(u_source, vUv);
|
||||
|
||||
// Un-premultilpy
|
||||
if (color.a != 0.0)
|
||||
color.rgb /= color.a;
|
||||
|
||||
color = u_color_matrix * color + u_color_offset;
|
||||
color = clamp(color, 0.0f, 1.0f);
|
||||
color = clamp(color, 0.0, 1.0);
|
||||
|
||||
color.rgb *= color.a;
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
uniform vec4 u_color;
|
||||
|
||||
void main() {
|
||||
vec4 diffuse = Texture(u_source, vUv);
|
||||
vec4 color = u_color;
|
||||
|
||||
// pre-multiply
|
||||
color.rgb *= color.a;
|
||||
|
||||
// u_source is drawn using cairo, so already pre-multiplied.
|
||||
color = vec4(color.rgb * diffuse.a * u_alpha,
|
||||
color.a * diffuse.a * u_alpha);
|
||||
|
||||
setOutputColor(color);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform vec4 u_color;
|
||||
|
||||
_OUT_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
|
||||
final_color = u_color;
|
||||
// pre-multiply
|
||||
final_color.rgb *= final_color.a;
|
||||
final_color *= u_alpha;
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
|
||||
_IN_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
vec4 diffuse = Texture(u_source, vUv);
|
||||
|
||||
setOutputColor(final_color * diffuse.a);
|
||||
}
|
||||
@@ -1,4 +1,11 @@
|
||||
// VERTEX_SHADER:
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform float u_progress;
|
||||
uniform sampler2D u_source2;
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D u_source;
|
||||
uniform sampler2D u_mask;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
uniform float u_alpha;
|
||||
uniform int uBlendMode;
|
||||
uniform vec4 u_viewport;
|
||||
|
||||
// In GtkSnapshot coordinates
|
||||
uniform vec4 u_clip;
|
||||
uniform vec4 u_clip_corner_widths;
|
||||
uniform vec4 u_clip_corner_heights;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
|
||||
struct RoundedRect
|
||||
{
|
||||
vec4 bounds;
|
||||
vec4 corner_widths;
|
||||
vec4 corner_heights;
|
||||
};
|
||||
|
||||
float
|
||||
ellipsis_dist (vec2 p, vec2 radius)
|
||||
{
|
||||
if (radius == vec2(0, 0))
|
||||
return 0.0;
|
||||
|
||||
vec2 p0 = p / radius;
|
||||
vec2 p1 = 2.0 * p0 / radius;
|
||||
|
||||
return (dot(p0, p0) - 1.0) / length (p1);
|
||||
}
|
||||
|
||||
float
|
||||
ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
|
||||
{
|
||||
float d = ellipsis_dist (point - center, radius);
|
||||
return clamp (0.5 - d, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float
|
||||
rounded_rect_coverage (RoundedRect r, vec2 p)
|
||||
{
|
||||
if (p.x < r.bounds.x || p.y < r.bounds.y ||
|
||||
p.x >= r.bounds.z || p.y >= r.bounds.w)
|
||||
return 0.0;
|
||||
|
||||
vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
|
||||
vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
|
||||
vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
|
||||
vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
|
||||
|
||||
vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x, r.corner_heights.x);
|
||||
vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y, r.corner_heights.y);
|
||||
vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
|
||||
vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
|
||||
|
||||
float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
|
||||
float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
|
||||
float d_br = ellipsis_coverage(p, ref_br, rad_br);
|
||||
float d_bl = ellipsis_coverage(p, ref_bl, rad_bl);
|
||||
|
||||
vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
|
||||
|
||||
bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
|
||||
p.x > ref_tr.x && p.y < ref_tr.y,
|
||||
p.x > ref_br.x && p.y > ref_br.y,
|
||||
p.x < ref_bl.x && p.y > ref_bl.y);
|
||||
|
||||
return 1.0 - dot(vec4(is_out), corner_coverages);
|
||||
}
|
||||
|
||||
RoundedRect
|
||||
rounded_rect_shrink (RoundedRect r, vec4 amount)
|
||||
{
|
||||
vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
|
||||
vec4 new_widths = max (r.corner_widths - amount.wyyw, 0.0);
|
||||
vec4 new_heights = max (r.corner_heights - amount.xxzz, 0.0);
|
||||
|
||||
return RoundedRect (new_bounds, new_widths, new_heights);
|
||||
}
|
||||
|
||||
vec4 Texture(sampler2D sampler, vec2 texCoords) {
|
||||
return texture2D(sampler, texCoords);
|
||||
}
|
||||
|
||||
void setOutputColor(vec4 color) {
|
||||
vec4 clipBounds = u_clip;
|
||||
vec4 f = gl_FragCoord;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
clipBounds.z = clipBounds.x + clipBounds.z;
|
||||
clipBounds.w = clipBounds.y + clipBounds.w;
|
||||
|
||||
RoundedRect r = RoundedRect(clipBounds, u_clip_corner_widths, u_clip_corner_heights);
|
||||
|
||||
gl_FragColor = color * rounded_rect_coverage(r, f.xy);
|
||||
/*gl_FragColor = color;*/
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
precision mediump float;
|
||||
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
|
||||
attribute vec2 aPosition;
|
||||
attribute vec2 aUv;
|
||||
|
||||
varying vec2 vUv;
|
||||
@@ -1,7 +0,0 @@
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
|
||||
in vec2 aPosition;
|
||||
in vec2 aUv;
|
||||
|
||||
out vec2 vUv;
|
||||
@@ -1,102 +0,0 @@
|
||||
uniform sampler2D u_source;
|
||||
uniform sampler2D u_mask;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
uniform float u_alpha;
|
||||
uniform int uBlendMode;
|
||||
uniform vec4 u_viewport;
|
||||
|
||||
// In GtkSnapshot coordinates
|
||||
uniform vec4 u_clip;
|
||||
uniform vec4 u_clip_corner_widths;
|
||||
uniform vec4 u_clip_corner_heights;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
|
||||
struct RoundedRect
|
||||
{
|
||||
vec4 bounds;
|
||||
vec4 corner_widths;
|
||||
vec4 corner_heights;
|
||||
};
|
||||
|
||||
float
|
||||
ellipsis_dist (vec2 p, vec2 radius)
|
||||
{
|
||||
if (radius == vec2(0, 0))
|
||||
return 0.0;
|
||||
|
||||
vec2 p0 = p / radius;
|
||||
vec2 p1 = 2.0 * p0 / radius;
|
||||
|
||||
return (dot(p0, p0) - 1.0) / length (p1);
|
||||
}
|
||||
|
||||
float
|
||||
ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
|
||||
{
|
||||
float d = ellipsis_dist (point - center, radius);
|
||||
return clamp (0.5 - d, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float
|
||||
rounded_rect_coverage (RoundedRect r, vec2 p)
|
||||
{
|
||||
if (p.x < r.bounds.x || p.y < r.bounds.y ||
|
||||
p.x >= r.bounds.z || p.y >= r.bounds.w)
|
||||
return 0.0;
|
||||
|
||||
vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
|
||||
vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
|
||||
vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
|
||||
vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
|
||||
|
||||
vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x, r.corner_heights.x);
|
||||
vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y, r.corner_heights.y);
|
||||
vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
|
||||
vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
|
||||
|
||||
float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
|
||||
float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
|
||||
float d_br = ellipsis_coverage(p, ref_br, rad_br);
|
||||
float d_bl = ellipsis_coverage(p, ref_bl, rad_bl);
|
||||
|
||||
vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
|
||||
|
||||
bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
|
||||
p.x > ref_tr.x && p.y < ref_tr.y,
|
||||
p.x > ref_br.x && p.y > ref_br.y,
|
||||
p.x < ref_bl.x && p.y > ref_bl.y);
|
||||
|
||||
return 1.0 - dot(vec4(is_out), corner_coverages);
|
||||
}
|
||||
|
||||
RoundedRect
|
||||
rounded_rect_shrink (RoundedRect r, vec4 amount)
|
||||
{
|
||||
vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
|
||||
vec4 new_widths = max (r.corner_widths - amount.wyyw, 0.0);
|
||||
vec4 new_heights = max (r.corner_heights - amount.xxzz, 0.0);
|
||||
|
||||
return RoundedRect (new_bounds, new_widths, new_heights);
|
||||
}
|
||||
|
||||
vec4 Texture(sampler2D sampler, vec2 texCoords) {
|
||||
return texture2D(sampler, texCoords);
|
||||
}
|
||||
|
||||
void setOutputColor(vec4 color) {
|
||||
vec4 clipBounds = u_clip;
|
||||
vec4 f = gl_FragCoord;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
clipBounds.z = clipBounds.x + clipBounds.z;
|
||||
clipBounds.w = clipBounds.y + clipBounds.w;
|
||||
|
||||
RoundedRect r = RoundedRect(clipBounds, u_clip_corner_widths, u_clip_corner_heights);
|
||||
|
||||
gl_FragColor = color * rounded_rect_coverage(r, f.xy);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
|
||||
attribute vec2 aPosition;
|
||||
attribute vec2 aUv;
|
||||
|
||||
varying vec2 vUv;
|
||||
@@ -1,26 +0,0 @@
|
||||
uniform float u_spread;
|
||||
uniform vec4 u_color;
|
||||
uniform vec2 u_offset;
|
||||
uniform vec4 u_outline;
|
||||
uniform vec4 u_corner_widths;
|
||||
uniform vec4 u_corner_heights;
|
||||
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect outline = RoundedRect(vec4(u_outline.xy, u_outline.xy + u_outline.zw),
|
||||
u_corner_widths, u_corner_heights);
|
||||
RoundedRect inside = rounded_rect_shrink(outline, vec4(u_spread));
|
||||
|
||||
|
||||
vec2 offset = vec2(u_offset.x, - u_offset.y);
|
||||
vec4 color = vec4(u_color.rgb * u_color.a, u_color.a);
|
||||
color = color * clamp (rounded_rect_coverage (outline, f.xy) -
|
||||
rounded_rect_coverage (inside, f.xy - offset),
|
||||
0.0, 1.0);
|
||||
setOutputColor(color * u_alpha);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform vec4 u_color;
|
||||
|
||||
_OUT_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
final_color = u_color;
|
||||
final_color.rgb *= final_color.a;
|
||||
final_color *= u_alpha;
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform float u_spread;
|
||||
uniform vec2 u_offset;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_IN_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
vec4 color;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect outside = create_rect(u_outline_rect);
|
||||
RoundedRect inside = rounded_rect_shrink(outside, vec4(u_spread));
|
||||
color = final_color * clamp (rounded_rect_coverage (outside, f.xy) -
|
||||
rounded_rect_coverage (inside, f.xy - u_offset),
|
||||
0.0, 1.0);
|
||||
setOutputColor(color);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
uniform vec4 u_color_stops[8];
|
||||
uniform float u_color_offsets[8];
|
||||
uniform int u_num_color_stops;
|
||||
uniform vec2 u_start_point;
|
||||
uniform vec2 u_end_point;
|
||||
|
||||
vec4 fragCoord() {
|
||||
vec4 f = gl_FragCoord;
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
return f;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 startPoint = (u_modelview * vec4(u_start_point, 0, 1)).xy;
|
||||
vec2 endPoint = (u_modelview * vec4(u_end_point, 0, 1)).xy;
|
||||
float maxDist = length(endPoint - startPoint);
|
||||
|
||||
// Position relative to startPoint
|
||||
vec2 pos = fragCoord().xy - startPoint;
|
||||
|
||||
// Gradient direction
|
||||
vec2 gradient = endPoint - startPoint;
|
||||
float gradientLength = length(gradient);
|
||||
|
||||
// Current pixel, projected onto the line between the start point and the end point
|
||||
// The projection will be relative to the start point!
|
||||
vec2 proj = (dot(gradient, pos) / (gradientLength * gradientLength)) * gradient;
|
||||
|
||||
// Offset of the current pixel
|
||||
float offset = length(proj) / maxDist;
|
||||
|
||||
vec4 color = u_color_stops[0];
|
||||
for (int i = 1; i < u_num_color_stops; i ++) {
|
||||
if (offset >= u_color_offsets[i - 1]) {
|
||||
float o = (offset - u_color_offsets[i - 1]) / (u_color_offsets[i] - u_color_offsets[i - 1]);
|
||||
color = mix(u_color_stops[i - 1], u_color_stops[i], clamp(o, 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
/* Pre-multiply */
|
||||
color.rgb *= color.a;
|
||||
|
||||
setOutputColor(color * u_alpha);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// VERTEX_SHADER
|
||||
uniform vec2 u_start_point;
|
||||
uniform vec2 u_end_point;
|
||||
uniform float u_color_stops[8 * 5];
|
||||
uniform int u_num_color_stops;
|
||||
|
||||
_OUT_ vec2 startPoint;
|
||||
_OUT_ vec2 endPoint;
|
||||
_OUT_ float maxDist;
|
||||
_OUT_ vec2 gradient;
|
||||
_OUT_ float gradientLength;
|
||||
_OUT_ vec4 color_stops[8];
|
||||
_OUT_ float color_offsets[8];
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
startPoint = (u_modelview * vec4(u_start_point, 0, 1)).xy;
|
||||
endPoint = (u_modelview * vec4(u_end_point, 0, 1)).xy;
|
||||
maxDist = length(endPoint - startPoint);
|
||||
|
||||
// Gradient direction
|
||||
gradient = endPoint - startPoint;
|
||||
gradientLength = length(gradient);
|
||||
|
||||
for (int i = 0; i < u_num_color_stops; i ++) {
|
||||
color_offsets[i] = u_color_stops[(i * 5) + 0];
|
||||
color_stops[i].r = u_color_stops[(i * 5) + 1];
|
||||
color_stops[i].g = u_color_stops[(i * 5) + 2];
|
||||
color_stops[i].b = u_color_stops[(i * 5) + 3];
|
||||
color_stops[i].a = u_color_stops[(i * 5) + 4];
|
||||
}
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
#ifdef GSK_LEGACY
|
||||
uniform int u_num_color_stops;
|
||||
#else
|
||||
uniform highp int u_num_color_stops; // Why? Because it works like this.
|
||||
#endif
|
||||
|
||||
_IN_ vec2 startPoint;
|
||||
_IN_ vec2 endPoint;
|
||||
_IN_ float maxDist;
|
||||
_IN_ vec2 gradient;
|
||||
_IN_ float gradientLength;
|
||||
_IN_ vec4 color_stops[8];
|
||||
_IN_ float color_offsets[8];
|
||||
|
||||
|
||||
vec4 fragCoord() {
|
||||
vec4 f = gl_FragCoord;
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
return f;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Position relative to startPoint
|
||||
vec2 pos = fragCoord().xy - startPoint;
|
||||
|
||||
// Current pixel, projected onto the line between the start point and the end point
|
||||
// The projection will be relative to the start point!
|
||||
vec2 proj = (dot(gradient, pos) / (gradientLength * gradientLength)) * gradient;
|
||||
|
||||
// Offset of the current pixel
|
||||
float offset = length(proj) / maxDist;
|
||||
|
||||
vec4 color = color_stops[0];
|
||||
for (int i = 1; i < u_num_color_stops; i ++) {
|
||||
if (offset >= color_offsets[i - 1]) {
|
||||
float o = (offset - color_offsets[i - 1]) / (color_offsets[i] - color_offsets[i - 1]);
|
||||
color = mix(color_stops[i - 1], color_stops[i], clamp(o, 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
/* Pre-multiply */
|
||||
color.rgb *= color.a;
|
||||
|
||||
setOutputColor(color * u_alpha);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
uniform vec4 u_outline;
|
||||
uniform vec4 u_corner_widths;//= vec4(0, 0, 0, 0);
|
||||
uniform vec4 u_corner_heights;// = vec4(0, 0, 0, 0);
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect outline = RoundedRect(vec4(u_outline.xy, u_outline.xy + u_outline.zw), u_corner_widths, u_corner_heights);
|
||||
|
||||
vec4 color = Texture(u_source, vUv);
|
||||
color = color * (1.0 - clamp(rounded_rect_coverage (outline, f.xy), 0.0, 1.0));
|
||||
setOutputColor(color * u_alpha);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// VERTEX_SHADER:
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect outline = create_rect(u_outline_rect);
|
||||
vec4 color = Texture(u_source, vUv);
|
||||
color = color * (1.0 - clamp(rounded_rect_coverage(outline, f.xy), 0.0, 1.0));
|
||||
setOutputColor(color * u_alpha);
|
||||
}
|
||||
@@ -1,21 +1,33 @@
|
||||
#ifdef GSK_GL3
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#ifdef GSK_GLES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
|
||||
uniform sampler2D u_source;
|
||||
uniform sampler2D u_mask;
|
||||
uniform mat4 u_projection = mat4(1.0);
|
||||
uniform mat4 u_modelview = mat4(1.0);
|
||||
uniform float u_alpha = 1.0;
|
||||
uniform int uBlendMode;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
uniform float u_alpha;// = 1.0;
|
||||
uniform vec4 u_viewport;
|
||||
uniform vec4[3] u_clip_rect;
|
||||
|
||||
// In GtkSnapshot coordinates
|
||||
uniform vec4 u_clip;
|
||||
uniform vec4 u_clip_corner_widths = vec4(0, 0, 0, 0);
|
||||
uniform vec4 u_clip_corner_heights = vec4(0, 0, 0, 0);
|
||||
#if GSK_GLES
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
#elif GSK_LEGACY
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
_OUT_ vec4 outputColor;
|
||||
#else
|
||||
#define _OUT_ out
|
||||
#define _IN_ in
|
||||
_OUT_ vec4 outputColor;
|
||||
#endif
|
||||
_IN_ vec2 vUv;
|
||||
|
||||
in vec2 vUv;
|
||||
|
||||
out vec4 outputColor;
|
||||
|
||||
|
||||
struct RoundedRect
|
||||
@@ -25,6 +37,16 @@ struct RoundedRect
|
||||
vec4 corner_heights;
|
||||
};
|
||||
|
||||
// Transform from a GskRoundedRect to a RoundedRect as we need it.
|
||||
RoundedRect
|
||||
create_rect(vec4 data[3])
|
||||
{
|
||||
vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
|
||||
vec4 widths = vec4(data[1].x, data[1].z, data[2].x, data[2].z);
|
||||
vec4 heights = vec4(data[1].y, data[1].w, data[2].y, data[2].w);
|
||||
return RoundedRect(bounds, widths, heights);
|
||||
}
|
||||
|
||||
float
|
||||
ellipsis_dist (vec2 p, vec2 radius)
|
||||
{
|
||||
@@ -76,6 +98,7 @@ rounded_rect_coverage (RoundedRect r, vec2 p)
|
||||
return 1.0 - dot(vec4(is_out), corner_coverages);
|
||||
}
|
||||
|
||||
// amount is: top, right, bottom, left
|
||||
RoundedRect
|
||||
rounded_rect_shrink (RoundedRect r, vec4 amount)
|
||||
{
|
||||
@@ -84,40 +107,46 @@ rounded_rect_shrink (RoundedRect r, vec4 amount)
|
||||
vec4 new_heights = vec4(0);
|
||||
|
||||
// Left top
|
||||
if (r.corner_widths.x > 0) new_widths.x = r.corner_widths.x - amount.w;
|
||||
if (r.corner_heights.x > 0) new_heights.x = r.corner_heights.x - amount.x;
|
||||
if (r.corner_widths.x > 0.0) new_widths.x = r.corner_widths.x - amount.w;
|
||||
if (r.corner_heights.x > 0.0) new_heights.x = r.corner_heights.x - amount.x;
|
||||
|
||||
// Top right
|
||||
if (r.corner_widths.y > 0) new_widths.y = r.corner_widths.y - amount.y;
|
||||
if (r.corner_heights.y > 0) new_heights.y = r.corner_heights.y - amount.x;
|
||||
if (r.corner_widths.y > 0.0) new_widths.y = r.corner_widths.y - amount.y;
|
||||
if (r.corner_heights.y > 0.0) new_heights.y = r.corner_heights.y - amount.x;
|
||||
|
||||
// Bottom right
|
||||
if (r.corner_widths.z > 0) new_widths.z = r.corner_widths.z - amount.y;
|
||||
if (r.corner_heights.z > 0) new_heights.z = r.corner_heights.z - amount.z;
|
||||
if (r.corner_widths.z > 0.0) new_widths.z = r.corner_widths.z - amount.y;
|
||||
if (r.corner_heights.z > 0.0) new_heights.z = r.corner_heights.z - amount.z;
|
||||
|
||||
// Bottom left
|
||||
if (r.corner_widths.w > 0) new_widths.w = r.corner_widths.w - amount.w;
|
||||
if (r.corner_heights.w > 0) new_heights.w = r.corner_heights.w - amount.z;
|
||||
if (r.corner_widths.w > 0.0) new_widths.w = r.corner_widths.w - amount.w;
|
||||
if (r.corner_heights.w > 0.0) new_heights.w = r.corner_heights.w - amount.z;
|
||||
|
||||
return RoundedRect (new_bounds, new_widths, new_heights);
|
||||
}
|
||||
|
||||
vec4 Texture(sampler2D sampler, vec2 texCoords) {
|
||||
#if GSK_GLES
|
||||
return texture2D(sampler, texCoords);
|
||||
#elif GSK_LEGACY
|
||||
return texture2D(sampler, texCoords);
|
||||
#else
|
||||
return texture(sampler, texCoords);
|
||||
#endif
|
||||
}
|
||||
|
||||
void setOutputColor(vec4 color) {
|
||||
vec4 clipBounds = u_clip;
|
||||
vec4 f = gl_FragCoord;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
clipBounds.z = clipBounds.x + clipBounds.z;
|
||||
clipBounds.w = clipBounds.y + clipBounds.w;
|
||||
|
||||
RoundedRect r = RoundedRect(clipBounds, u_clip_corner_widths, u_clip_corner_heights);
|
||||
|
||||
outputColor = color * rounded_rect_coverage(r, f.xy);
|
||||
#if GSK_GLES
|
||||
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
|
||||
#elif GSK_LEGACY
|
||||
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
|
||||
#else
|
||||
outputColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
|
||||
#endif
|
||||
/*outputColor = color;*/
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
uniform float u_alpha;
|
||||
|
||||
#ifdef GSK_GLES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#if GSK_GLES
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
attribute vec2 aPosition;
|
||||
attribute vec2 aUv;
|
||||
_OUT_ vec2 vUv;
|
||||
#elif GSK_LEGACY
|
||||
#define _OUT_ varying
|
||||
#define _IN_ varying
|
||||
attribute vec2 aPosition;
|
||||
attribute vec2 aUv;
|
||||
_OUT_ vec2 vUv;
|
||||
#else
|
||||
#define _OUT_ out
|
||||
#define _IN_ in
|
||||
_IN_ vec2 aPosition;
|
||||
_IN_ vec2 aUv;
|
||||
_OUT_ vec2 vUv;
|
||||
#endif
|
||||
@@ -1,3 +1,11 @@
|
||||
// VERTEX_SHADER:
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform vec4 u_child_bounds;
|
||||
uniform vec4 u_texture_rect;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
uniform float u_spread;
|
||||
uniform vec4 u_color;
|
||||
uniform vec2 u_offset;
|
||||
uniform vec4 u_outline;
|
||||
uniform vec4 u_corner_widths;
|
||||
uniform vec4 u_corner_heights;
|
||||
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect inside = RoundedRect(vec4(u_outline.xy, u_outline.xy + u_outline.zw),
|
||||
u_corner_widths, u_corner_heights);
|
||||
|
||||
RoundedRect outline = rounded_rect_shrink(inside, vec4(- u_spread));
|
||||
|
||||
vec2 offset = vec2(u_offset.x, - u_offset.y);
|
||||
vec4 color = vec4(u_color.rgb * u_color.a, u_color.a);
|
||||
color = color * clamp (rounded_rect_coverage (outline, f.xy - offset) -
|
||||
rounded_rect_coverage (inside, f.xy),
|
||||
0.0, 1.0);
|
||||
setOutputColor(color * u_alpha);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// VERTEX_SHADER:
|
||||
uniform vec4 u_color;
|
||||
|
||||
_OUT_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
final_color = u_color;
|
||||
final_color.rgb *= final_color.a;
|
||||
final_color *= u_alpha;
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
uniform float u_spread;
|
||||
uniform vec2 u_offset;
|
||||
uniform vec4[3] u_outline_rect;
|
||||
|
||||
_IN_ vec4 final_color;
|
||||
|
||||
void main() {
|
||||
vec4 f = gl_FragCoord;
|
||||
vec4 color;
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect inside = create_rect(u_outline_rect);
|
||||
RoundedRect outside = rounded_rect_shrink(inside, vec4(- u_spread));
|
||||
color = final_color * clamp (rounded_rect_coverage (outside, f.xy - u_offset) -
|
||||
rounded_rect_coverage (inside, f.xy),
|
||||
0.0, 1.0);
|
||||
setOutputColor(color);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user