Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 989553758e | |||
| 767df50eda | |||
| baae2920dc | |||
| 832419b2c3 | |||
| ff78adb25d | |||
| e05f404fc5 | |||
| d572b5d94c | |||
| c2306d3ba6 | |||
| edf56b438e | |||
| cd3cd64769 | |||
| fb0b0ddfe0 | |||
| 3180cdb9ef | |||
| 07d1ea4356 | |||
| e5f1ff6a4d | |||
| f8303c7a22 | |||
| af6d1839e1 | |||
| b4b7fe122e | |||
| e36940fa8c | |||
| d2e13dd3e4 | |||
| ad48bbb849 | |||
| 2497d982b0 | |||
| ace2208f45 | |||
| b8c4009686 | |||
| 6f0ff3a8cb | |||
| 209e8b54e9 | |||
| 07d17c5bc1 | |||
| e26c361d2d | |||
| 290e250886 | |||
| 22d5b9bc41 | |||
| ab407ba57c | |||
| 07f2024bfc | |||
| accbfc0083 | |||
| e8d890ae0c | |||
| bfc1e77b7f | |||
| dba9298c14 | |||
| 67c0f88c00 | |||
| e93408e962 | |||
| 6d193d7cb4 | |||
| fb4fbfb2a8 | |||
| 7e77afe94c | |||
| 7587996279 | |||
| 15b3c0f563 | |||
| 5e341210a1 | |||
| fbea677a5c |
@@ -15,8 +15,6 @@ stages:
|
||||
fedora-x86_64:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v7
|
||||
stage: build
|
||||
variables:
|
||||
WRAP_MODE: default
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
artifacts:
|
||||
@@ -35,31 +33,6 @@ fedora-x86_64:
|
||||
key: "$CI_JOB_NAME"
|
||||
<<: *cache-paths
|
||||
|
||||
all-dependencies:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v7
|
||||
stage: build
|
||||
variables:
|
||||
WRAP_MODE: forcefallback
|
||||
script:
|
||||
- meson wrap promote subprojects/glib/subprojects/libffi.wrap
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
allow_failure: true
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
junit:
|
||||
- "${CI_PROJECT_DIR}/_build/report.xml"
|
||||
name: "gtk-all-deps-${CI_COMMIT_REF_NAME}"
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-list"
|
||||
- "${CI_PROJECT_DIR}/_build/report.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report.html"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*.png"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
<<: *cache-paths
|
||||
|
||||
.mingw-defaults: &mingw-defaults
|
||||
stage: build
|
||||
tags:
|
||||
|
||||
@@ -17,7 +17,6 @@ meson \
|
||||
-Dbroadway-backend=true \
|
||||
-Dvulkan=yes \
|
||||
--werror \
|
||||
--wrap-mode=${WRAP_MODE:-default} \
|
||||
_build $srcdir
|
||||
unset CCACHE_DISABLE
|
||||
|
||||
|
||||
@@ -167,8 +167,8 @@
|
||||
<file>drawingarea.c</file>
|
||||
<file>dnd.c</file>
|
||||
<file>editable_cells.c</file>
|
||||
<file>entry_buffer.c</file>
|
||||
<file>entry_completion.c</file>
|
||||
<file>entry_undo.c</file>
|
||||
<file>expander.c</file>
|
||||
<file>filtermodel.c</file>
|
||||
<file>fishbowl.c</file>
|
||||
@@ -220,6 +220,7 @@
|
||||
<file>spinner.c</file>
|
||||
<file>tabs.c</file>
|
||||
<file>tagged_entry.c</file>
|
||||
<file>textundo.c</file>
|
||||
<file>textview.c</file>
|
||||
<file>textscroll.c</file>
|
||||
<file>theming_style_classes.c</file>
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
/* Entry/Entry Buffer
|
||||
/* Entry/Entry Undo
|
||||
*
|
||||
* GtkEntryBuffer provides the text content in a GtkEntry.
|
||||
* Applications can provide their own buffer implementation,
|
||||
* e.g. to provide secure handling for passwords in memory.
|
||||
* GtkEntry can provide basic Undo/Redo support using standard keyboard
|
||||
* accelerators such as Primary+z to undo and Primary+Shift+z to redo.
|
||||
* Additionally, Primary+y can be used to redo.
|
||||
*
|
||||
* Use gtk_entry_set_enable_undo() to enable undo/redo support.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
GtkWidget *
|
||||
do_entry_buffer (GtkWidget *do_widget)
|
||||
do_entry_undo (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *entry;
|
||||
GtkEntryBuffer *buffer;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
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), "Entry Buffer");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Entry Undo");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
@@ -33,22 +34,13 @@ do_entry_buffer (GtkWidget *do_widget)
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"Entries share a buffer. Typing in one is reflected in the other.");
|
||||
"Use Primary+z or Primary+Shift+z to undo or redo changes");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
/* Create a buffer */
|
||||
buffer = gtk_entry_buffer_new (NULL, 0);
|
||||
|
||||
/* Create our first entry */
|
||||
entry = gtk_entry_new_with_buffer (buffer);
|
||||
/* Create our entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_editable_set_enable_undo (GTK_EDITABLE (entry), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
|
||||
/* Create the second entry */
|
||||
entry = gtk_entry_new_with_buffer (buffer);
|
||||
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
@@ -41,6 +41,7 @@ show_page (GtkTextBuffer *buffer,
|
||||
|
||||
gtk_text_buffer_set_text (buffer, "", 0);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
if (page == 1)
|
||||
{
|
||||
gtk_text_buffer_insert (buffer, &iter, "Some text to show that simple ", -1);
|
||||
@@ -73,6 +74,7 @@ show_page (GtkTextBuffer *buffer,
|
||||
"so that related items of information are connected.\n", -1);
|
||||
insert_link (buffer, &iter, "Go back", 1);
|
||||
}
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
}
|
||||
|
||||
/* Looks at all tags covering the position of iter in the text view,
|
||||
@@ -258,6 +260,7 @@ do_hypertext (GtkWidget *do_widget)
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_enable_undo (buffer, TRUE);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
|
||||
@@ -748,6 +748,9 @@ load_file (const gchar *demoname,
|
||||
|
||||
source_buffer = gtk_text_buffer_new (NULL);
|
||||
|
||||
gtk_text_buffer_begin_irreversible_action (info_buffer);
|
||||
gtk_text_buffer_begin_irreversible_action (source_buffer);
|
||||
|
||||
resource_filename = g_strconcat ("/sources/", filename, NULL);
|
||||
bytes = g_resources_lookup_data (resource_filename, 0, &err);
|
||||
g_free (resource_filename);
|
||||
@@ -880,9 +883,11 @@ load_file (const gchar *demoname,
|
||||
|
||||
fontify (source_buffer);
|
||||
|
||||
gtk_text_buffer_end_irreversible_action (source_buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (source_view), source_buffer);
|
||||
g_object_unref (source_buffer);
|
||||
|
||||
gtk_text_buffer_end_irreversible_action (info_buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (info_view), info_buffer);
|
||||
g_object_unref (info_buffer);
|
||||
}
|
||||
|
||||
@@ -29,8 +29,10 @@ source_toggled (GtkToggleButton *button)
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_delete (buffer, &start, &end);
|
||||
gtk_text_buffer_insert_markup (buffer, &start, markup, -1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
g_free (markup);
|
||||
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (stack), "formatted");
|
||||
@@ -106,11 +108,15 @@ do_markup (GtkWidget *do_widget)
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_insert_markup (buffer, &iter, markup, -1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view2));
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_insert (buffer, &iter, markup, -1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ demos = files([
|
||||
'drawingarea.c',
|
||||
'dnd.c',
|
||||
'editable_cells.c',
|
||||
'entry_buffer.c',
|
||||
'entry_completion.c',
|
||||
'entry_undo.c',
|
||||
'expander.c',
|
||||
'filtermodel.c',
|
||||
'fishbowl.c',
|
||||
@@ -73,6 +73,7 @@ demos = files([
|
||||
'tabs.c',
|
||||
'tagged_entry.c',
|
||||
'textmask.c',
|
||||
'textundo.c',
|
||||
'textview.c',
|
||||
'textscroll.c',
|
||||
'themes.c',
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/* Text View/Undo and Redo
|
||||
*
|
||||
* The GtkTextView supports undo and redo through the use of a
|
||||
* GtkTextBuffer. You can enable or disable undo support using
|
||||
* gtk_text_buffer_set_enable_undo().
|
||||
*
|
||||
* Use Primary+Z to undo and Primary+Shift+Z or Primary+Y to
|
||||
* redo previously undone operations.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h> /* for exit() */
|
||||
|
||||
GtkWidget *
|
||||
do_textundo (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkWidget *sw;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_default_size (GTK_WINDOW (window),
|
||||
450, 450);
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (window), "TextView Undo");
|
||||
|
||||
view = gtk_text_view_new ();
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_enable_undo (buffer, TRUE);
|
||||
|
||||
/* this text cannot be undone */
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
gtk_text_buffer_insert (buffer, &iter,
|
||||
"Type to add more text.\n"
|
||||
"Use Primary+Z to undo and Primary+Shift+Z to redo a previously undone action.\n"
|
||||
"\n",
|
||||
-1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (window), sw);
|
||||
gtk_container_add (GTK_CONTAINER (sw), view);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
{
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_destroy (window);
|
||||
window = NULL;
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -144,6 +144,7 @@ insert_text (GtkTextBuffer *buffer)
|
||||
*/
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
|
||||
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_insert (buffer, &iter,
|
||||
"The text widget can display text with all kinds of nifty attributes. "
|
||||
"It also supports multiple views of the same buffer; this demo is "
|
||||
@@ -377,6 +378,8 @@ insert_text (GtkTextBuffer *buffer)
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
gtk_text_buffer_apply_tag_by_name (buffer, "word_wrap", &start, &end);
|
||||
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,10 +76,10 @@ How to compile GTK itself
|
||||
</para>
|
||||
<para>
|
||||
Several environment variables are useful to pass to set before
|
||||
running configure. <envar>CPPFLAGS</envar> contains options to
|
||||
pass to the C compiler, and is used to tell the compiler where
|
||||
to look for include files. The <envar>LDFLAGS</envar> variable
|
||||
is used in a similar fashion for the linker. Finally the
|
||||
running <application>meson</application>. <envar>CPPFLAGS</envar>
|
||||
contains options to pass to the C compiler, and is used to tell
|
||||
the compiler where to look for include files. The <envar>LDFLAGS</envar>
|
||||
variable is used in a similar fashion for the linker. Finally the
|
||||
<envar>PKG_CONFIG_PATH</envar> environment variable contains
|
||||
a search path that <command>pkg-config</command> (see below)
|
||||
uses when looking for files describing how to compile
|
||||
@@ -106,6 +106,61 @@ How to compile GTK itself
|
||||
export LD_LIBRARY_PATH PATH
|
||||
</programlisting>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="build-types">
|
||||
<title>Build types</title>
|
||||
|
||||
<para>Meson has different build types, exposed by the <literal>buildtype</literal>
|
||||
configuration option. GTK enables and disables functionality depending on
|
||||
the build type used when calling <application>meson</application> to
|
||||
configure the build.</para>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>debug</systemitem> and <systemitem>debugoptimized</systemitem></title>
|
||||
|
||||
<para>
|
||||
GTK will enable debugging code paths in both the
|
||||
<literal>debug</literal> and <literal>debugoptimized</literal>
|
||||
build types. Builds with <literal>buildtype</literal> set
|
||||
to <literal>debug</literal> will additionally enable
|
||||
consistency checks on the internal state of the toolkit.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is recommended to use the <literal>debug</literal> or
|
||||
<literal>debugoptimized</literal> build types when developing
|
||||
GTK itself. Additionally, <literal>debug</literal> builds of
|
||||
GTK are recommended for profiling and debugging GTK applications,
|
||||
as they include additional validation of the internal state.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <literal>debugoptimized</literal> build type is the
|
||||
default for GTK if no build type is specified when calling
|
||||
<application>meson</application>
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>release</systemitem></title>
|
||||
|
||||
<para>
|
||||
The <literal>release</literal> build type will disable
|
||||
debugging code paths and additional run time safeties, like
|
||||
checked casts for object instances.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<para>
|
||||
The <literal>plain</literal> build type provided by Meson
|
||||
should only be used when packaging GTK, and it's expected
|
||||
that packagers will provide their own compiler flags when
|
||||
building GTK. See the previous section for the list of
|
||||
environment variables to be used to define compiler and
|
||||
linker flags.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="dependencies">
|
||||
<title>Dependencies</title>
|
||||
<para>
|
||||
@@ -283,184 +338,181 @@ How to compile GTK itself
|
||||
See <xref linkend="gtk-resources"/> for more information.
|
||||
</para>
|
||||
</refsect1>
|
||||
<refsect1 id="extra-configuration-options">
|
||||
<title>Extra Configuration Options</title>
|
||||
|
||||
<refsect1 id="extra-configuration-options">
|
||||
<title>Extra Configuration Options</title>
|
||||
|
||||
<para>
|
||||
In addition to the normal options provided by Meson, GTK defines
|
||||
various arguments that modify what should be built.
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>meson</command>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dx11-backend=true</arg>
|
||||
<arg choice="plain">-Dx11-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dwayland-backend=true</arg>
|
||||
<arg choice="plain">-Dwayland-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dbroadway-backend=true</arg>
|
||||
<arg choice="plain">-Dbroadway-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dwin32-backend=true</arg>
|
||||
<arg choice="plain">-Dwin32-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dquartz-backend=true</arg>
|
||||
<arg choice="plain">-Dquartz-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dmedia=gstreamer</arg>
|
||||
<arg choice="plain">-Dmedia=ffmpeg</arg>
|
||||
<arg choice="plain">-Dmedia=all</arg>
|
||||
<arg choice="plain">-Dmedia=none</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dvulkan=yes</arg>
|
||||
<arg choice="plain">-Dvulkan=no</arg>
|
||||
<arg choice="plain">-Dvulkan=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dxinerama=yes</arg>
|
||||
<arg choice="plain">-Dxinerama=no</arg>
|
||||
<arg choice="plain">-Dxinerama=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dcloudproviders=true</arg>
|
||||
<arg choice="plain">-Dcloudproviders=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dprint-backends=all</arg>
|
||||
<arg choice="plain">-Dprint-backends=none</arg>
|
||||
<arg choice="plain">-Dprint-backends=cups,lpr,...</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dcolord=yes</arg>
|
||||
<arg choice="plain">-Dcolord=no</arg>
|
||||
<arg choice="plain">-Dcolord=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dgtk_doc=true</arg>
|
||||
<arg choice="plain">-Dgtk_doc=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dman-pages=true</arg>
|
||||
<arg choice="plain">-Dman-pages=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dintrospection=true</arg>
|
||||
<arg choice="plain">-Dintrospection=false</arg>
|
||||
</group>
|
||||
</cmdsynopsis>
|
||||
</para>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>xinerama</systemitem></title>
|
||||
|
||||
<para>
|
||||
In addition to the normal options provided by Meson, GTK defines
|
||||
various arguments that modify what should be built.
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>meson</command>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dx11-backend=true</arg>
|
||||
<arg choice="plain">-Dx11-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dwayland-backend=true</arg>
|
||||
<arg choice="plain">-Dwayland-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dbroadway-backend=true</arg>
|
||||
<arg choice="plain">-Dbroadway-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dwin32-backend=true</arg>
|
||||
<arg choice="plain">-Dwin32-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dquartz-backend=true</arg>
|
||||
<arg choice="plain">-Dquartz-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dmedia=gstreamer</arg>
|
||||
<arg choice="plain">-Dmedia=ffmpeg</arg>
|
||||
<arg choice="plain">-Dmedia=all</arg>
|
||||
<arg choice="plain">-Dmedia=none</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dvulkan=yes</arg>
|
||||
<arg choice="plain">-Dvulkan=no</arg>
|
||||
<arg choice="plain">-Dvulkan=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dxinerama=yes</arg>
|
||||
<arg choice="plain">-Dxinerama=no</arg>
|
||||
<arg choice="plain">-Dxinerama=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dcloudproviders=true</arg>
|
||||
<arg choice="plain">-Dcloudproviders=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dprint-backends=all</arg>
|
||||
<arg choice="plain">-Dprint-backends=none</arg>
|
||||
<arg choice="plain">-Dprint-backends=cups,lpr,...</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dcolord=yes</arg>
|
||||
<arg choice="plain">-Dcolord=no</arg>
|
||||
<arg choice="plain">-Dcolord=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dgtk_doc=true</arg>
|
||||
<arg choice="plain">-Dgtk_doc=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dman-pages=true</arg>
|
||||
<arg choice="plain">-Dman-pages=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dintrospection=true</arg>
|
||||
<arg choice="plain">-Dintrospection=false</arg>
|
||||
</group>
|
||||
</cmdsynopsis>
|
||||
By default GTK will try to link against the Xinerama libraries
|
||||
if they are found. This options can be used to explicitly control
|
||||
whether Xinerama should be used.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>xinerama</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>gtk_doc</systemitem> and
|
||||
<systemitem>man-pages</systemitem></title>
|
||||
|
||||
<para>
|
||||
By default GTK will try to link against the Xinerama libraries
|
||||
if they are found. This options can be used to explicitly control
|
||||
whether Xinerama should be used.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
The <application>gtk-doc</application> package is
|
||||
used to generate the reference documentation included
|
||||
with GTK. By default support for <application>gtk-doc</application>
|
||||
is disabled because it requires various extra dependencies
|
||||
to be installed. If you have
|
||||
<application>gtk-doc</application> installed and
|
||||
are modifying GTK, you may want to enable
|
||||
<application>gtk-doc</application> support by passing
|
||||
in <systemitem>gtk_doc</systemitem>.
|
||||
</para>
|
||||
<para>
|
||||
Additionally, some tools provided by GTK have their own
|
||||
manual pages generated using a similar set of dependencies;
|
||||
if you have <application>xsltproc</application> then you
|
||||
can generate manual pages by passing <systemitem>man-pages</systemitem>
|
||||
when configuring the build.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>gtk_doc</systemitem> and
|
||||
<systemitem>man-pages</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>print-backends</systemitem></title>
|
||||
|
||||
<para>
|
||||
The <application>gtk-doc</application> package is
|
||||
used to generate the reference documentation included
|
||||
with GTK. By default support for <application>gtk-doc</application>
|
||||
is disabled because it requires various extra dependencies
|
||||
to be installed. If you have
|
||||
<application>gtk-doc</application> installed and
|
||||
are modifying GTK, you may want to enable
|
||||
<application>gtk-doc</application> support by passing
|
||||
in <systemitem>gtk_doc</systemitem>.
|
||||
</para>
|
||||
<para>
|
||||
Additionally, some tools provided by GTK have their own
|
||||
manual pages generated using a similar set of dependencies;
|
||||
if you have <application>xsltproc</application> then you
|
||||
can generate manual pages by passing <systemitem>man-pages</systemitem>
|
||||
when configuring the build.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
By default, GTK will try to build various print backends if
|
||||
their dependencies are found. This option can be used to
|
||||
explicitly control which print backends should be built.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>print-backends</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>x11-backend</systemitem>,
|
||||
<systemitem>win32-backend</systemitem>,
|
||||
<systemitem>quartz-backend</systemitem>,
|
||||
<systemitem>broadway-backend</systemitem> and
|
||||
<systemitem>wayland-backend</systemitem></title>
|
||||
|
||||
<para>
|
||||
By default, GTK will try to build various print backends if
|
||||
their dependencies are found. This option can be used to
|
||||
explicitly control which print backends should be built.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
Enable specific backends for GDK. If none of these options
|
||||
are given, the Wayland backend will be enabled by default,
|
||||
if the platform is Linux; the X11 backend will also be enabled
|
||||
by default, unless the platform is Windows, in which case the
|
||||
default is win32, or the platform is macOS, in which case the
|
||||
default is quartz. If any backend is explicitly enabled or disabled,
|
||||
no other platform will be enabled automatically.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>x11-backend</systemitem>,
|
||||
<systemitem>win32-backend</systemitem>,
|
||||
<systemitem>quartz-backend</systemitem>,
|
||||
<systemitem>broadway-backend</systemitem> and
|
||||
<systemitem>wayland-backend</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>introspection</systemitem></title>
|
||||
|
||||
<para>
|
||||
Enable specific backends for GDK. If none of these options
|
||||
are given, the Wayland backend will be enabled by default,
|
||||
if the platform is Linux; the X11 backend will also be enabled
|
||||
by default, unless the platform is Windows, in which case the
|
||||
default is win32, or the platform is macOS, in which case the
|
||||
default is quartz. If any backend is explicitly enabled or disabled,
|
||||
no other platform will be enabled automatically.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
Allows to disable building introspection support. This is option
|
||||
is mainly useful for shortening turnaround times on developer
|
||||
systems. Installed builds of GTK should always have introspection
|
||||
support.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>introspection</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>build-tests</systemitem>,
|
||||
<systemitem>install-tests</systemitem>,
|
||||
<systemitem>demos</systemitem></title>
|
||||
|
||||
<para>
|
||||
Allows to disable building introspection support. This is option
|
||||
is mainly useful for shortening turnaround times on developer
|
||||
systems. Installed builds of GTK should always have introspection
|
||||
support.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
By default, GTK will build quite a few tests and demos.
|
||||
While these are useful on a developer system, they are not
|
||||
needed when GTK is built e.g. for a flatpak runtime. These
|
||||
options allow to disable building tests and demos.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>build-tests</systemitem>,
|
||||
<systemitem>install-tests</systemitem>,
|
||||
<systemitem>demos</systemitem></title>
|
||||
|
||||
<para>
|
||||
By default, GTK will build quite a few tests and demos.
|
||||
While these are useful on a developer system, they are not
|
||||
needed when GTK is built e.g. for a flatpak runtime. These
|
||||
options allow to disable building tests and demos.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
</refsect1>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
<!-- Local Variables: -->
|
||||
<!-- sgml-parent-document: ("gtk-docs.sgml" "chapter" "refentry") -->
|
||||
<!-- End: -->
|
||||
@@ -224,10 +224,3 @@
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: xml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "refentry")
|
||||
End:
|
||||
-->
|
||||
|
||||
@@ -364,10 +364,3 @@
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossary>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "glossary")
|
||||
End:
|
||||
-->
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
<title>GTK Overview</title>
|
||||
<xi:include href="overview.xml"/>
|
||||
<xi:include href="xml/getting_started.xml"/>
|
||||
<xi:include href="resources.sgml" />
|
||||
<xi:include href="xml/question_index.sgml" />
|
||||
<xi:include href="resources.xml" />
|
||||
<xi:include href="xml/question_index.xml" />
|
||||
<xi:include href="xml/drawing-model.xml" />
|
||||
<xi:include href="xml/input-handling.xml" />
|
||||
<xi:include href="xml/actions.xml" />
|
||||
@@ -168,7 +168,7 @@
|
||||
|
||||
<chapter id="TextWidgetObjects">
|
||||
<title>Multiline Text Editor</title>
|
||||
<xi:include href="xml/text_widget.sgml" />
|
||||
<xi:include href="xml/text_widget.xml" />
|
||||
<xi:include href="xml/gtktextiter.xml" />
|
||||
<xi:include href="xml/gtktextmark.xml" />
|
||||
<xi:include href="xml/gtktextbuffer.xml" />
|
||||
@@ -179,7 +179,7 @@
|
||||
|
||||
<chapter id="TreeWidgetObjects">
|
||||
<title>Tree, List and Icon Grid Widgets</title>
|
||||
<xi:include href="xml/tree_widget.sgml" />
|
||||
<xi:include href="xml/tree_widget.xml" />
|
||||
<xi:include href="xml/gtktreemodel.xml" />
|
||||
<xi:include href="xml/gtktreeselection.xml" />
|
||||
<xi:include href="xml/gtktreeviewcolumn.xml" />
|
||||
@@ -407,12 +407,12 @@
|
||||
|
||||
<part id="platform-support">
|
||||
<title>GTK Platform Support</title>
|
||||
<xi:include href="building.sgml" />
|
||||
<xi:include href="xml/compiling.sgml" />
|
||||
<xi:include href="running.sgml" />
|
||||
<xi:include href="x11.sgml" />
|
||||
<xi:include href="windows.sgml" />
|
||||
<xi:include href="osx.sgml" />
|
||||
<xi:include href="building.xml" />
|
||||
<xi:include href="xml/compiling.xml" />
|
||||
<xi:include href="running.xml" />
|
||||
<xi:include href="x11.xml" />
|
||||
<xi:include href="windows.xml" />
|
||||
<xi:include href="osx.xml" />
|
||||
<xi:include href="broadway.xml" />
|
||||
<xi:include href="wayland.xml" />
|
||||
</part>
|
||||
|
||||
@@ -882,6 +882,8 @@ gtk_editable_get_width_chars
|
||||
gtk_editable_set_width_chars
|
||||
gtk_editable_get_max_width_chars
|
||||
gtk_editable_set_max_width_chars
|
||||
gtk_editable_get_enable_undo
|
||||
gtk_editable_set_enable_undo
|
||||
<SUBSECTION>
|
||||
gtk_editable_install_properties
|
||||
gtk_editable_init_delegate
|
||||
@@ -2876,6 +2878,18 @@ gtk_text_buffer_begin_user_action
|
||||
gtk_text_buffer_end_user_action
|
||||
gtk_text_buffer_add_selection_clipboard
|
||||
gtk_text_buffer_remove_selection_clipboard
|
||||
gtk_text_buffer_get_can_undo
|
||||
gtk_text_buffer_get_can_redo
|
||||
gtk_text_buffer_get_enable_undo
|
||||
gtk_text_buffer_set_enable_undo
|
||||
gtk_text_buffer_get_max_undo_levels
|
||||
gtk_text_buffer_set_max_undo_levels
|
||||
gtk_text_buffer_undo
|
||||
gtk_text_buffer_redo
|
||||
gtk_text_buffer_begin_irreversible_action
|
||||
gtk_text_buffer_end_irreversible_action
|
||||
gtk_text_buffer_begin_user_action
|
||||
gtk_text_buffer_end_user_action
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TEXT_BUFFER
|
||||
|
||||
@@ -342,8 +342,8 @@ images = [
|
||||
content_files = [
|
||||
'actions.xml',
|
||||
'broadway.xml',
|
||||
'building.sgml',
|
||||
'compiling.sgml',
|
||||
'building.xml',
|
||||
'compiling.xml',
|
||||
'css-overview.xml',
|
||||
'css-properties.xml',
|
||||
'drawing-model.xml',
|
||||
@@ -361,31 +361,31 @@ content_files = [
|
||||
'input-handling.xml',
|
||||
'migrating-2to4.xml',
|
||||
'migrating-3to4.xml',
|
||||
'osx.sgml',
|
||||
'other_software.sgml',
|
||||
'osx.xml',
|
||||
'other_software.xml',
|
||||
'overview.xml',
|
||||
'question_index.sgml',
|
||||
'resources.sgml',
|
||||
'running.sgml',
|
||||
'text_widget.sgml',
|
||||
'tree_widget.sgml',
|
||||
'question_index.xml',
|
||||
'resources.xml',
|
||||
'running.xml',
|
||||
'text_widget.xml',
|
||||
'tree_widget.xml',
|
||||
'visual_index.xml',
|
||||
'wayland.xml',
|
||||
'windows.sgml',
|
||||
'x11.sgml',
|
||||
'windows.xml',
|
||||
'x11.xml',
|
||||
]
|
||||
|
||||
expand_content_files = [
|
||||
'actions.xml',
|
||||
'compiling.sgml',
|
||||
'compiling.xml',
|
||||
'drawing-model.xml',
|
||||
'glossary.xml',
|
||||
'input-handling.xml',
|
||||
'migrating-2to4.xml',
|
||||
'migrating-3to4.xml',
|
||||
'question_index.sgml',
|
||||
'text_widget.sgml',
|
||||
'tree_widget.sgml',
|
||||
'question_index.xml',
|
||||
'text_widget.xml',
|
||||
'tree_widget.xml',
|
||||
]
|
||||
|
||||
types_conf = configuration_data()
|
||||
|
||||
@@ -813,6 +813,21 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>GtkEntryBuffer ::deleted-text has changed</title>
|
||||
<para>
|
||||
To allow signal handlers to access the deleted text before it
|
||||
has been deleted #GtkEntryBuffer::deleted-text has changed from
|
||||
%G_SIGNAL_RUN_FIRST to %G_SIGNAL_RUN_LAST. The default handler
|
||||
removes the text from the #GtkEntryBuffer.
|
||||
</para>
|
||||
<para>
|
||||
To adapt existing code, use g_signal_connect_after() or
|
||||
%G_CONNECT_AFTER when using g_signal_connect_data() or
|
||||
g_signal_connect_object().
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -112,6 +112,16 @@ multiple bytes in UTF-8, and the two-character sequence "\r\n" is also
|
||||
considered a line separator.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Text buffers support undo and redo if gtk_text_buffer_set_undo_enabled()
|
||||
has been set to %TRUE. Use gtk_text_buffer_undo() or gtk_text_buffer_redo()
|
||||
to perform the necessary action. Note that these operations are ignored if
|
||||
the buffer is not editable. Developers may want some operations to not be
|
||||
undoable. To do this, wrap your changes in
|
||||
gtk_text_buffer_begin_irreversible_action() and
|
||||
gtk_text_buffer_end_irreversible_action().
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -364,12 +364,28 @@ gtk_app_chooser_button_populate (GtkAppChooserButton *self)
|
||||
|
||||
if (default_app != NULL)
|
||||
{
|
||||
get_first_iter (priv->store, &iter);
|
||||
cycled_recommended = TRUE;
|
||||
/* The default app matches all types and sub-types of the
|
||||
* content type we're looking at, whereas the recomended
|
||||
* apps match the content type exactly. If the default app
|
||||
* does not appear in the recommended apps then we might
|
||||
* end up showing a text editor for calendar-related files,
|
||||
* which is not helpful.
|
||||
*
|
||||
* See: https://gitlab.gnome.org/GNOME/gtk/issues/377
|
||||
*/
|
||||
if (g_list_find (recommended_apps, default_app) != NULL)
|
||||
{
|
||||
get_first_iter (priv->store, &iter);
|
||||
cycled_recommended = TRUE;
|
||||
|
||||
insert_one_application (self, default_app, &iter);
|
||||
insert_one_application (self, default_app, &iter);
|
||||
|
||||
g_object_unref (default_app);
|
||||
g_object_unref (default_app);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_clear_object (&default_app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,8 +228,8 @@ gtk_css_value_calc_multiply (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_calc_try_add (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2)
|
||||
gtk_css_value_calc_try_add (GtkCssValue *value1,
|
||||
GtkCssValue *value2)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -235,12 +235,18 @@ gtk_css_value_dimension_multiply (const GtkCssValue *value,
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_dimension_try_add (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2)
|
||||
gtk_css_value_dimension_try_add (GtkCssValue *value1,
|
||||
GtkCssValue *value2)
|
||||
{
|
||||
if (value1->unit != value2->unit)
|
||||
return NULL;
|
||||
|
||||
if (value1->value == 0)
|
||||
return _gtk_css_value_ref (value2);
|
||||
|
||||
if (value2->value == 0)
|
||||
return _gtk_css_value_ref (value1);
|
||||
|
||||
return gtk_css_dimension_value_new (value1->value + value2->value, value1->unit);
|
||||
}
|
||||
|
||||
@@ -304,16 +310,26 @@ gtk_css_dimension_value_new (double value,
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 2 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 3 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 4 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 8 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 16 }, /* Icon size default */
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 32 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 64 },
|
||||
};
|
||||
static GtkCssValue percent_singletons[] = {
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PERCENT, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PERCENT, 50 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PERCENT, 100 },
|
||||
};
|
||||
static GtkCssValue second_singletons[] = {
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_S, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_S, 1 },
|
||||
};
|
||||
static GtkCssValue deg_singletons[] = {
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 0 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 90 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 180 },
|
||||
{ >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 270 },
|
||||
};
|
||||
GtkCssValue *result;
|
||||
|
||||
switch ((guint)unit)
|
||||
@@ -334,17 +350,24 @@ gtk_css_dimension_value_new (double value,
|
||||
value == 3 ||
|
||||
value == 4)
|
||||
return _gtk_css_value_ref (&px_singletons[(int) value]);
|
||||
else if (value == 16)
|
||||
if (value == 8)
|
||||
return _gtk_css_value_ref (&px_singletons[5]);
|
||||
if (value == 16)
|
||||
return _gtk_css_value_ref (&px_singletons[6]);
|
||||
if (value == 32)
|
||||
return _gtk_css_value_ref (&px_singletons[7]);
|
||||
if (value == 64)
|
||||
return _gtk_css_value_ref (&px_singletons[8]);
|
||||
|
||||
break;
|
||||
|
||||
case GTK_CSS_PERCENT:
|
||||
if (value == 0)
|
||||
return _gtk_css_value_ref (&percent_singletons[0]);
|
||||
|
||||
if (value == 100)
|
||||
if (value == 50)
|
||||
return _gtk_css_value_ref (&percent_singletons[1]);
|
||||
if (value == 100)
|
||||
return _gtk_css_value_ref (&percent_singletons[2]);
|
||||
|
||||
break;
|
||||
|
||||
@@ -354,6 +377,18 @@ gtk_css_dimension_value_new (double value,
|
||||
|
||||
break;
|
||||
|
||||
case GTK_CSS_DEG:
|
||||
if (value == 0)
|
||||
return _gtk_css_value_ref (°_singletons[0]);
|
||||
if (value == 90)
|
||||
return _gtk_css_value_ref (°_singletons[1]);
|
||||
if (value == 180)
|
||||
return _gtk_css_value_ref (°_singletons[2]);
|
||||
if (value == 270)
|
||||
return _gtk_css_value_ref (°_singletons[3]);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
@@ -174,24 +174,25 @@ gtk_css_image_recolor_snapshot (GtkCssImage *image,
|
||||
double height)
|
||||
{
|
||||
GtkCssImageRecolor *recolor = GTK_CSS_IMAGE_RECOLOR (image);
|
||||
const GdkRGBA *fg = &recolor->color;
|
||||
const GdkRGBA *sc = &recolor->success;
|
||||
const GdkRGBA *wc = &recolor->warning;
|
||||
const GdkRGBA *ec = &recolor->error;
|
||||
graphene_matrix_t matrix;
|
||||
graphene_vec4_t offset;
|
||||
GdkRGBA fg = recolor->color;
|
||||
GdkRGBA sc = recolor->success;
|
||||
GdkRGBA wc = recolor->warning;
|
||||
GdkRGBA ec = recolor->error;
|
||||
|
||||
if (recolor->texture == NULL)
|
||||
return;
|
||||
|
||||
graphene_matrix_init_from_float (&matrix,
|
||||
(float[16]) {
|
||||
sc.red - fg.red, sc.green - fg.green, sc.blue - fg.blue, 0,
|
||||
wc.red - fg.red, wc.green - fg.green, wc.blue - fg.blue, 0,
|
||||
ec.red - fg.red, ec.green - fg.green, ec.blue - fg.blue, 0,
|
||||
0, 0, 0, fg.alpha
|
||||
sc->red - fg->red, sc->green - fg->green, sc->blue - fg->blue, 0,
|
||||
wc->red - fg->red, wc->green - fg->green, wc->blue - fg->blue, 0,
|
||||
ec->red - fg->red, ec->green - fg->green, ec->blue - fg->blue, 0,
|
||||
0, 0, 0, fg->alpha
|
||||
});
|
||||
graphene_vec4_init (&offset, fg.red, fg.green, fg.blue, 0);
|
||||
|
||||
graphene_vec4_init (&offset, fg->red, fg->green, fg->blue, 0);
|
||||
gtk_snapshot_push_color_matrix (snapshot, &matrix, &offset);
|
||||
|
||||
gtk_snapshot_append_texture (snapshot,
|
||||
|
||||
@@ -66,8 +66,8 @@ gtk_css_number_value_add (GtkCssValue *value1,
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_number_value_try_add (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2)
|
||||
gtk_css_number_value_try_add (GtkCssValue *value1,
|
||||
GtkCssValue *value2)
|
||||
{
|
||||
GtkCssNumberValueClass *number_value_class;
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ struct _GtkCssNumberValueClass {
|
||||
gboolean (* has_percent) (const GtkCssValue *value);
|
||||
GtkCssValue * (* multiply) (const GtkCssValue *value,
|
||||
double factor);
|
||||
GtkCssValue * (* try_add) (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2);
|
||||
GtkCssValue * (* try_add) (GtkCssValue *value1,
|
||||
GtkCssValue *value2);
|
||||
gint (* get_calc_term_order) (const GtkCssValue *value);
|
||||
};
|
||||
|
||||
@@ -67,8 +67,8 @@ GtkCssValue * gtk_css_number_value_multiply (const GtkCssValue *val
|
||||
double factor);
|
||||
GtkCssValue * gtk_css_number_value_add (GtkCssValue *value1,
|
||||
GtkCssValue *value2);
|
||||
GtkCssValue * gtk_css_number_value_try_add (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2);
|
||||
GtkCssValue * gtk_css_number_value_try_add (GtkCssValue *value1,
|
||||
GtkCssValue *value2);
|
||||
gint gtk_css_number_value_get_calc_term_order (const GtkCssValue *value);
|
||||
|
||||
double _gtk_css_number_value_get (const GtkCssValue *number,
|
||||
|
||||
@@ -107,9 +107,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_RGBA = {
|
||||
gtk_css_value_rgba_print
|
||||
};
|
||||
|
||||
static GtkCssValue transparent_black_singleton = (GtkCssValue) { >K_CSS_VALUE_RGBA, 1, { 0, 0, 0, 0 }};
|
||||
static GtkCssValue transparent_white_singleton = (GtkCssValue) { >K_CSS_VALUE_RGBA, 1, { 1, 1, 1, 0 }};
|
||||
static GtkCssValue opaque_white_singleton = (GtkCssValue) { >K_CSS_VALUE_RGBA, 1, { 1, 1, 1, 1 }};
|
||||
static GtkCssValue transparent_black_singleton = { >K_CSS_VALUE_RGBA, 1, { 0, 0, 0, 0 }};
|
||||
static GtkCssValue transparent_white_singleton = { >K_CSS_VALUE_RGBA, 1, { 1, 1, 1, 0 }};
|
||||
static GtkCssValue opaque_white_singleton = { >K_CSS_VALUE_RGBA, 1, { 1, 1, 1, 1 }};
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_rgba_value_new_from_rgba (const GdkRGBA *rgba)
|
||||
|
||||
@@ -379,6 +379,13 @@ gtk_editable_default_init (GtkEditableInterface *iface)
|
||||
0,
|
||||
GTK_PARAM_READABLE));
|
||||
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_boolean ("enable-undo",
|
||||
P_("Enable Undo"),
|
||||
P_("If undo/redo should be enabled for the editable"),
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_int ("selection-bound",
|
||||
P_("Selection Bound"),
|
||||
@@ -835,6 +842,46 @@ gtk_editable_set_max_width_chars (GtkEditable *editable,
|
||||
g_object_set (editable, "max-width-chars", n_chars, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_editable_get_enable_undo:
|
||||
* @editable: a #GtkEditable
|
||||
*
|
||||
* Gets if undo/redo actions are enabled for @editable
|
||||
*
|
||||
* Returns: %TRUE if undo is enabled
|
||||
*/
|
||||
gboolean
|
||||
gtk_editable_get_enable_undo (GtkEditable *editable)
|
||||
{
|
||||
gboolean enable_undo;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_EDITABLE (editable), 0);
|
||||
|
||||
g_object_get (editable, "enable-undo", &enable_undo, NULL);
|
||||
|
||||
return enable_undo;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_editable_set_enable_undo:
|
||||
* @editable: a #GtkEditable
|
||||
* @enable_undo: if undo/redo should be enabled
|
||||
*
|
||||
* If enabled, changes to @editable will be saved for undo/redo actions.
|
||||
*
|
||||
* This results in an additional copy of text changes and are not stored in
|
||||
* secure memory. As such, undo is forcefully disabled when #GtkText:visibility
|
||||
* is set to %FALSE.
|
||||
*/
|
||||
void
|
||||
gtk_editable_set_enable_undo (GtkEditable *editable,
|
||||
gboolean enable_undo)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_EDITABLE (editable));
|
||||
|
||||
g_object_set (editable, "enable-undo", enable_undo, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_editable_install_properties:
|
||||
* @object_class: a #GObjectClass
|
||||
@@ -869,6 +916,7 @@ gtk_editable_install_properties (GObjectClass *object_class,
|
||||
g_object_class_override_property (object_class, first_prop + GTK_EDITABLE_PROP_WIDTH_CHARS, "width-chars");
|
||||
g_object_class_override_property (object_class, first_prop + GTK_EDITABLE_PROP_MAX_WIDTH_CHARS, "max-width-chars");
|
||||
g_object_class_override_property (object_class, first_prop + GTK_EDITABLE_PROP_XALIGN, "xalign");
|
||||
g_object_class_override_property (object_class, first_prop + GTK_EDITABLE_PROP_ENABLE_UNDO, "enable-undo");
|
||||
|
||||
return GTK_EDITABLE_NUM_PROPERTIES;
|
||||
}
|
||||
@@ -982,6 +1030,10 @@ gtk_editable_delegate_set_property (GObject *object,
|
||||
gtk_editable_set_alignment (delegate, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
case GTK_EDITABLE_PROP_ENABLE_UNDO:
|
||||
gtk_editable_set_enable_undo (delegate, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1054,6 +1106,10 @@ gtk_editable_delegate_get_property (GObject *object,
|
||||
g_value_set_float (value, gtk_editable_get_alignment (delegate));
|
||||
break;
|
||||
|
||||
case GTK_EDITABLE_PROP_ENABLE_UNDO:
|
||||
g_value_set_boolean (value, gtk_editable_get_enable_undo (delegate));
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -138,6 +138,11 @@ int gtk_editable_get_max_width_chars (GtkEditable *editable);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_editable_set_max_width_chars (GtkEditable *editable,
|
||||
int n_chars);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_editable_get_enable_undo (GtkEditable *editable);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_editable_set_enable_undo (GtkEditable *editable,
|
||||
gboolean enable_undo);
|
||||
|
||||
/* api for implementations */
|
||||
|
||||
@@ -149,6 +154,7 @@ typedef enum {
|
||||
GTK_EDITABLE_PROP_WIDTH_CHARS,
|
||||
GTK_EDITABLE_PROP_MAX_WIDTH_CHARS,
|
||||
GTK_EDITABLE_PROP_XALIGN,
|
||||
GTK_EDITABLE_PROP_ENABLE_UNDO,
|
||||
GTK_EDITABLE_NUM_PROPERTIES
|
||||
} GtkEditableProperties;
|
||||
|
||||
|
||||
+22
-20
@@ -192,7 +192,6 @@ gtk_entry_buffer_normal_delete_text (GtkEntryBuffer *buffer,
|
||||
guint n_chars)
|
||||
{
|
||||
GtkEntryBufferPrivate *pv = gtk_entry_buffer_get_instance_private (buffer);
|
||||
gsize start, end;
|
||||
|
||||
if (position > pv->normal_text_chars)
|
||||
position = pv->normal_text_chars;
|
||||
@@ -200,23 +199,7 @@ gtk_entry_buffer_normal_delete_text (GtkEntryBuffer *buffer,
|
||||
n_chars = pv->normal_text_chars - position;
|
||||
|
||||
if (n_chars > 0)
|
||||
{
|
||||
start = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text;
|
||||
end = g_utf8_offset_to_pointer (pv->normal_text, position + n_chars) - pv->normal_text;
|
||||
|
||||
memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end);
|
||||
pv->normal_text_chars -= n_chars;
|
||||
pv->normal_text_bytes -= (end - start);
|
||||
|
||||
/*
|
||||
* Could be a password, make sure we don't leave anything sensitive after
|
||||
* the terminating zero. Note, that the terminating zero already trashed
|
||||
* one byte.
|
||||
*/
|
||||
trash_area (pv->normal_text + pv->normal_text_bytes + 1, end - start - 1);
|
||||
|
||||
gtk_entry_buffer_emit_deleted_text (buffer, position, n_chars);
|
||||
}
|
||||
gtk_entry_buffer_emit_deleted_text (buffer, position, n_chars);
|
||||
|
||||
return n_chars;
|
||||
}
|
||||
@@ -240,6 +223,23 @@ gtk_entry_buffer_real_deleted_text (GtkEntryBuffer *buffer,
|
||||
guint position,
|
||||
guint n_chars)
|
||||
{
|
||||
GtkEntryBufferPrivate *pv = gtk_entry_buffer_get_instance_private (buffer);
|
||||
gsize start, end;
|
||||
|
||||
start = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text;
|
||||
end = g_utf8_offset_to_pointer (pv->normal_text, position + n_chars) - pv->normal_text;
|
||||
|
||||
memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end);
|
||||
pv->normal_text_chars -= n_chars;
|
||||
pv->normal_text_bytes -= (end - start);
|
||||
|
||||
/*
|
||||
* Could be a password, make sure we don't leave anything sensitive after
|
||||
* the terminating zero. Note, that the terminating zero already trashed
|
||||
* one byte.
|
||||
*/
|
||||
trash_area (pv->normal_text + pv->normal_text_bytes + 1, end - start - 1);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (buffer), entry_buffer_props[PROP_TEXT]);
|
||||
g_object_notify_by_pspec (G_OBJECT (buffer), entry_buffer_props[PROP_LENGTH]);
|
||||
}
|
||||
@@ -405,11 +405,13 @@ gtk_entry_buffer_class_init (GtkEntryBufferClass *klass)
|
||||
* @position: the position the text was deleted at.
|
||||
* @n_chars: The number of characters that were deleted.
|
||||
*
|
||||
* This signal is emitted after text is deleted from the buffer.
|
||||
* The text is altered in the default handler for this signal. If you want
|
||||
* access to the text after the text has been modified, use
|
||||
* %G_CONNECT_AFTER.
|
||||
*/
|
||||
signals[DELETED_TEXT] = g_signal_new (I_("deleted-text"),
|
||||
GTK_TYPE_ENTRY_BUFFER,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkEntryBufferClass, deleted_text),
|
||||
NULL, NULL,
|
||||
_gtk_marshal_VOID__UINT_UINT,
|
||||
|
||||
+5
-2
@@ -818,10 +818,11 @@ gtk_header_bar_dispose (GObject *object)
|
||||
|
||||
g_clear_pointer (&priv->custom_title, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->label_box, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->start_box, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->end_box, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (gtk_header_bar_parent_class)->dispose (object);
|
||||
|
||||
g_clear_pointer (&priv->start_box, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->end_box, gtk_widget_unparent);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -981,11 +982,13 @@ gtk_header_bar_remove (GtkContainer *container,
|
||||
|
||||
if (parent == priv->start_box)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (widget, notify_child_cb, bar);
|
||||
gtk_container_remove (GTK_CONTAINER (priv->start_box), widget);
|
||||
removed = TRUE;
|
||||
}
|
||||
else if (parent == priv->end_box)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (widget, notify_child_cb, bar);
|
||||
gtk_container_remove (GTK_CONTAINER (priv->end_box), widget);
|
||||
removed = TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
#ifndef __GTK_ISTRING_PRIVATE_H__
|
||||
#define __GTK_ISTRING_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint n_bytes;
|
||||
guint n_chars;
|
||||
union {
|
||||
char buf[24];
|
||||
char *str;
|
||||
} u;
|
||||
} IString;
|
||||
|
||||
static inline gboolean
|
||||
istring_is_inline (const IString *str)
|
||||
{
|
||||
return str->n_bytes <= (sizeof str->u.buf - 1);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
istring_str (IString *str)
|
||||
{
|
||||
if (istring_is_inline (str))
|
||||
return str->u.buf;
|
||||
else
|
||||
return str->u.str;
|
||||
}
|
||||
|
||||
static inline void
|
||||
istring_clear (IString *str)
|
||||
{
|
||||
if (istring_is_inline (str))
|
||||
str->u.buf[0] = 0;
|
||||
else
|
||||
g_clear_pointer (&str->u.str, g_free);
|
||||
|
||||
str->n_bytes = 0;
|
||||
str->n_chars = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
istring_set (IString *str,
|
||||
const char *text,
|
||||
guint n_bytes,
|
||||
guint n_chars)
|
||||
{
|
||||
if G_LIKELY (n_bytes <= (sizeof str->u.buf - 1))
|
||||
{
|
||||
memcpy (str->u.buf, text, n_bytes);
|
||||
str->u.buf[n_bytes] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
str->u.str = g_strndup (text, n_bytes);
|
||||
}
|
||||
|
||||
str->n_bytes = n_bytes;
|
||||
str->n_chars = n_chars;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
istring_empty (IString *str)
|
||||
{
|
||||
return str->n_bytes == 0;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
istring_ends_with_space (IString *str)
|
||||
{
|
||||
return g_ascii_isspace (istring_str (str)[str->n_bytes - 1]);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
istring_starts_with_space (IString *str)
|
||||
{
|
||||
return g_unichar_isspace (g_utf8_get_char (istring_str (str)));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
istring_contains_unichar (IString *str,
|
||||
gunichar ch)
|
||||
{
|
||||
return g_utf8_strchr (istring_str (str), str->n_bytes, ch) != NULL;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
istring_only_contains_space (IString *str)
|
||||
{
|
||||
const char *iter;
|
||||
|
||||
for (iter = istring_str (str); *iter; iter = g_utf8_next_char (iter))
|
||||
{
|
||||
if (!g_unichar_isspace (g_utf8_get_char (iter)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
istring_contains_space (IString *str)
|
||||
{
|
||||
const char *iter;
|
||||
|
||||
for (iter = istring_str (str); *iter; iter = g_utf8_next_char (iter))
|
||||
{
|
||||
if (g_unichar_isspace (g_utf8_get_char (iter)))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
istring_prepend (IString *str,
|
||||
IString *other)
|
||||
{
|
||||
if G_LIKELY (str->n_bytes + other->n_bytes < sizeof str->u.buf - 1)
|
||||
{
|
||||
memmove (str->u.buf + other->n_bytes, str->u.buf, str->n_bytes);
|
||||
memcpy (str->u.buf, other->u.buf, other->n_bytes);
|
||||
str->n_bytes += other->n_bytes;
|
||||
str->n_chars += other->n_chars;
|
||||
str->u.buf[str->n_bytes] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *old = NULL;
|
||||
|
||||
if (!istring_is_inline (str))
|
||||
old = str->u.str;
|
||||
|
||||
str->u.str = g_strconcat (istring_str (str), istring_str (other), NULL);
|
||||
str->n_bytes += other->n_bytes;
|
||||
str->n_chars += other->n_chars;
|
||||
|
||||
g_free (old);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
istring_append (IString *str,
|
||||
IString *other)
|
||||
{
|
||||
const gchar *text = istring_str (other);
|
||||
guint n_bytes = other->n_bytes;
|
||||
guint n_chars = other->n_chars;
|
||||
|
||||
if G_LIKELY (istring_is_inline (str))
|
||||
{
|
||||
if G_LIKELY (str->n_bytes + n_bytes <= (sizeof str->u.buf - 1))
|
||||
memcpy (str->u.buf + str->n_bytes, text, n_bytes);
|
||||
else
|
||||
str->u.str = g_strconcat (str->u.buf, text, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
str->u.str = g_realloc (str->u.str, str->n_bytes + n_bytes + 1);
|
||||
memcpy (str->u.str + str->n_bytes, text, n_bytes);
|
||||
}
|
||||
|
||||
str->n_bytes += n_bytes;
|
||||
str->n_chars += n_chars;
|
||||
|
||||
istring_str (str)[str->n_bytes] = 0;
|
||||
}
|
||||
|
||||
#endif /* __GTK_ISTRING_PRIVATE_H__ */
|
||||
+3
-38
@@ -113,6 +113,7 @@
|
||||
#include "gtkeventcontrollerkey.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkbindings.h"
|
||||
#include "gtkbinlayout.h"
|
||||
#include "gtkenums.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkmnemonichash.h"
|
||||
@@ -504,39 +505,6 @@ surface_moved_to_rect (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
measure_contents (GtkGizmo *gizmo,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkPopover *popover = GTK_POPOVER (gtk_widget_get_parent (GTK_WIDGET (gizmo)));
|
||||
GtkWidget *child = gtk_bin_get_child (GTK_BIN (popover));
|
||||
|
||||
if (child)
|
||||
gtk_widget_measure (child, orientation, for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
allocate_contents (GtkGizmo *gizmo,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkPopover *popover = GTK_POPOVER (gtk_widget_get_parent (GTK_WIDGET (gizmo)));
|
||||
GtkWidget *child = gtk_bin_get_child (GTK_BIN (popover));
|
||||
|
||||
if (child)
|
||||
gtk_widget_size_allocate (child,
|
||||
&(GtkAllocation) { 0, 0, width, height
|
||||
}, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_activate_default (GtkPopover *popover)
|
||||
{
|
||||
@@ -622,11 +590,8 @@ gtk_popover_init (GtkPopover *popover)
|
||||
G_CALLBACK (node_style_changed_cb), popover, 0);
|
||||
g_object_unref (priv->arrow_node);
|
||||
|
||||
priv->contents_widget = gtk_gizmo_new ("contents",
|
||||
measure_contents,
|
||||
allocate_contents,
|
||||
NULL,
|
||||
NULL);
|
||||
priv->contents_widget = gtk_gizmo_new ("contents", NULL, NULL, NULL, NULL);
|
||||
gtk_widget_set_layout_manager (priv->contents_widget, gtk_bin_layout_new ());
|
||||
gtk_widget_set_parent (priv->contents_widget, GTK_WIDGET (popover));
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (popover));
|
||||
|
||||
+18
-18
@@ -337,8 +337,8 @@ static void gtk_scrolled_window_get_property (GObject *objec
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_scrolled_window_dispose (GObject *object);
|
||||
|
||||
static void gtk_scrolled_window_destroy (GtkWidget *widget);
|
||||
static void gtk_scrolled_window_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot);
|
||||
static void gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
@@ -519,17 +519,14 @@ static void
|
||||
gtk_scrolled_window_class_init (GtkScrolledWindowClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class;
|
||||
GtkContainerClass *container_class;
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
|
||||
GtkBindingSet *binding_set;
|
||||
|
||||
widget_class = (GtkWidgetClass*) class;
|
||||
container_class = (GtkContainerClass*) class;
|
||||
|
||||
gobject_class->set_property = gtk_scrolled_window_set_property;
|
||||
gobject_class->get_property = gtk_scrolled_window_get_property;
|
||||
gobject_class->dispose = gtk_scrolled_window_dispose;
|
||||
|
||||
widget_class->destroy = gtk_scrolled_window_destroy;
|
||||
widget_class->snapshot = gtk_scrolled_window_snapshot;
|
||||
widget_class->size_allocate = gtk_scrolled_window_size_allocate;
|
||||
widget_class->focus = gtk_scrolled_window_focus;
|
||||
@@ -2573,24 +2570,27 @@ gtk_scrolled_window_get_capture_button_press (GtkScrolledWindow *scrolled_window
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrolled_window_destroy (GtkWidget *widget)
|
||||
gtk_scrolled_window_dispose (GObject *object)
|
||||
{
|
||||
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
|
||||
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window);
|
||||
GtkScrolledWindow *self = GTK_SCROLLED_WINDOW (object);
|
||||
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (self);
|
||||
GtkWidget *child;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||
child = gtk_bin_get_child (GTK_BIN (self));
|
||||
if (child)
|
||||
gtk_widget_destroy (child);
|
||||
{
|
||||
gtk_widget_unparent (child);
|
||||
_gtk_bin_set_child (GTK_BIN (self), NULL);
|
||||
}
|
||||
|
||||
remove_indicator (scrolled_window, &priv->hindicator);
|
||||
remove_indicator (scrolled_window, &priv->vindicator);
|
||||
remove_indicator (self, &priv->hindicator);
|
||||
remove_indicator (self, &priv->vindicator);
|
||||
|
||||
if (priv->hscrollbar)
|
||||
{
|
||||
GtkAdjustment *hadjustment = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->hscrollbar));
|
||||
|
||||
g_signal_handlers_disconnect_by_data (hadjustment, scrolled_window);
|
||||
g_signal_handlers_disconnect_by_data (hadjustment, self);
|
||||
g_signal_handlers_disconnect_by_data (hadjustment, &priv->hindicator);
|
||||
|
||||
gtk_widget_unparent (priv->hscrollbar);
|
||||
@@ -2601,7 +2601,7 @@ gtk_scrolled_window_destroy (GtkWidget *widget)
|
||||
{
|
||||
GtkAdjustment *vadjustment = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->vscrollbar));
|
||||
|
||||
g_signal_handlers_disconnect_by_data (vadjustment, scrolled_window);
|
||||
g_signal_handlers_disconnect_by_data (vadjustment, self);
|
||||
g_signal_handlers_disconnect_by_data (vadjustment, &priv->vindicator);
|
||||
|
||||
gtk_widget_unparent (priv->vscrollbar);
|
||||
@@ -2610,7 +2610,7 @@ gtk_scrolled_window_destroy (GtkWidget *widget)
|
||||
|
||||
if (priv->deceleration_id)
|
||||
{
|
||||
gtk_widget_remove_tick_callback (widget, priv->deceleration_id);
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (self), priv->deceleration_id);
|
||||
priv->deceleration_id = 0;
|
||||
}
|
||||
|
||||
@@ -2620,7 +2620,7 @@ gtk_scrolled_window_destroy (GtkWidget *widget)
|
||||
priv->scroll_events_overshoot_id = 0;
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->destroy (widget);
|
||||
G_OBJECT_CLASS (gtk_scrolled_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+171
@@ -58,6 +58,7 @@
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtktexthandleprivate.h"
|
||||
#include "gtktexthistoryprivate.h"
|
||||
#include "gtktextutil.h"
|
||||
#include "gtktooltip.h"
|
||||
#include "gtktreeselection.h"
|
||||
@@ -135,6 +136,8 @@
|
||||
|
||||
#define UNDERSHOOT_SIZE 20
|
||||
|
||||
#define DEFAULT_MAX_UNDO 200
|
||||
|
||||
static GQuark quark_password_hint = 0;
|
||||
|
||||
typedef struct _GtkTextPasswordHint GtkTextPasswordHint;
|
||||
@@ -175,6 +178,8 @@ struct _GtkTextPrivate
|
||||
GtkWidget *popup_menu;
|
||||
GMenuModel *extra_menu;
|
||||
|
||||
GtkTextHistory *history;
|
||||
|
||||
float xalign;
|
||||
|
||||
int ascent; /* font ascent in pango units */
|
||||
@@ -559,6 +564,29 @@ static void gtk_text_activate_selection_select_all (GtkWidget *widget,
|
||||
static void gtk_text_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_real_undo (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameters);
|
||||
static void gtk_text_real_redo (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameters);
|
||||
static void gtk_text_history_change_state_cb (gpointer funcs_data,
|
||||
gboolean is_modified,
|
||||
gboolean can_undo,
|
||||
gboolean can_redo);
|
||||
static void gtk_text_history_insert_cb (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *text,
|
||||
guint len);
|
||||
static void gtk_text_history_delete_cb (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *expected_text,
|
||||
guint len);
|
||||
static void gtk_text_history_select_cb (gpointer funcs_data,
|
||||
int selection_insert,
|
||||
int selection_bound);
|
||||
|
||||
/* GtkTextContent implementation
|
||||
*/
|
||||
@@ -645,6 +673,13 @@ gtk_text_content_init (GtkTextContent *content)
|
||||
/* GtkText
|
||||
*/
|
||||
|
||||
static const GtkTextHistoryFuncs history_funcs = {
|
||||
gtk_text_history_change_state_cb,
|
||||
gtk_text_history_insert_cb,
|
||||
gtk_text_history_delete_cb,
|
||||
gtk_text_history_select_cb,
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkText, gtk_text, GTK_TYPE_WIDGET,
|
||||
G_ADD_PRIVATE (GtkText)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, gtk_text_editable_init))
|
||||
@@ -1173,6 +1208,9 @@ gtk_text_class_init (GtkTextClass *class)
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "text.undo", NULL, gtk_text_real_undo);
|
||||
gtk_widget_class_install_action (widget_class, "text.redo", NULL, gtk_text_real_redo);
|
||||
|
||||
/*
|
||||
* Key bindings
|
||||
*/
|
||||
@@ -1346,6 +1384,14 @@ gtk_text_class_init (GtkTextClass *class)
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_semicolon, GDK_CONTROL_MASK,
|
||||
"insert-emoji", 0);
|
||||
|
||||
/* Undo/Redo */
|
||||
gtk_binding_entry_add_action (binding_set, GDK_KEY_z, GDK_CONTROL_MASK,
|
||||
"text.undo", NULL);
|
||||
gtk_binding_entry_add_action (binding_set, GDK_KEY_y, GDK_CONTROL_MASK,
|
||||
"text.redo", NULL);
|
||||
gtk_binding_entry_add_action (binding_set, GDK_KEY_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
|
||||
"text.redo", NULL);
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_TEXT_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, I_("text"));
|
||||
|
||||
@@ -1447,6 +1493,14 @@ gtk_text_set_property (GObject *object,
|
||||
gtk_text_set_alignment (self, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
case NUM_PROPERTIES + GTK_EDITABLE_PROP_ENABLE_UNDO:
|
||||
if (g_value_get_boolean (value) != gtk_text_history_get_enabled (priv->history))
|
||||
{
|
||||
gtk_text_history_set_enabled (priv->history, g_value_get_boolean (value));
|
||||
g_object_notify_by_pspec (object, pspec);
|
||||
}
|
||||
break;
|
||||
|
||||
/* GtkText properties */
|
||||
case PROP_BUFFER:
|
||||
gtk_text_set_buffer (self, g_value_get_object (value));
|
||||
@@ -1578,6 +1632,10 @@ gtk_text_get_property (GObject *object,
|
||||
g_value_set_float (value, priv->xalign);
|
||||
break;
|
||||
|
||||
case NUM_PROPERTIES + GTK_EDITABLE_PROP_ENABLE_UNDO:
|
||||
g_value_set_boolean (value, gtk_text_history_get_enabled (priv->history));
|
||||
break;
|
||||
|
||||
/* GtkText properties */
|
||||
case PROP_BUFFER:
|
||||
g_value_set_object (value, get_buffer (self));
|
||||
@@ -1678,6 +1736,9 @@ gtk_text_init (GtkText *self)
|
||||
priv->xalign = 0.0;
|
||||
priv->insert_pos = -1;
|
||||
priv->cursor_alpha = 1.0;
|
||||
priv->history = gtk_text_history_new (&history_funcs, self);
|
||||
|
||||
gtk_text_history_set_max_undo_levels (priv->history, DEFAULT_MAX_UNDO);
|
||||
|
||||
priv->selection_content = g_object_new (GTK_TYPE_TEXT_CONTENT, NULL);
|
||||
GTK_TEXT_CONTENT (priv->selection_content)->self = self;
|
||||
@@ -1812,6 +1873,7 @@ gtk_text_finalize (GObject *object)
|
||||
|
||||
g_clear_object (&priv->selection_content);
|
||||
|
||||
g_clear_object (&priv->history);
|
||||
g_clear_object (&priv->cached_layout);
|
||||
g_clear_object (&priv->im_context);
|
||||
g_clear_pointer (&priv->magnifier_popover, gtk_widget_destroy);
|
||||
@@ -3344,6 +3406,8 @@ buffer_inserted_text (GtkEntryBuffer *buffer,
|
||||
gtk_text_set_positions (self, current_pos, selection_bound);
|
||||
gtk_text_recompute (self);
|
||||
|
||||
gtk_text_history_text_inserted (priv->history, position, chars, -1);
|
||||
|
||||
/* Calculate the password hint if it needs to be displayed. */
|
||||
if (n_chars == 1 && !priv->visible)
|
||||
{
|
||||
@@ -3381,6 +3445,35 @@ buffer_deleted_text (GtkEntryBuffer *buffer,
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
guint end_pos = position + n_chars;
|
||||
|
||||
if (gtk_text_history_get_enabled (priv->history))
|
||||
{
|
||||
char *deleted_text;
|
||||
|
||||
deleted_text = gtk_editable_get_chars (GTK_EDITABLE (self),
|
||||
position,
|
||||
end_pos);
|
||||
gtk_text_history_selection_changed (priv->history,
|
||||
priv->current_pos,
|
||||
priv->selection_bound);
|
||||
gtk_text_history_text_deleted (priv->history,
|
||||
position,
|
||||
end_pos,
|
||||
deleted_text,
|
||||
-1);
|
||||
|
||||
g_free (deleted_text);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_deleted_text_after (GtkEntryBuffer *buffer,
|
||||
guint position,
|
||||
guint n_chars,
|
||||
GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
guint end_pos = position + n_chars;
|
||||
int selection_bound;
|
||||
guint current_pos;
|
||||
|
||||
@@ -3435,6 +3528,7 @@ buffer_connect_signals (GtkText *self)
|
||||
{
|
||||
g_signal_connect (get_buffer (self), "inserted-text", G_CALLBACK (buffer_inserted_text), self);
|
||||
g_signal_connect (get_buffer (self), "deleted-text", G_CALLBACK (buffer_deleted_text), self);
|
||||
g_signal_connect_after (get_buffer (self), "deleted-text", G_CALLBACK (buffer_deleted_text_after), self);
|
||||
g_signal_connect (get_buffer (self), "notify::text", G_CALLBACK (buffer_notify_text), self);
|
||||
g_signal_connect (get_buffer (self), "notify::max-length", G_CALLBACK (buffer_notify_max_length), self);
|
||||
}
|
||||
@@ -3444,6 +3538,7 @@ buffer_disconnect_signals (GtkText *self)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (self), buffer_inserted_text, self);
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (self), buffer_deleted_text, self);
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (self), buffer_deleted_text_after, self);
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (self), buffer_notify_text, self);
|
||||
g_signal_handlers_disconnect_by_func (get_buffer (self), buffer_notify_max_length, self);
|
||||
}
|
||||
@@ -5236,6 +5331,7 @@ static void
|
||||
gtk_text_set_text (GtkText *self,
|
||||
const char *text)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
int tmp_pos;
|
||||
|
||||
g_return_if_fail (GTK_IS_TEXT (self));
|
||||
@@ -5247,6 +5343,8 @@ gtk_text_set_text (GtkText *self,
|
||||
if (strcmp (gtk_entry_buffer_get_text (get_buffer (self)), text) == 0)
|
||||
return;
|
||||
|
||||
gtk_text_history_begin_irreversible_action (priv->history);
|
||||
|
||||
begin_change (self);
|
||||
g_object_freeze_notify (G_OBJECT (self));
|
||||
gtk_text_delete_text (self, 0, -1);
|
||||
@@ -5254,6 +5352,8 @@ gtk_text_set_text (GtkText *self,
|
||||
gtk_text_insert_text (self, text, strlen (text), &tmp_pos);
|
||||
g_object_thaw_notify (G_OBJECT (self));
|
||||
end_change (self);
|
||||
|
||||
gtk_text_history_end_irreversible_action (priv->history);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5293,6 +5393,9 @@ gtk_text_set_visibility (GtkText *self,
|
||||
g_object_notify (G_OBJECT (self), "visibility");
|
||||
gtk_text_recompute (self);
|
||||
|
||||
/* disable undo when invisible text is used */
|
||||
gtk_text_history_set_enabled (priv->history, visible);
|
||||
|
||||
gtk_text_update_clipboard_actions (self);
|
||||
}
|
||||
}
|
||||
@@ -6815,3 +6918,71 @@ gtk_text_get_extra_menu (GtkText *self)
|
||||
|
||||
return priv->extra_menu;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_real_undo (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameters)
|
||||
{
|
||||
GtkText *text = GTK_TEXT (widget);
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (text);
|
||||
|
||||
gtk_text_history_undo (priv->history);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_real_redo (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameters)
|
||||
{
|
||||
GtkText *text = GTK_TEXT (widget);
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (text);
|
||||
|
||||
gtk_text_history_redo (priv->history);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_history_change_state_cb (gpointer funcs_data,
|
||||
gboolean is_modified,
|
||||
gboolean can_undo,
|
||||
gboolean can_redo)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_history_insert_cb (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *str,
|
||||
guint len)
|
||||
{
|
||||
GtkText *text = funcs_data;
|
||||
int location = begin;
|
||||
|
||||
gtk_editable_insert_text (GTK_EDITABLE (text), str, len, &location);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_history_delete_cb (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *expected_text,
|
||||
guint len)
|
||||
{
|
||||
GtkText *text = funcs_data;
|
||||
|
||||
gtk_editable_delete_text (GTK_EDITABLE (text), begin, end);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_history_select_cb (gpointer funcs_data,
|
||||
int selection_insert,
|
||||
int selection_bound)
|
||||
{
|
||||
GtkText *text = funcs_data;
|
||||
|
||||
gtk_editable_select_region (GTK_EDITABLE (text),
|
||||
selection_insert,
|
||||
selection_bound);
|
||||
}
|
||||
|
||||
+419
-7
@@ -30,6 +30,7 @@
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtktextbuffer.h"
|
||||
#include "gtktexthistoryprivate.h"
|
||||
#include "gtktextbufferprivate.h"
|
||||
#include "gtktextbtree.h"
|
||||
#include "gtktextiterprivate.h"
|
||||
@@ -38,6 +39,8 @@
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
#define DEFAULT_MAX_UNDO 200
|
||||
|
||||
/**
|
||||
* SECTION:gtktextbuffer
|
||||
* @Short_description: Stores attributed text for display in a GtkTextView
|
||||
@@ -62,11 +65,15 @@ struct _GtkTextBufferPrivate
|
||||
|
||||
GtkTextLogAttrCache *log_attr_cache;
|
||||
|
||||
GtkTextHistory *history;
|
||||
|
||||
guint user_action_count;
|
||||
|
||||
/* Whether the buffer has been modified since last save */
|
||||
guint modified : 1;
|
||||
guint has_selection : 1;
|
||||
guint can_undo : 1;
|
||||
guint can_redo : 1;
|
||||
};
|
||||
|
||||
typedef struct _ClipboardRequest ClipboardRequest;
|
||||
@@ -93,6 +100,8 @@ enum {
|
||||
BEGIN_USER_ACTION,
|
||||
END_USER_ACTION,
|
||||
PASTE_DONE,
|
||||
UNDO,
|
||||
REDO,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -108,6 +117,9 @@ enum {
|
||||
PROP_CURSOR_POSITION,
|
||||
PROP_COPY_TARGET_LIST,
|
||||
PROP_PASTE_TARGET_LIST,
|
||||
PROP_CAN_UNDO,
|
||||
PROP_CAN_REDO,
|
||||
PROP_ENABLE_UNDO,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -138,6 +150,8 @@ static void gtk_text_buffer_real_changed (GtkTextBuffer *buffe
|
||||
static void gtk_text_buffer_real_mark_set (GtkTextBuffer *buffer,
|
||||
const GtkTextIter *iter,
|
||||
GtkTextMark *mark);
|
||||
static void gtk_text_buffer_real_undo (GtkTextBuffer *buffer);
|
||||
static void gtk_text_buffer_real_redo (GtkTextBuffer *buffer);
|
||||
|
||||
static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
|
||||
static void free_log_attr_cache (GtkTextLogAttrCache *cache);
|
||||
@@ -154,6 +168,24 @@ static void gtk_text_buffer_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void gtk_text_buffer_history_change_state (gpointer funcs_data,
|
||||
gboolean is_modified,
|
||||
gboolean can_undo,
|
||||
gboolean can_redo);
|
||||
static void gtk_text_buffer_history_insert (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *text,
|
||||
guint len);
|
||||
static void gtk_text_buffer_history_delete (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *expected_text,
|
||||
guint len);
|
||||
static void gtk_text_buffer_history_select (gpointer funcs_data,
|
||||
int selection_insert,
|
||||
int selection_bound);
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
static GParamSpec *text_buffer_props[LAST_PROP];
|
||||
|
||||
@@ -185,6 +217,13 @@ GType gtk_text_buffer_content_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE (GtkTextBufferContent, gtk_text_buffer_content, GDK_TYPE_CONTENT_PROVIDER)
|
||||
|
||||
static GtkTextHistoryFuncs history_funcs = {
|
||||
gtk_text_buffer_history_change_state,
|
||||
gtk_text_buffer_history_insert,
|
||||
gtk_text_buffer_history_delete,
|
||||
gtk_text_buffer_history_select,
|
||||
};
|
||||
|
||||
static GdkContentFormats *
|
||||
gtk_text_buffer_content_ref_formats (GdkContentProvider *provider)
|
||||
{
|
||||
@@ -403,6 +442,8 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
|
||||
klass->remove_tag = gtk_text_buffer_real_remove_tag;
|
||||
klass->changed = gtk_text_buffer_real_changed;
|
||||
klass->mark_set = gtk_text_buffer_real_mark_set;
|
||||
klass->undo = gtk_text_buffer_real_undo;
|
||||
klass->redo = gtk_text_buffer_real_redo;
|
||||
|
||||
/* Construct */
|
||||
text_buffer_props[PROP_TAG_TABLE] =
|
||||
@@ -439,6 +480,45 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
|
||||
FALSE,
|
||||
GTK_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* GtkTextBuffer:can-undo:
|
||||
*
|
||||
* The :can-undo property denotes that the buffer can undo the last
|
||||
* applied action.
|
||||
*/
|
||||
text_buffer_props[PROP_CAN_UNDO] =
|
||||
g_param_spec_boolean ("can-undo",
|
||||
P_("Can Undo"),
|
||||
P_("If the buffer can have the last action undone"),
|
||||
FALSE,
|
||||
GTK_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* GtkTextBuffer:can-redo:
|
||||
*
|
||||
* The :can-redo property denotes that the buffer can reapply the
|
||||
* last undone action.
|
||||
*/
|
||||
text_buffer_props[PROP_CAN_REDO] =
|
||||
g_param_spec_boolean ("can-redo",
|
||||
P_("Can Redo"),
|
||||
P_("If the buffer can have the last undone action reapplied"),
|
||||
FALSE,
|
||||
GTK_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* GtkTextBuffer:enable-undo:
|
||||
*
|
||||
* The :enable-undo property denotes if support for undoing and redoing
|
||||
* changes to the buffer is allowed.
|
||||
*/
|
||||
text_buffer_props[PROP_ENABLE_UNDO] =
|
||||
g_param_spec_boolean ("enable-undo",
|
||||
"Enable Undo",
|
||||
"Enable support for undo and redo in the text view",
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkTextBuffer:cursor-position:
|
||||
*
|
||||
@@ -840,6 +920,34 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
|
||||
1,
|
||||
GDK_TYPE_CLIPBOARD);
|
||||
|
||||
/**
|
||||
* GtkTextBuffer::redo:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
*
|
||||
* The "redo" signal is emitted when a request has been made to redo the
|
||||
* previously undone operation.
|
||||
*/
|
||||
signals[REDO] =
|
||||
g_signal_new (I_("redo"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkTextBufferClass, redo),
|
||||
NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GtkTextBuffer::undo:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
*
|
||||
* The "undo" signal is emitted when a request has been made to undo the
|
||||
* previous operation or set of operations that have been grouped together.
|
||||
*/
|
||||
signals[UNDO] =
|
||||
g_signal_new (I_("undo"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkTextBufferClass, undo),
|
||||
NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
|
||||
gtk_text_buffer_register_serializers ();
|
||||
}
|
||||
|
||||
@@ -848,6 +956,9 @@ gtk_text_buffer_init (GtkTextBuffer *buffer)
|
||||
{
|
||||
buffer->priv = gtk_text_buffer_get_instance_private (buffer);
|
||||
buffer->priv->tag_table = NULL;
|
||||
buffer->priv->history = gtk_text_history_new (&history_funcs, buffer);
|
||||
|
||||
gtk_text_history_set_max_undo_levels (buffer->priv->history, DEFAULT_MAX_UNDO);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -891,6 +1002,10 @@ gtk_text_buffer_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ENABLE_UNDO:
|
||||
gtk_text_buffer_set_enable_undo (text_buffer, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_TAG_TABLE:
|
||||
set_table (text_buffer, g_value_get_object (value));
|
||||
break;
|
||||
@@ -919,6 +1034,10 @@ gtk_text_buffer_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ENABLE_UNDO:
|
||||
g_value_set_boolean (value, gtk_text_buffer_get_enable_undo (text_buffer));
|
||||
break;
|
||||
|
||||
case PROP_TAG_TABLE:
|
||||
g_value_set_object (value, get_table (text_buffer));
|
||||
break;
|
||||
@@ -946,6 +1065,14 @@ gtk_text_buffer_get_property (GObject *object,
|
||||
g_value_set_int (value, gtk_text_iter_get_offset (&iter));
|
||||
break;
|
||||
|
||||
case PROP_CAN_UNDO:
|
||||
g_value_set_boolean (value, gtk_text_buffer_get_can_undo (text_buffer));
|
||||
break;
|
||||
|
||||
case PROP_CAN_REDO:
|
||||
g_value_set_boolean (value, gtk_text_buffer_get_can_redo (text_buffer));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -981,6 +1108,8 @@ gtk_text_buffer_finalize (GObject *object)
|
||||
|
||||
remove_all_selection_clipboards (buffer);
|
||||
|
||||
g_clear_object (&buffer->priv->history);
|
||||
|
||||
if (priv->tag_table)
|
||||
{
|
||||
_gtk_text_tag_table_remove_buffer (priv->tag_table, buffer);
|
||||
@@ -1058,6 +1187,8 @@ gtk_text_buffer_set_text (GtkTextBuffer *buffer,
|
||||
if (len < 0)
|
||||
len = strlen (text);
|
||||
|
||||
gtk_text_history_begin_irreversible_action (buffer->priv->history);
|
||||
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
|
||||
gtk_text_buffer_delete (buffer, &start, &end);
|
||||
@@ -1067,6 +1198,8 @@ gtk_text_buffer_set_text (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
|
||||
gtk_text_buffer_insert (buffer, &start, text, len);
|
||||
}
|
||||
|
||||
gtk_text_history_end_irreversible_action (buffer->priv->history);
|
||||
}
|
||||
|
||||
|
||||
@@ -1084,6 +1217,11 @@ gtk_text_buffer_real_insert_text (GtkTextBuffer *buffer,
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
gtk_text_history_text_inserted (buffer->priv->history,
|
||||
gtk_text_iter_get_offset (iter),
|
||||
text,
|
||||
len);
|
||||
|
||||
_gtk_text_btree_insert (iter, text, len);
|
||||
|
||||
g_signal_emit (buffer, signals[CHANGED], 0);
|
||||
@@ -1798,6 +1936,28 @@ gtk_text_buffer_real_delete_range (GtkTextBuffer *buffer,
|
||||
g_return_if_fail (start != NULL);
|
||||
g_return_if_fail (end != NULL);
|
||||
|
||||
if (gtk_text_history_get_enabled (buffer->priv->history))
|
||||
{
|
||||
GtkTextIter sel_begin, sel_end;
|
||||
gchar *text;
|
||||
|
||||
if (gtk_text_buffer_get_selection_bounds (buffer, &sel_begin, &sel_end))
|
||||
gtk_text_history_selection_changed (buffer->priv->history,
|
||||
gtk_text_iter_get_offset (&sel_begin),
|
||||
gtk_text_iter_get_offset (&sel_end));
|
||||
else
|
||||
gtk_text_history_selection_changed (buffer->priv->history,
|
||||
gtk_text_iter_get_offset (&sel_begin),
|
||||
-1);
|
||||
|
||||
text = gtk_text_iter_get_slice (start, end);
|
||||
gtk_text_history_text_deleted (buffer->priv->history,
|
||||
gtk_text_iter_get_offset (start),
|
||||
gtk_text_iter_get_offset (end),
|
||||
text, -1);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
_gtk_text_btree_delete (start, end);
|
||||
|
||||
/* may have deleted the selection... */
|
||||
@@ -3274,17 +3434,14 @@ void
|
||||
gtk_text_buffer_set_modified (GtkTextBuffer *buffer,
|
||||
gboolean setting)
|
||||
{
|
||||
gboolean fixed_setting;
|
||||
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
|
||||
fixed_setting = setting != FALSE;
|
||||
setting = !!setting;
|
||||
|
||||
if (buffer->priv->modified == fixed_setting)
|
||||
return;
|
||||
else
|
||||
if (buffer->priv->modified != setting)
|
||||
{
|
||||
buffer->priv->modified = fixed_setting;
|
||||
buffer->priv->modified = setting;
|
||||
gtk_text_history_modified_changed (buffer->priv->history, setting);
|
||||
g_signal_emit (buffer, signals[MODIFIED_CHANGED], 0);
|
||||
}
|
||||
}
|
||||
@@ -4723,3 +4880,258 @@ gtk_text_buffer_insert_markup (GtkTextBuffer *buffer,
|
||||
pango_attr_list_unref (attributes);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_buffer_real_undo (GtkTextBuffer *buffer)
|
||||
{
|
||||
if (gtk_text_history_get_can_undo (buffer->priv->history))
|
||||
gtk_text_history_undo (buffer->priv->history);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_buffer_real_redo (GtkTextBuffer *buffer)
|
||||
{
|
||||
if (gtk_text_history_get_can_redo (buffer->priv->history))
|
||||
gtk_text_history_redo (buffer->priv->history);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_text_buffer_get_can_undo (GtkTextBuffer *buffer)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
|
||||
|
||||
return gtk_text_history_get_can_undo (buffer->priv->history);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_text_buffer_get_can_redo (GtkTextBuffer *buffer)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
|
||||
|
||||
return gtk_text_history_get_can_redo (buffer->priv->history);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_buffer_history_change_state (gpointer funcs_data,
|
||||
gboolean is_modified,
|
||||
gboolean can_undo,
|
||||
gboolean can_redo)
|
||||
{
|
||||
GtkTextBuffer *buffer = funcs_data;
|
||||
|
||||
if (buffer->priv->can_undo != can_undo)
|
||||
{
|
||||
buffer->priv->can_undo = can_undo;
|
||||
g_object_notify_by_pspec (G_OBJECT (buffer), text_buffer_props[PROP_CAN_UNDO]);
|
||||
}
|
||||
|
||||
if (buffer->priv->can_redo != can_redo)
|
||||
{
|
||||
buffer->priv->can_redo = can_redo;
|
||||
g_object_notify_by_pspec (G_OBJECT (buffer), text_buffer_props[PROP_CAN_REDO]);
|
||||
}
|
||||
|
||||
if (buffer->priv->modified != is_modified)
|
||||
gtk_text_buffer_set_modified (buffer, is_modified);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_buffer_history_insert (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *text,
|
||||
guint len)
|
||||
{
|
||||
GtkTextBuffer *buffer = funcs_data;
|
||||
GtkTextIter iter;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, begin);
|
||||
gtk_text_buffer_insert (buffer, &iter, text, len);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_buffer_history_delete (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *expected_text,
|
||||
guint len)
|
||||
{
|
||||
GtkTextBuffer *buffer = funcs_data;
|
||||
GtkTextIter iter;
|
||||
GtkTextIter end_iter;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, begin);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
|
||||
gtk_text_buffer_delete (buffer, &iter, &end_iter);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_buffer_history_select (gpointer funcs_data,
|
||||
int selection_insert,
|
||||
int selection_bound)
|
||||
{
|
||||
GtkTextBuffer *buffer = funcs_data;
|
||||
GtkTextIter insert;
|
||||
GtkTextIter bound;
|
||||
|
||||
if (selection_insert == -1 || selection_bound == -1)
|
||||
return;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &insert, selection_insert);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &bound, selection_bound);
|
||||
gtk_text_buffer_select_range (buffer, &insert, &bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_undo:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
*
|
||||
* Undoes the last undoable action on the buffer, if there is one.
|
||||
*/
|
||||
void
|
||||
gtk_text_buffer_undo (GtkTextBuffer *buffer)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
|
||||
if (gtk_text_buffer_get_can_undo (buffer))
|
||||
g_signal_emit (buffer, signals[UNDO], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_redo:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
*
|
||||
* Redoes the next redoable action on the buffer, if there is one.
|
||||
*/
|
||||
void
|
||||
gtk_text_buffer_redo (GtkTextBuffer *buffer)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
|
||||
if (gtk_text_buffer_get_can_redo (buffer))
|
||||
g_signal_emit (buffer, signals[REDO], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_get_enable_undo:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
*
|
||||
* Gets whether the buffer is saving modifications to the buffer to allow for
|
||||
* undo and redo actions.
|
||||
*
|
||||
* See gtk_text_buffer_begin_irreversible_action() and
|
||||
* gtk_text_buffer_end_irreversible_action() to create changes to the buffer
|
||||
* that cannot be undone.
|
||||
*/
|
||||
gboolean
|
||||
gtk_text_buffer_get_enable_undo (GtkTextBuffer *buffer)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
|
||||
|
||||
return gtk_text_history_get_enabled (buffer->priv->history);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_set_enable_undo:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
*
|
||||
* Sets whether or not to enable undoable actions in the text buffer. If
|
||||
* enabled, the user will be able to undo the last number of actions up to
|
||||
* gtk_text_buffer_get_max_undo_levels().
|
||||
*
|
||||
* See gtk_text_buffer_begin_irreversible_action() and
|
||||
* gtk_text_buffer_end_irreversible_action() to create changes to the buffer
|
||||
* that cannot be undone.
|
||||
*/
|
||||
void
|
||||
gtk_text_buffer_set_enable_undo (GtkTextBuffer *buffer,
|
||||
gboolean enabled)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
|
||||
if (enabled != gtk_text_history_get_enabled (buffer->priv->history))
|
||||
{
|
||||
gtk_text_history_set_enabled (buffer->priv->history, enabled);
|
||||
g_object_notify_by_pspec (G_OBJECT (buffer),
|
||||
text_buffer_props[PROP_ENABLE_UNDO]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_begin_irreversible_action:
|
||||
* @self: a #Gtktextbuffer
|
||||
*
|
||||
* Denotes the beginning of an action that may not be undone. This will cause
|
||||
* any previous operations in the undo/redo queue to be cleared.
|
||||
*
|
||||
* This should be paired with a call to
|
||||
* gtk_text_buffer_end_irreversible_action() after the irreversible action
|
||||
* has completed.
|
||||
*
|
||||
* You may nest calls to gtk_text_buffer_begin_irreversible_action() and
|
||||
* gtk_text_buffer_end_irreversible_action() pairs.
|
||||
*/
|
||||
void
|
||||
gtk_text_buffer_begin_irreversible_action (GtkTextBuffer *buffer)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
|
||||
gtk_text_history_begin_irreversible_action (buffer->priv->history);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_end_irreversible_action:
|
||||
* @self: a #Gtktextbuffer
|
||||
*
|
||||
* Denotes the end of an action that may not be undone. This will cause
|
||||
* any previous operations in the undo/redo queue to be cleared.
|
||||
*
|
||||
* This should be called after completing modifications to the text buffer
|
||||
* after gtk_text_buffer_begin_irreversible_action() was called.
|
||||
*
|
||||
* You may nest calls to gtk_text_buffer_begin_irreversible_action() and
|
||||
* gtk_text_buffer_end_irreversible_action() pairs.
|
||||
*/
|
||||
void
|
||||
gtk_text_buffer_end_irreversible_action (GtkTextBuffer *buffer)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
|
||||
gtk_text_history_end_irreversible_action (buffer->priv->history);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_get_max_undo_levels:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
*
|
||||
* Gets the maximum number of undo levels to perform. If 0, unlimited undo
|
||||
* actions may be performed. Note that this may have a memory usage impact
|
||||
* as it requires storing an additional copy of the inserted or removed text
|
||||
* within the text buffer.
|
||||
*/
|
||||
guint
|
||||
gtk_text_buffer_get_max_undo_levels (GtkTextBuffer *buffer)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), 0);
|
||||
|
||||
return gtk_text_history_get_max_undo_levels (buffer->priv->history);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_set_max_undo_levels:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @max_undo_levels: the maximum number of undo actions to perform
|
||||
*
|
||||
* Sets the maximum number of undo levels to perform. If 0, unlimited undo
|
||||
* actions may be performed. Note that this may have a memory usage impact
|
||||
* as it requires storing an additional copy of the inserted or removed text
|
||||
* within the text buffer.
|
||||
*/
|
||||
void
|
||||
gtk_text_buffer_set_max_undo_levels (GtkTextBuffer *buffer,
|
||||
guint max_undo_levels)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
|
||||
gtk_text_history_set_max_undo_levels (buffer->priv->history, max_undo_levels);
|
||||
}
|
||||
|
||||
+26
-3
@@ -146,6 +146,8 @@ struct _GtkTextBufferClass
|
||||
|
||||
void (* paste_done) (GtkTextBuffer *buffer,
|
||||
GdkClipboard *clipboard);
|
||||
void (* undo) (GtkTextBuffer *buffer);
|
||||
void (* redo) (GtkTextBuffer *buffer);
|
||||
|
||||
/*< private >*/
|
||||
|
||||
@@ -451,11 +453,32 @@ gboolean gtk_text_buffer_delete_selection (GtkTextBuffer *buffer,
|
||||
gboolean interactive,
|
||||
gboolean default_editable);
|
||||
|
||||
/* Called to specify atomic user actions, used to implement undo */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_begin_user_action (GtkTextBuffer *buffer);
|
||||
gboolean gtk_text_buffer_get_can_undo (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_end_user_action (GtkTextBuffer *buffer);
|
||||
gboolean gtk_text_buffer_get_can_redo (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_text_buffer_get_enable_undo (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_set_enable_undo (GtkTextBuffer *buffer,
|
||||
gboolean enable_undo);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gtk_text_buffer_get_max_undo_levels (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_set_max_undo_levels (GtkTextBuffer *buffer,
|
||||
guint max_undo_levels);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_undo (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_redo (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_begin_irreversible_action (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_end_irreversible_action (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_begin_user_action (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_end_user_action (GtkTextBuffer *buffer);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
/* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_TEXT_HISTORY_PRIVATE_H__
|
||||
#define __GTK_TEXT_HISTORY_PRIVATE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_TEXT_HISTORY (gtk_text_history_get_type())
|
||||
|
||||
typedef struct _GtkTextHistoryFuncs GtkTextHistoryFuncs;
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkTextHistory, gtk_text_history, GTK, TEXT_HISTORY, GObject)
|
||||
|
||||
struct _GtkTextHistoryFuncs
|
||||
{
|
||||
void (*change_state) (gpointer funcs_data,
|
||||
gboolean is_modified,
|
||||
gboolean can_undo,
|
||||
gboolean can_redo);
|
||||
void (*insert) (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *text,
|
||||
guint len);
|
||||
void (*delete) (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *expected_text,
|
||||
guint len);
|
||||
void (*select) (gpointer funcs_data,
|
||||
int selection_insert,
|
||||
int selection_bound);
|
||||
};
|
||||
|
||||
GtkTextHistory *gtk_text_history_new (const GtkTextHistoryFuncs *funcs,
|
||||
gpointer funcs_data);
|
||||
void gtk_text_history_begin_user_action (GtkTextHistory *self);
|
||||
void gtk_text_history_end_user_action (GtkTextHistory *self);
|
||||
void gtk_text_history_begin_irreversible_action (GtkTextHistory *self);
|
||||
void gtk_text_history_end_irreversible_action (GtkTextHistory *self);
|
||||
gboolean gtk_text_history_get_can_undo (GtkTextHistory *self);
|
||||
gboolean gtk_text_history_get_can_redo (GtkTextHistory *self);
|
||||
void gtk_text_history_undo (GtkTextHistory *self);
|
||||
void gtk_text_history_redo (GtkTextHistory *self);
|
||||
guint gtk_text_history_get_max_undo_levels (GtkTextHistory *self);
|
||||
void gtk_text_history_set_max_undo_levels (GtkTextHistory *self,
|
||||
guint max_undo_levels);
|
||||
void gtk_text_history_modified_changed (GtkTextHistory *self,
|
||||
gboolean modified);
|
||||
void gtk_text_history_selection_changed (GtkTextHistory *self,
|
||||
int selection_insert,
|
||||
int selection_bound);
|
||||
void gtk_text_history_text_inserted (GtkTextHistory *self,
|
||||
guint position,
|
||||
const char *text,
|
||||
int len);
|
||||
void gtk_text_history_text_deleted (GtkTextHistory *self,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *text,
|
||||
int len);
|
||||
gboolean gtk_text_history_get_enabled (GtkTextHistory *self);
|
||||
void gtk_text_history_set_enabled (GtkTextHistory *self,
|
||||
gboolean enabled);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TEXT_HISTORY_PRIVATE_H__ */
|
||||
@@ -85,6 +85,8 @@ struct _GtkTextClass
|
||||
void (* paste_clipboard) (GtkText *self);
|
||||
void (* toggle_overwrite) (GtkText *self);
|
||||
void (* insert_emoji) (GtkText *self);
|
||||
void (* undo) (GtkText *self);
|
||||
void (* redo) (GtkText *self);
|
||||
};
|
||||
|
||||
char * gtk_text_get_display_text (GtkText *entry,
|
||||
|
||||
@@ -619,6 +619,13 @@ static void gtk_text_view_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
static void gtk_text_view_real_undo (GtkWidget *widget,
|
||||
const gchar *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_real_redo (GtkWidget *widget,
|
||||
const gchar *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
|
||||
/* FIXME probably need the focus methods. */
|
||||
|
||||
@@ -1358,6 +1365,9 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "text.undo", NULL, gtk_text_view_real_undo);
|
||||
gtk_widget_class_install_action (widget_class, "text.redo", NULL, gtk_text_view_real_redo);
|
||||
|
||||
/*
|
||||
* Key bindings
|
||||
*/
|
||||
@@ -1550,6 +1560,14 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Insert, GDK_SHIFT_MASK,
|
||||
"paste-clipboard", 0);
|
||||
|
||||
/* Undo/Redo */
|
||||
gtk_binding_entry_add_action (binding_set, GDK_KEY_z, GDK_CONTROL_MASK,
|
||||
"text.undo", NULL);
|
||||
gtk_binding_entry_add_action (binding_set, GDK_KEY_y, GDK_CONTROL_MASK,
|
||||
"text.redo", NULL);
|
||||
gtk_binding_entry_add_action (binding_set, GDK_KEY_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
|
||||
"text.redo", NULL);
|
||||
|
||||
/* Overwrite */
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Insert, 0,
|
||||
"toggle-overwrite", 0);
|
||||
@@ -9835,3 +9853,25 @@ gtk_text_view_get_extra_menu (GtkTextView *text_view)
|
||||
|
||||
return priv->extra_menu;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_real_undo (GtkWidget *widget,
|
||||
const gchar *action_name,
|
||||
GVariant *parameters)
|
||||
{
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
|
||||
|
||||
if (gtk_text_view_get_editable (text_view))
|
||||
gtk_text_buffer_undo (text_view->priv->buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_real_redo (GtkWidget *widget,
|
||||
const gchar *action_name,
|
||||
GVariant *parameters)
|
||||
{
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
|
||||
|
||||
if (gtk_text_view_get_editable (text_view))
|
||||
gtk_text_buffer_redo (text_view->priv->buffer);
|
||||
}
|
||||
|
||||
@@ -696,6 +696,7 @@ void
|
||||
gtk_inspector_object_tree_activate_object (GtkInspectorObjectTree *wt,
|
||||
GObject *object)
|
||||
{
|
||||
gtk_inspector_object_tree_select_object (wt, object);
|
||||
g_signal_emit (wt, signals[OBJECT_ACTIVATED], 0, object);
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ gtk_private_sources = files([
|
||||
'gtkstylecascade.c',
|
||||
'gtkstyleproperty.c',
|
||||
'gtktextbtree.c',
|
||||
'gtktexthistory.c',
|
||||
'gtktextviewchild.c',
|
||||
'gtktrashmonitor.c',
|
||||
'gtktreedatalist.c',
|
||||
@@ -1103,6 +1104,8 @@ if build_gir
|
||||
gtk_introspection_sources = [
|
||||
gtk_public_headers,
|
||||
gtk_public_sources,
|
||||
gtk_css_public_headers,
|
||||
gtk_css_public_sources,
|
||||
gtk_deprecated_headers,
|
||||
gtk_deprecated_sources,
|
||||
a11y_headers,
|
||||
|
||||
@@ -1473,7 +1473,6 @@ headerbar {
|
||||
border-style: solid;
|
||||
border-color: $alt_borders_color;
|
||||
border-radius: 0;
|
||||
border-spacing: 6px;
|
||||
|
||||
@include headerbar_fill(darken($bg_color, 10%));
|
||||
|
||||
@@ -1691,6 +1690,8 @@ headerbar {
|
||||
}
|
||||
|
||||
headerbar {
|
||||
border-spacing: 6px;
|
||||
|
||||
// add vertical margins to common widget on the headerbar to avoid them spanning the whole height
|
||||
entry,
|
||||
spinbutton,
|
||||
@@ -2855,20 +2856,42 @@ radio {
|
||||
border: 1px solid;
|
||||
-gtk-icon-source: none;
|
||||
|
||||
@include button(normal-alt, $edge: $shadow_color);
|
||||
&:hover { @include button(hover-alt, $c:$checkradio_bg_color, $tc:$checkradio_fg_color, $edge: $shadow_color); }
|
||||
&:hover:not(:checked) { @include button(hover-alt, $edge: $shadow_color); }
|
||||
&:active { @include button(active, $c:$checkradio_bg_color, $tc:$checkradio_fg_color); }
|
||||
&:checked { @include button(normal-alt, $c:$checkradio_bg_color, $tc:$checkradio_fg_color, $edge: $shadow_color); }
|
||||
&:disabled { @include button(insensitive); }
|
||||
&:backdrop {
|
||||
@include button(backdrop);
|
||||
& {
|
||||
// for unchecked
|
||||
$_c: if($variant=='light', white, $bg_color);
|
||||
|
||||
transition: $backdrop_transition;
|
||||
|
||||
&:disabled { @include button(backdrop-insensitive); }
|
||||
@each $state, $t in ("", "normal"),
|
||||
(":hover", "hover"),
|
||||
(":active", "active"),
|
||||
(":disabled", "insensitive"),
|
||||
(":backdrop", "backdrop"),
|
||||
(":backdrop:disabled", 'backdrop-insensitive') {
|
||||
&#{$state} {
|
||||
@include check($t, $_c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& {
|
||||
// for checked
|
||||
@each $t in (':checked'), (':indeterminate') {
|
||||
&#{$t} {
|
||||
@each $state, $t in ("", "normal"),
|
||||
(":hover", "hover"),
|
||||
(":active", "active"),
|
||||
(":disabled", "insensitive"),
|
||||
(":backdrop", "backdrop"),
|
||||
(":backdrop:disabled", 'backdrop-insensitive') {
|
||||
&#{$state} {
|
||||
@include check($t, $checkradio_bg_color, $checkradio_fg_color, $checked: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:backdrop { transition: $backdrop_transition; }
|
||||
|
||||
@if $variant == 'light' {
|
||||
// the borders of the light variant versions of checks and radios are too similar in luminosity to the selected background
|
||||
// color, hence we need special casing.
|
||||
@@ -2897,6 +2920,12 @@ radio {
|
||||
color: inherit;
|
||||
border-color: currentColor;
|
||||
}
|
||||
&:indeterminate, &:checked {
|
||||
&:hover {
|
||||
color: $checkradio_fg_color;
|
||||
border-color: darken($checkradio_bg_color, if($variant=='light', 15%, 30%));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2956,15 +2985,7 @@ treeview.view radio {
|
||||
|
||||
@if $variant == 'light' { border-color: $selected_borders_color; }
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: $insensitive_fg_color;
|
||||
|
||||
&:backdrop { color: $backdrop_insensitive_color; }
|
||||
}
|
||||
}
|
||||
|
||||
&:backdrop { &:selected, & { color: $backdrop_fg_color; }}
|
||||
}
|
||||
|
||||
treeview.view radio:selected { &:focus, & { @extend %radio; }} // This is a workaround
|
||||
@@ -4710,7 +4731,11 @@ stackswitcher.circular {
|
||||
* Emoji *
|
||||
********/
|
||||
|
||||
popover.emoji-picker { padding-left: 0; padding-right: 0; }
|
||||
popover.emoji-picker > contents {
|
||||
padding: 0;
|
||||
|
||||
entry.search { margin: 5px; }
|
||||
}
|
||||
|
||||
button.emoji-section {
|
||||
border-color: transparent;
|
||||
@@ -4718,7 +4743,7 @@ button.emoji-section {
|
||||
border-style: none none solid;
|
||||
border-radius: 0;
|
||||
|
||||
margin: 2px 4px 2px 4px;
|
||||
margin: 2px 8px 4px;
|
||||
padding: 3px 0 0;
|
||||
min-width: 32px;
|
||||
min-height: 28px;
|
||||
@@ -4730,8 +4755,11 @@ button.emoji-section {
|
||||
|
||||
outline-offset: -5px;
|
||||
|
||||
&:dir(ltr):not(:last-child) { margin-right: 0; }
|
||||
&:dir(rtl):not(:last-child) { margin-left: 0; }
|
||||
|
||||
&:backdrop:not(:checked) { border-color: transparent; }
|
||||
&:hover { border-color: $borders_color; }
|
||||
&:hover { border-color: if($variant == 'light', $borders_color, transparentize($fg_color, .9)); }
|
||||
&:checked { border-color: $selected_bg_color; }
|
||||
|
||||
label {
|
||||
@@ -4749,7 +4777,7 @@ popover.emoji-picker .emoji {
|
||||
padding: 6px;
|
||||
border-radius: 6px;
|
||||
|
||||
:hover {
|
||||
&:hover {
|
||||
background: $selected_bg_color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,3 +568,54 @@
|
||||
border: none; //
|
||||
box-shadow: none; //
|
||||
}
|
||||
|
||||
/***************************
|
||||
* Check and Radio buttons *
|
||||
***************************/
|
||||
|
||||
@mixin check($t, $c:$bg_color, $tc:$fg_color, $checked: false) {
|
||||
// Check/Radio drawing function
|
||||
//
|
||||
// $t: check/radio type,
|
||||
// $c: base button color for colored* types
|
||||
// $tc: optional text color for colored* types
|
||||
// $checked: bool to chose between checked/unchecked
|
||||
//
|
||||
// possible $t values:
|
||||
// normal, hover, active, insensitive, backdrop, backdrop-insensitive
|
||||
|
||||
$_border_color: if($c==$checkradio_bg_color, $c, $alt_borders_color);
|
||||
$_dim_border_color: transparentize($_border_color, if($variant == 'light', 0.3, 0.7));
|
||||
|
||||
@if $t==normal {
|
||||
background-clip: if($checked, border-box, padding-box);
|
||||
background-image: linear-gradient(to bottom, lighten($c, 5%) 20%, $c 90%);
|
||||
border-color: $_border_color;
|
||||
box-shadow: 0 1px transparentize(black, 0.95);
|
||||
color: $tc;
|
||||
}
|
||||
|
||||
@if $t==hover {
|
||||
background-image: if($c == white, image(darken($c, 5%)), linear-gradient(to bottom, lighten($c, 9%) 10%, lighten($c, 4%) 90%));
|
||||
}
|
||||
|
||||
@if $t==active {
|
||||
box-shadow: inset 0 1px 1px 0px if($variant == 'light', rgba(0, 0, 0, 0.2), black);
|
||||
}
|
||||
|
||||
@if $t==insensitive {
|
||||
box-shadow: none;
|
||||
color: transparentize($tc, 0.3);
|
||||
}
|
||||
|
||||
@if $t==backdrop {
|
||||
background-image: image($c);
|
||||
box-shadow: none;
|
||||
color: $tc;
|
||||
}
|
||||
|
||||
@if $t==backdrop-insensitive {
|
||||
box-shadow: none;
|
||||
color: transparentize($tc, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*************************** Check and Radio buttons * */
|
||||
* { padding: 0; -gtk-secondary-caret-color: #15539e; }
|
||||
|
||||
button:focus(visible), checkbutton:focus(visible), radiobutton:focus(visible), switch:focus(visible), scale:focus(visible), label:focus(visible), row:focus(visible), flowboxchild:focus(visible) { outline-color: alpha(currentColor,0.3); outline-style: dashed; outline-offset: -3px; outline-width: 1px; -gtk-outline-radius: 3px; }
|
||||
@@ -82,7 +83,7 @@ assistant .sidebar label { padding: 6px 12px; }
|
||||
|
||||
assistant .sidebar label.highlight { background-color: #5a5a59; }
|
||||
|
||||
.osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents, .app-notification, .app-notification.frame, .osd .scale-popup, .osd { color: #eeeeec; border: none; background-color: rgba(37, 37, 38, 0.7); background-clip: padding-box; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
.osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents, .app-notification, .app-notification.frame, .osd .scale-popup, .osd { color: #eeeeec; border: none; background-color: rgba(38, 38, 38, 0.7); background-clip: padding-box; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
|
||||
.osd popover.background > arrow:backdrop, .osd popover.background > contents:backdrop, popover.background.touch-selection > arrow:backdrop, popover.background.touch-selection > contents:backdrop, popover.background.magnifier > arrow:backdrop, popover.background.magnifier > contents:backdrop, .app-notification:backdrop, .osd .scale-popup:backdrop, .osd:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -267,7 +268,7 @@ row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(di
|
||||
|
||||
row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled):backdrop, row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled):backdrop { color: #919190; }
|
||||
|
||||
button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
|
||||
button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
|
||||
|
||||
button.osd.image-button { min-width: 30px; }
|
||||
|
||||
@@ -279,9 +280,9 @@ button.osd:active, button.osd:checked { color: white; border-color: rgba(0, 0, 0
|
||||
|
||||
button.osd:disabled:backdrop, button.osd:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
|
||||
button.osd:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
button.osd:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
|
||||
popover.background.touch-selection button, popover.background.magnifier button, .app-notification button, .app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
popover.background.touch-selection button, popover.background.magnifier button, .app-notification button, .app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
popover.background.touch-selection button:hover, popover.background.magnifier button:hover, .app-notification button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
@@ -289,7 +290,7 @@ popover.background.touch-selection button:active:backdrop, popover.background.ma
|
||||
|
||||
popover.background.touch-selection button:disabled:backdrop, popover.background.magnifier button:disabled:backdrop, .app-notification button:disabled:backdrop, popover.background.touch-selection button:disabled, popover.background.magnifier button:disabled, .app-notification button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
popover.background.touch-selection button:backdrop, popover.background.magnifier button:backdrop, .app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
popover.background.touch-selection button:backdrop, popover.background.magnifier button:backdrop, .app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
popover.background.touch-selection button.flat, popover.background.magnifier button.flat, .app-notification button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; box-shadow: none; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
|
||||
@@ -499,7 +500,7 @@ button:link > label:active, button:visited > label:active, *:link:active, button
|
||||
|
||||
*:selected button:link > label:active, *:selected button:visited > label:active, *:selected *:link:active, *:selected button:active:link, *:selected button:active:visited { color: #d0ddec; }
|
||||
|
||||
button:link > label:disabled, button:visited > label:disabled, button:link > label:disabled:backdrop, button:visited > label:disabled:backdrop, *:link:disabled, button:disabled:link, button:disabled:visited, *:link:disabled:backdrop, button:disabled:backdrop:link, button:disabled:backdrop:visited { color: rgba(140, 140, 141, 0.8); }
|
||||
button:link > label:disabled, button:visited > label:disabled, button:link > label:disabled:backdrop, button:visited > label:disabled:backdrop, *:link:disabled, button:disabled:link, button:disabled:visited, *:link:disabled:backdrop, button:disabled:backdrop:link, button:disabled:backdrop:visited { color: rgba(141, 141, 141, 0.8); }
|
||||
|
||||
button:link > label:backdrop:backdrop:hover, button:visited > label:backdrop:backdrop:hover, button:link > label:backdrop:backdrop:hover:selected, button:visited > label:backdrop:backdrop:hover:selected, button:link > label:backdrop, button:visited > label:backdrop, *:link:backdrop:backdrop:hover, button:backdrop:backdrop:hover:link, button:backdrop:backdrop:hover:visited, *:link:backdrop:backdrop:hover:selected, button:backdrop:backdrop:hover:selected:link, button:backdrop:backdrop:hover:selected:visited, .selection-mode .titlebar:not(headerbar) .subtitle:backdrop:backdrop:hover:link, .selection-mode.titlebar:not(headerbar) .subtitle:backdrop:backdrop:hover:link, .selection-mode headerbar .subtitle:backdrop:backdrop:hover:link, headerbar.selection-mode .subtitle:backdrop:backdrop:hover:link, *:link:backdrop, button:backdrop:link, button:backdrop:visited { color: #15539e; }
|
||||
|
||||
@@ -566,7 +567,7 @@ spinbutton.vertical button.up { border-bottom-style: none; border-bottom-left-ra
|
||||
|
||||
spinbutton.vertical button.down { border-top-style: none; border-top-left-radius: 0; border-top-right-radius: 0; }
|
||||
|
||||
.osd spinbutton.vertical button:first-child { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.osd spinbutton.vertical button:first-child { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd spinbutton.vertical button:first-child:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
@@ -574,7 +575,7 @@ spinbutton.vertical button.down { border-top-style: none; border-top-left-radius
|
||||
|
||||
.osd spinbutton.vertical button:first-child:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.osd spinbutton.vertical button:first-child:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd spinbutton.vertical button:first-child:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
treeview spinbutton:not(.vertical) { min-height: 0; border-style: none; border-radius: 0; }
|
||||
|
||||
@@ -592,7 +593,7 @@ toolbar { padding: 4px 3px 3px 4px; }
|
||||
|
||||
.osd toolbar { background-color: transparent; }
|
||||
|
||||
toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(37, 37, 38, 0.7); }
|
||||
toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(38, 38, 38, 0.7); }
|
||||
|
||||
toolbar.osd.left, toolbar.osd.right, toolbar.osd.top, toolbar.osd.bottom { border-radius: 0; }
|
||||
|
||||
@@ -615,7 +616,7 @@ searchbar > revealer > box { padding: 6px; border-width: 0 0 1px; }
|
||||
.inline-toolbar:backdrop, .location-bar:backdrop, searchbar > revealer > box:backdrop { border-color: #202020; background-color: #2e2e2e; box-shadow: none; transition: 200ms ease-out; }
|
||||
|
||||
/*************** Header bars * */
|
||||
.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #070707; border-radius: 0; border-spacing: 6px; background: #1b1b1b linear-gradient(to top, #252526, #2b2b2b); box-shadow: inset 0 1px rgba(238, 238, 236, 0.07); /* Darken switchbuttons for headerbars. issue #1588 */ /* hide the close button separator */ }
|
||||
.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #070707; border-radius: 0; background: #1b1b1b linear-gradient(to top, #262626, #2b2b2b); box-shadow: inset 0 1px rgba(238, 238, 236, 0.07); /* Darken switchbuttons for headerbars. issue #1588 */ /* hide the close button separator */ }
|
||||
|
||||
.titlebar:backdrop:not(headerbar), headerbar:backdrop { border-color: #202020; background-color: #353535; background-image: none; box-shadow: inset 0 1px rgba(238, 238, 236, 0.07); transition: 200ms ease-out; }
|
||||
|
||||
@@ -705,6 +706,8 @@ searchbar > revealer > box { padding: 6px; border-width: 0 0 1px; }
|
||||
|
||||
.solid-csd .titlebar:backdrop:dir(rtl):not(headerbar), .solid-csd .titlebar:backdrop:dir(ltr):not(headerbar), .solid-csd .titlebar:dir(rtl):not(headerbar), .solid-csd .titlebar:dir(ltr):not(headerbar), .solid-csd headerbar:backdrop:dir(rtl), .solid-csd headerbar:backdrop:dir(ltr), .solid-csd headerbar:dir(rtl), .solid-csd headerbar:dir(ltr) { margin-left: -1px; margin-right: -1px; margin-top: -1px; border-radius: 0; box-shadow: none; }
|
||||
|
||||
headerbar { border-spacing: 6px; }
|
||||
|
||||
headerbar entry, headerbar spinbutton, headerbar separator:not(.sidebar), headerbar button, headerbar menubutton { margin-top: 6px; margin-bottom: 6px; }
|
||||
|
||||
headerbar menubutton > button { margin-top: 0px; margin-bottom: 0px; }
|
||||
@@ -1149,7 +1152,7 @@ switch:backdrop:disabled slider label, switch:backdrop:disabled slider { color:
|
||||
|
||||
.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(21, 83, 158, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(89, 89, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(90, 90, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view .tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: rgba(21, 83, 158, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -1157,11 +1160,11 @@ switch:backdrop:disabled slider label, switch:backdrop:disabled slider { color:
|
||||
|
||||
.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list), .content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: rgba(21, 83, 158, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: rgba(89, 89, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: rgba(90, 90, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
checkbutton.text-button, radiobutton.text-button { padding: 2px 0; outline-offset: 0; border-spacing: 4px; }
|
||||
|
||||
check, radio { margin: 0 4px; min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to bottom, #2d2d2d 20%, #252526 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
check, radio { margin: 0 4px; min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; }
|
||||
|
||||
check:only-child, radio:only-child { margin: 0; }
|
||||
|
||||
@@ -1169,33 +1172,51 @@ popover check.left:dir(rtl), popover radio.left:dir(rtl) { margin-left: 0; margi
|
||||
|
||||
popover check.right:dir(ltr), popover radio.right:dir(ltr) { margin-left: 12px; margin-right: 0; }
|
||||
|
||||
check:hover, radio:hover { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #092444; box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to bottom, #15539e 20%, #13498c 90%); }
|
||||
check, radio { background-clip: padding-box; background-image: linear-gradient(to bottom, #424242 20%, #353535 90%); border-color: #070707; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #eeeeec; }
|
||||
|
||||
check:hover:not(:checked), radio:hover:not(:checked) { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to bottom, #353535 20%, #2b2b2b 90%); }
|
||||
check:hover, radio:hover { background-image: linear-gradient(to bottom, #4c4c4c 10%, #3f3f3f 90%); }
|
||||
|
||||
check:active, radio:active { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #0f3b71; background-image: image(#103e75); box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
check:active, radio:active { box-shadow: inset 0 1px 1px 0px black; }
|
||||
|
||||
check:checked, radio:checked { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #092444; text-shadow: 0 -1px rgba(0, 0, 0, 0.719216); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.719216); background-image: linear-gradient(to bottom, #134c90 20%, #114583 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
check:disabled, radio:disabled { box-shadow: none; color: rgba(238, 238, 236, 0.7); }
|
||||
|
||||
check:disabled, radio:disabled { border-color: #1b1b1b; background-image: image(#323232); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); }
|
||||
check:backdrop, radio:backdrop { background-image: image(#353535); box-shadow: none; color: #eeeeec; }
|
||||
|
||||
check:disabled label, check:disabled, radio:disabled label, radio:disabled { color: #919190; }
|
||||
check:backdrop:disabled, radio:backdrop:disabled { box-shadow: none; color: rgba(238, 238, 236, 0.7); }
|
||||
|
||||
check:backdrop, radio:backdrop { border-color: #202020; background-image: image(#353535); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); transition: 200ms ease-out; }
|
||||
check:checked, radio:checked { background-clip: border-box; background-image: linear-gradient(to bottom, #185fb4 20%, #15539e 90%); border-color: #15539e; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
|
||||
|
||||
check:backdrop label, check:backdrop, radio:backdrop label, radio:backdrop { color: #919190; }
|
||||
check:checked:hover, radio:checked:hover { background-image: linear-gradient(to bottom, #1b68c6 10%, #185cb0 90%); }
|
||||
|
||||
check:backdrop:disabled, radio:backdrop:disabled { border-color: #202020; background-image: image(#323232); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); }
|
||||
check:checked:active, radio:checked:active { box-shadow: inset 0 1px 1px 0px black; }
|
||||
|
||||
check:backdrop:disabled label, check:backdrop:disabled, radio:backdrop:disabled label, radio:backdrop:disabled { color: #5b5b5b; }
|
||||
check:checked:disabled, radio:checked:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
.osd check, .osd radio { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
check:checked:backdrop, radio:checked:backdrop { background-image: image(#15539e); box-shadow: none; color: #ffffff; }
|
||||
|
||||
.osd check:hover, .osd radio:hover { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
check:checked:backdrop:disabled, radio:checked:backdrop:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
check:indeterminate, radio:indeterminate { background-clip: border-box; background-image: linear-gradient(to bottom, #185fb4 20%, #15539e 90%); border-color: #15539e; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
|
||||
|
||||
check:indeterminate:hover, radio:indeterminate:hover { background-image: linear-gradient(to bottom, #1b68c6 10%, #185cb0 90%); }
|
||||
|
||||
check:indeterminate:active, radio:indeterminate:active { box-shadow: inset 0 1px 1px 0px black; }
|
||||
|
||||
check:indeterminate:disabled, radio:indeterminate:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
check:indeterminate:backdrop, radio:indeterminate:backdrop { background-image: image(#15539e); box-shadow: none; color: #ffffff; }
|
||||
|
||||
check:indeterminate:backdrop:disabled, radio:indeterminate:backdrop:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
check:backdrop, radio:backdrop { transition: 200ms ease-out; }
|
||||
|
||||
.osd check, .osd radio { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd check:hover, .osd radio:hover { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd check:active, .osd radio:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd check:backdrop, .osd radio:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd check:backdrop, .osd radio:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.osd check:disabled, .osd radio:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -1203,6 +1224,8 @@ menu menuitem check, menu menuitem radio { margin: 0; }
|
||||
|
||||
menu menuitem check, menu menuitem check:hover, menu menuitem check:disabled, menu menuitem radio, menu menuitem radio:hover, menu menuitem radio:disabled { min-height: 14px; min-width: 14px; background-image: none; background-color: transparent; box-shadow: none; -gtk-icon-shadow: none; color: inherit; border-color: currentColor; }
|
||||
|
||||
menu menuitem check:indeterminate:hover, menu menuitem check:checked:hover, menu menuitem radio:indeterminate:hover, menu menuitem radio:checked:hover { color: #ffffff; border-color: #030c17; }
|
||||
|
||||
check { border-radius: 3px; -gtk-icon-size: 14px; }
|
||||
|
||||
check:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/check-symbolic.symbolic.png")), -gtk-recolor(url("assets/check@2-symbolic.symbolic.png"))); }
|
||||
@@ -1227,12 +1250,6 @@ menu menuitem radio:checked:not(:backdrop), menu menuitem radio:indeterminate:no
|
||||
|
||||
treeview.view check:selected:focus, treeview.view check:selected, treeview.view radio:selected:focus, treeview.view radio:selected { color: #ffffff; }
|
||||
|
||||
treeview.view check:selected:disabled, treeview.view radio:selected:disabled { color: #919190; }
|
||||
|
||||
treeview.view check:selected:disabled:backdrop, treeview.view radio:selected:disabled:backdrop { color: #5b5b5b; }
|
||||
|
||||
treeview.view check:backdrop:selected, treeview.view check:backdrop, treeview.view radio:backdrop:selected, treeview.view radio:backdrop { color: #919190; }
|
||||
|
||||
/************ GtkScale * */
|
||||
scale trough, scale fill, progressbar trough { border: 1px solid #1b1b1b; border-radius: 3px; background-color: #282828; }
|
||||
|
||||
@@ -1288,7 +1305,7 @@ scale fill:disabled:backdrop, scale fill:disabled { border-color: transparent; b
|
||||
|
||||
.osd scale fill:disabled:backdrop, .osd scale fill:disabled { border-color: transparent; background-color: transparent; }
|
||||
|
||||
scale slider { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to bottom, #2d2d2d 20%, #252526 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); border: 1px solid black; border-radius: 100%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border, box-shadow; }
|
||||
scale slider { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to bottom, #2d2d2d 20%, #262626 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); border: 1px solid black; border-radius: 100%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border, box-shadow; }
|
||||
|
||||
scale slider:hover { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to bottom, #353535 20%, #2b2b2b 90%); }
|
||||
|
||||
@@ -1308,17 +1325,17 @@ scale slider:backdrop:disabled label, scale slider:backdrop:disabled { color: #5
|
||||
|
||||
row:selected scale slider:disabled, row:selected scale slider { border-color: #030c17; }
|
||||
|
||||
.osd scale slider { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); border-color: rgba(0, 0, 0, 0.7); background-color: #252526; }
|
||||
.osd scale slider { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); border-color: rgba(0, 0, 0, 0.7); background-color: #262626; }
|
||||
|
||||
.osd scale slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #252526; }
|
||||
.osd scale slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #262626; }
|
||||
|
||||
.osd scale slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #252526; }
|
||||
.osd scale slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #262626; }
|
||||
|
||||
.osd scale slider:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #252526; }
|
||||
.osd scale slider:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #262626; }
|
||||
|
||||
.osd scale slider:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #252526; }
|
||||
.osd scale slider:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #262626; }
|
||||
|
||||
.osd scale slider:backdrop:disabled { background-color: #252526; }
|
||||
.osd scale slider:backdrop:disabled { background-color: #262626; }
|
||||
|
||||
scale value { color: alpha(currentColor,0.55); }
|
||||
|
||||
@@ -1648,7 +1665,7 @@ row.activatable:selected.has-open-popup, row.activatable:selected:hover { backgr
|
||||
row.activatable:selected:backdrop { background-color: #15539e; }
|
||||
|
||||
/********************* App Notifications * */
|
||||
.app-notification, .app-notification.frame { padding: 10px; border-radius: 0 0 5px 5px; background-color: rgba(37, 37, 38, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
|
||||
.app-notification, .app-notification.frame { padding: 10px; border-radius: 0 0 5px 5px; background-color: rgba(38, 38, 38, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
|
||||
|
||||
.app-notification:backdrop, .app-notification.frame:backdrop { background-image: none; transition: 200ms ease-out; }
|
||||
|
||||
@@ -2041,13 +2058,19 @@ stackswitcher.circular > button.circular, stackswitcher.circular > button.text-b
|
||||
.icon-dropshadow { -gtk-icon-shadow: 0 2px 12px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.7); }
|
||||
|
||||
/********* Emoji * */
|
||||
popover.emoji-picker { padding-left: 0; padding-right: 0; }
|
||||
popover.emoji-picker > contents { padding: 0; }
|
||||
|
||||
button.emoji-section { border-color: transparent; border-width: 3px; border-style: none none solid; border-radius: 0; margin: 2px 4px 2px 4px; padding: 3px 0 0; min-width: 32px; min-height: 28px; /* reset props inherited from the button style */ background: none; box-shadow: none; text-shadow: none; outline-offset: -5px; }
|
||||
popover.emoji-picker > contents entry.search { margin: 5px; }
|
||||
|
||||
button.emoji-section { border-color: transparent; border-width: 3px; border-style: none none solid; border-radius: 0; margin: 2px 8px 4px; padding: 3px 0 0; min-width: 32px; min-height: 28px; /* reset props inherited from the button style */ background: none; box-shadow: none; text-shadow: none; outline-offset: -5px; }
|
||||
|
||||
button.emoji-section:dir(ltr):not(:last-child) { margin-right: 0; }
|
||||
|
||||
button.emoji-section:dir(rtl):not(:last-child) { margin-left: 0; }
|
||||
|
||||
button.emoji-section:backdrop:not(:checked) { border-color: transparent; }
|
||||
|
||||
button.emoji-section:hover { border-color: #1b1b1b; }
|
||||
button.emoji-section:hover { border-color: rgba(238, 238, 236, 0.1); }
|
||||
|
||||
button.emoji-section:checked { border-color: #15539e; }
|
||||
|
||||
@@ -2059,7 +2082,7 @@ button.emoji-section:checked label { opacity: 1; }
|
||||
|
||||
popover.emoji-picker .emoji { font-size: x-large; padding: 6px; border-radius: 6px; }
|
||||
|
||||
popover.emoji-picker .emoji :hover { background: #15539e; }
|
||||
popover.emoji-picker .emoji:hover { background: #15539e; }
|
||||
|
||||
popover.emoji-completion contents row box { border-spacing: 10px; padding: 2px 10px; }
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*************************** Check and Radio buttons * */
|
||||
* { padding: 0; -gtk-secondary-caret-color: #3584e4; }
|
||||
|
||||
button:focus(visible), checkbutton:focus(visible), radiobutton:focus(visible), switch:focus(visible), scale:focus(visible), label:focus(visible), row:focus(visible), flowboxchild:focus(visible) { outline-color: alpha(currentColor,0.3); outline-style: dashed; outline-offset: -3px; outline-width: 1px; -gtk-outline-radius: 3px; }
|
||||
@@ -623,7 +624,7 @@ searchbar > revealer > box { padding: 6px; border-width: 0 0 1px; }
|
||||
.inline-toolbar:backdrop, .location-bar:backdrop, searchbar > revealer > box:backdrop { border-color: #d5d0cc; background-color: #eae8e6; box-shadow: none; transition: 200ms ease-out; }
|
||||
|
||||
/*************** Header bars * */
|
||||
.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #bfb8b1; border-radius: 0; border-spacing: 6px; background: #dfdcd8 linear-gradient(to top, #dad6d2, #e1dedb); box-shadow: inset 0 1px rgba(255, 255, 255, 0.8); /* Darken switchbuttons for headerbars. issue #1588 */ /* hide the close button separator */ }
|
||||
.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #bfb8b1; border-radius: 0; background: #dfdcd8 linear-gradient(to top, #dad6d2, #e1dedb); box-shadow: inset 0 1px rgba(255, 255, 255, 0.8); /* Darken switchbuttons for headerbars. issue #1588 */ /* hide the close button separator */ }
|
||||
|
||||
.titlebar:backdrop:not(headerbar), headerbar:backdrop { border-color: #d5d0cc; background-color: #f6f5f4; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0.8); transition: 200ms ease-out; }
|
||||
|
||||
@@ -713,6 +714,8 @@ searchbar > revealer > box { padding: 6px; border-width: 0 0 1px; }
|
||||
|
||||
.solid-csd .titlebar:backdrop:dir(rtl):not(headerbar), .solid-csd .titlebar:backdrop:dir(ltr):not(headerbar), .solid-csd .titlebar:dir(rtl):not(headerbar), .solid-csd .titlebar:dir(ltr):not(headerbar), .solid-csd headerbar:backdrop:dir(rtl), .solid-csd headerbar:backdrop:dir(ltr), .solid-csd headerbar:dir(rtl), .solid-csd headerbar:dir(ltr) { margin-left: -1px; margin-right: -1px; margin-top: -1px; border-radius: 0; box-shadow: none; }
|
||||
|
||||
headerbar { border-spacing: 6px; }
|
||||
|
||||
headerbar entry, headerbar spinbutton, headerbar separator:not(.sidebar), headerbar button, headerbar menubutton { margin-top: 6px; margin-bottom: 6px; }
|
||||
|
||||
headerbar menubutton > button { margin-top: 0px; margin-bottom: 0px; }
|
||||
@@ -1163,7 +1166,7 @@ row:selected switch slider:checked, row:selected switch slider { border-color: #
|
||||
|
||||
.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(53, 132, 228, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(140, 140, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: rgba(141, 141, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view .tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: rgba(53, 132, 228, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -1171,11 +1174,11 @@ row:selected switch slider:checked, row:selected switch slider { border-color: #
|
||||
|
||||
.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list), .content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: rgba(53, 132, 228, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: rgba(140, 140, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: rgba(141, 141, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
|
||||
|
||||
checkbutton.text-button, radiobutton.text-button { padding: 2px 0; outline-offset: 0; border-spacing: 4px; }
|
||||
|
||||
check, radio { margin: 0 4px; min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #bfb8b1; text-shadow: 0 1px rgba(255, 255, 255, 0.769231); -gtk-icon-shadow: 0 1px rgba(255, 255, 255, 0.769231); background-image: linear-gradient(to bottom, white 20%, #f6f5f4 90%); box-shadow: inset 0 1px white, 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
check, radio { margin: 0 4px; min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; }
|
||||
|
||||
check:only-child, radio:only-child { margin: 0; }
|
||||
|
||||
@@ -1183,25 +1186,43 @@ popover check.left:dir(rtl), popover radio.left:dir(rtl) { margin-left: 0; margi
|
||||
|
||||
popover check.right:dir(ltr), popover radio.right:dir(ltr) { margin-left: 12px; margin-right: 0; }
|
||||
|
||||
check:hover, radio:hover { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #15539e; box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to bottom, #5d9de9 10%, #478fe6 90%); }
|
||||
check, radio { background-clip: padding-box; background-image: linear-gradient(to bottom, white 20%, white 90%); border-color: #bfb8b1; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #2e3436; }
|
||||
|
||||
check:hover:not(:checked), radio:hover:not(:checked) { color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #bfb8b1; box-shadow: inset 0 1px white, 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to bottom, white 10%, white 90%); }
|
||||
check:hover, radio:hover { background-image: image(#f2f2f2); }
|
||||
|
||||
check:active, radio:active { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #1b6acb; background-image: image(#1961b9); box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
check:active, radio:active { box-shadow: inset 0 1px 1px 0px rgba(0, 0, 0, 0.2); }
|
||||
|
||||
check:checked, radio:checked { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #15539e; text-shadow: 0 -1px rgba(0, 0, 0, 0.559216); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.559216); background-image: linear-gradient(to bottom, #4b92e7 20%, #3584e4 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
check:disabled, radio:disabled { box-shadow: none; color: rgba(46, 52, 54, 0.7); }
|
||||
|
||||
check:disabled, radio:disabled { border-color: #cdc7c2; background-image: image(#faf9f8); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); }
|
||||
check:backdrop, radio:backdrop { background-image: image(white); box-shadow: none; color: #2e3436; }
|
||||
|
||||
check:disabled label, check:disabled, radio:disabled label, radio:disabled { color: #929595; }
|
||||
check:backdrop:disabled, radio:backdrop:disabled { box-shadow: none; color: rgba(46, 52, 54, 0.7); }
|
||||
|
||||
check:backdrop, radio:backdrop { border-color: #d5d0cc; background-image: image(#f6f5f4); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); transition: 200ms ease-out; }
|
||||
check:checked, radio:checked { background-clip: border-box; background-image: linear-gradient(to bottom, #4b92e7 20%, #3584e4 90%); border-color: #3584e4; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
|
||||
|
||||
check:backdrop label, check:backdrop, radio:backdrop label, radio:backdrop { color: #929595; }
|
||||
check:checked:hover, radio:checked:hover { background-image: linear-gradient(to bottom, #5d9de9 10%, #478fe6 90%); }
|
||||
|
||||
check:backdrop:disabled, radio:backdrop:disabled { border-color: #d5d0cc; background-image: image(#faf9f8); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); }
|
||||
check:checked:active, radio:checked:active { box-shadow: inset 0 1px 1px 0px rgba(0, 0, 0, 0.2); }
|
||||
|
||||
check:backdrop:disabled label, check:backdrop:disabled, radio:backdrop:disabled label, radio:backdrop:disabled { color: #d4cfca; }
|
||||
check:checked:disabled, radio:checked:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
check:checked:backdrop, radio:checked:backdrop { background-image: image(#3584e4); box-shadow: none; color: #ffffff; }
|
||||
|
||||
check:checked:backdrop:disabled, radio:checked:backdrop:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
check:indeterminate, radio:indeterminate { background-clip: border-box; background-image: linear-gradient(to bottom, #4b92e7 20%, #3584e4 90%); border-color: #3584e4; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
|
||||
|
||||
check:indeterminate:hover, radio:indeterminate:hover { background-image: linear-gradient(to bottom, #5d9de9 10%, #478fe6 90%); }
|
||||
|
||||
check:indeterminate:active, radio:indeterminate:active { box-shadow: inset 0 1px 1px 0px rgba(0, 0, 0, 0.2); }
|
||||
|
||||
check:indeterminate:disabled, radio:indeterminate:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
check:indeterminate:backdrop, radio:indeterminate:backdrop { background-image: image(#3584e4); box-shadow: none; color: #ffffff; }
|
||||
|
||||
check:indeterminate:backdrop:disabled, radio:indeterminate:backdrop:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
check:backdrop, radio:backdrop { transition: 200ms ease-out; }
|
||||
|
||||
row:selected check, row:selected radio { border-color: #185fb4; }
|
||||
|
||||
@@ -1219,6 +1240,8 @@ menu menuitem check, menu menuitem radio { margin: 0; }
|
||||
|
||||
menu menuitem check, menu menuitem check:hover, menu menuitem check:disabled, menu menuitem radio, menu menuitem radio:hover, menu menuitem radio:disabled { min-height: 14px; min-width: 14px; background-image: none; background-color: transparent; box-shadow: none; -gtk-icon-shadow: none; color: inherit; border-color: currentColor; }
|
||||
|
||||
menu menuitem check:indeterminate:hover, menu menuitem check:checked:hover, menu menuitem radio:indeterminate:hover, menu menuitem radio:checked:hover { color: #ffffff; border-color: #185fb4; }
|
||||
|
||||
check { border-radius: 3px; -gtk-icon-size: 14px; }
|
||||
|
||||
check:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/check-symbolic.symbolic.png")), -gtk-recolor(url("assets/check@2-symbolic.symbolic.png"))); }
|
||||
@@ -1243,12 +1266,6 @@ menu menuitem radio:checked:not(:backdrop), menu menuitem radio:indeterminate:no
|
||||
|
||||
treeview.view check:selected:focus, treeview.view check:selected, treeview.view radio:selected:focus, treeview.view radio:selected { color: #ffffff; border-color: #185fb4; }
|
||||
|
||||
treeview.view check:selected:disabled, treeview.view radio:selected:disabled { color: #929595; }
|
||||
|
||||
treeview.view check:selected:disabled:backdrop, treeview.view radio:selected:disabled:backdrop { color: #d4cfca; }
|
||||
|
||||
treeview.view check:backdrop:selected, treeview.view check:backdrop, treeview.view radio:backdrop:selected, treeview.view radio:backdrop { color: #929595; }
|
||||
|
||||
/************ GtkScale * */
|
||||
scale trough, scale fill, progressbar trough { border: 1px solid #cdc7c2; border-radius: 3px; background-color: #e1dedb; }
|
||||
|
||||
@@ -2057,9 +2074,15 @@ stackswitcher.circular > button.circular, stackswitcher.circular > button.text-b
|
||||
.icon-dropshadow { -gtk-icon-shadow: 0 2px 12px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.7); }
|
||||
|
||||
/********* Emoji * */
|
||||
popover.emoji-picker { padding-left: 0; padding-right: 0; }
|
||||
popover.emoji-picker > contents { padding: 0; }
|
||||
|
||||
button.emoji-section { border-color: transparent; border-width: 3px; border-style: none none solid; border-radius: 0; margin: 2px 4px 2px 4px; padding: 3px 0 0; min-width: 32px; min-height: 28px; /* reset props inherited from the button style */ background: none; box-shadow: none; text-shadow: none; outline-offset: -5px; }
|
||||
popover.emoji-picker > contents entry.search { margin: 5px; }
|
||||
|
||||
button.emoji-section { border-color: transparent; border-width: 3px; border-style: none none solid; border-radius: 0; margin: 2px 8px 4px; padding: 3px 0 0; min-width: 32px; min-height: 28px; /* reset props inherited from the button style */ background: none; box-shadow: none; text-shadow: none; outline-offset: -5px; }
|
||||
|
||||
button.emoji-section:dir(ltr):not(:last-child) { margin-right: 0; }
|
||||
|
||||
button.emoji-section:dir(rtl):not(:last-child) { margin-left: 0; }
|
||||
|
||||
button.emoji-section:backdrop:not(:checked) { border-color: transparent; }
|
||||
|
||||
@@ -2075,7 +2098,7 @@ button.emoji-section:checked label { opacity: 1; }
|
||||
|
||||
popover.emoji-picker .emoji { font-size: x-large; padding: 6px; border-radius: 6px; }
|
||||
|
||||
popover.emoji-picker .emoji :hover { background: #3584e4; }
|
||||
popover.emoji-picker .emoji:hover { background: #3584e4; }
|
||||
|
||||
popover.emoji-completion contents row box { border-spacing: 10px; padding: 2px 10px; }
|
||||
|
||||
|
||||
+326
-306
File diff suppressed because it is too large
Load Diff
+340
-312
File diff suppressed because it is too large
Load Diff
@@ -126,6 +126,7 @@ gtk_tests = [
|
||||
['testblur'],
|
||||
['testtexture'],
|
||||
['testwindowdrag'],
|
||||
['testtexthistory', ['../gtk/gtktexthistory.c']],
|
||||
]
|
||||
|
||||
if os_unix
|
||||
|
||||
@@ -107,6 +107,7 @@ main (int argc, char *argv[])
|
||||
popover1 = gtk_popover_menu_new_from_model_full (NULL, model, GTK_POPOVER_MENU_NESTED);
|
||||
gtk_menu_button_set_popover (GTK_MENU_BUTTON (button1), popover1);
|
||||
|
||||
g_object_unref (builder);
|
||||
builder = gtk_builder_new_from_file ("popover2.ui");
|
||||
popover2 = (GtkWidget *)gtk_builder_get_object (builder, "popover");
|
||||
gtk_menu_button_set_popover (GTK_MENU_BUTTON (button2), popover2);
|
||||
@@ -164,6 +165,7 @@ main (int argc, char *argv[])
|
||||
g_object_bind_property (combo, "active", box, "valign", G_BINDING_SYNC_CREATE);
|
||||
gtk_grid_attach (GTK_GRID (grid), label , 1, 5, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), combo, 2, 5, 1, 1);
|
||||
g_object_unref (builder);
|
||||
|
||||
|
||||
g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
@@ -0,0 +1,600 @@
|
||||
#include "gtktexthistoryprivate.h"
|
||||
|
||||
#if 0
|
||||
# define DEBUG_COMMANDS
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkTextHistory *history;
|
||||
GString *buf;
|
||||
struct {
|
||||
int insert;
|
||||
int bound;
|
||||
} selection;
|
||||
guint can_redo : 1;
|
||||
guint can_undo : 1;
|
||||
guint is_modified : 1;
|
||||
} Text;
|
||||
|
||||
enum {
|
||||
IGNORE = 0,
|
||||
SET = 1,
|
||||
UNSET = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
IGNORE_SELECT = 0,
|
||||
DO_SELECT = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
INSERT = 1,
|
||||
INSERT_SEQ,
|
||||
BACKSPACE,
|
||||
DELETE_KEY,
|
||||
UNDO,
|
||||
REDO,
|
||||
BEGIN_IRREVERSIBLE,
|
||||
END_IRREVERSIBLE,
|
||||
BEGIN_USER,
|
||||
END_USER,
|
||||
MODIFIED,
|
||||
UNMODIFIED,
|
||||
SELECT,
|
||||
CHECK_SELECT,
|
||||
SET_MAX_UNDO,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int kind;
|
||||
int location;
|
||||
int end_location;
|
||||
const char *text;
|
||||
const char *expected;
|
||||
int can_undo;
|
||||
int can_redo;
|
||||
int is_modified;
|
||||
int select;
|
||||
} Command;
|
||||
|
||||
static void
|
||||
do_change_state (gpointer funcs_data,
|
||||
gboolean is_modified,
|
||||
gboolean can_undo,
|
||||
gboolean can_redo)
|
||||
{
|
||||
Text *text = funcs_data;
|
||||
|
||||
text->is_modified = is_modified;
|
||||
text->can_undo = can_undo;
|
||||
text->can_redo = can_redo;
|
||||
}
|
||||
|
||||
static void
|
||||
do_insert (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const char *text,
|
||||
guint len)
|
||||
{
|
||||
Text *t = funcs_data;
|
||||
|
||||
#ifdef DEBUG_COMMANDS
|
||||
g_printerr ("Insert Into '%s' (begin=%u end=%u text=%s)\n",
|
||||
t->buf->str, begin, end, text);
|
||||
#endif
|
||||
|
||||
g_string_insert_len (t->buf, begin, text, len);
|
||||
}
|
||||
|
||||
static void
|
||||
do_delete (gpointer funcs_data,
|
||||
guint begin,
|
||||
guint end,
|
||||
const gchar *expected_text,
|
||||
guint len)
|
||||
{
|
||||
Text *t = funcs_data;
|
||||
|
||||
#ifdef DEBUG_COMMANDS
|
||||
g_printerr ("Delete(begin=%u end=%u expected_text=%s)\n", begin, end, expected_text);
|
||||
#endif
|
||||
|
||||
if (end < begin)
|
||||
{
|
||||
guint tmp = end;
|
||||
end = begin;
|
||||
begin = tmp;
|
||||
}
|
||||
|
||||
g_assert_cmpint (memcmp (t->buf->str + begin, expected_text, len), ==, 0);
|
||||
|
||||
if (end >= t->buf->len)
|
||||
{
|
||||
t->buf->len = begin;
|
||||
t->buf->str[begin] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
memmove (t->buf->str + begin,
|
||||
t->buf->str + end,
|
||||
t->buf->len - end);
|
||||
g_string_truncate (t->buf, t->buf->len - (end - begin));
|
||||
}
|
||||
|
||||
static void
|
||||
do_select (gpointer funcs_data,
|
||||
gint selection_insert,
|
||||
gint selection_bound)
|
||||
{
|
||||
Text *text = funcs_data;
|
||||
|
||||
text->selection.insert = selection_insert;
|
||||
text->selection.bound = selection_bound;
|
||||
}
|
||||
|
||||
static GtkTextHistoryFuncs funcs = {
|
||||
do_change_state,
|
||||
do_insert,
|
||||
do_delete,
|
||||
do_select,
|
||||
};
|
||||
|
||||
static Text *
|
||||
text_new (void)
|
||||
{
|
||||
Text *text = g_slice_new0 (Text);
|
||||
|
||||
text->history = gtk_text_history_new (&funcs, text);
|
||||
text->buf = g_string_new (NULL);
|
||||
text->selection.insert = -1;
|
||||
text->selection.bound = -1;
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static void
|
||||
text_free (Text *text)
|
||||
{
|
||||
g_object_unref (text->history);
|
||||
g_string_free (text->buf, TRUE);
|
||||
g_slice_free (Text, text);
|
||||
}
|
||||
|
||||
static void
|
||||
command_insert (const Command *cmd,
|
||||
Text *text)
|
||||
{
|
||||
do_insert (text,
|
||||
cmd->location,
|
||||
cmd->location + g_utf8_strlen (cmd->text, -1),
|
||||
cmd->text,
|
||||
strlen (cmd->text));
|
||||
gtk_text_history_text_inserted (text->history, cmd->location, cmd->text, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
command_delete_key (const Command *cmd,
|
||||
Text *text)
|
||||
{
|
||||
do_delete (text,
|
||||
cmd->location,
|
||||
cmd->end_location,
|
||||
cmd->text,
|
||||
strlen (cmd->text));
|
||||
gtk_text_history_text_deleted (text->history,
|
||||
cmd->location,
|
||||
cmd->end_location,
|
||||
cmd->text,
|
||||
ABS (cmd->end_location - cmd->location));
|
||||
}
|
||||
|
||||
static void
|
||||
command_undo (const Command *cmd,
|
||||
Text *text)
|
||||
{
|
||||
gtk_text_history_undo (text->history);
|
||||
}
|
||||
|
||||
static void
|
||||
command_redo (const Command *cmd,
|
||||
Text *text)
|
||||
{
|
||||
gtk_text_history_redo (text->history);
|
||||
}
|
||||
|
||||
static void
|
||||
set_selection (Text *text,
|
||||
int begin,
|
||||
int end)
|
||||
{
|
||||
gtk_text_history_selection_changed (text->history, begin, end);
|
||||
}
|
||||
|
||||
static void
|
||||
run_test (const Command *commands,
|
||||
guint n_commands,
|
||||
guint max_undo)
|
||||
{
|
||||
Text *text = text_new ();
|
||||
|
||||
if (max_undo)
|
||||
gtk_text_history_set_max_undo_levels (text->history, max_undo);
|
||||
|
||||
for (guint i = 0; i < n_commands; i++)
|
||||
{
|
||||
const Command *cmd = &commands[i];
|
||||
|
||||
#ifdef DEBUG_COMMANDS
|
||||
g_printerr ("%d: %d\n", i, cmd->kind);
|
||||
#endif
|
||||
|
||||
switch (cmd->kind)
|
||||
{
|
||||
case INSERT:
|
||||
command_insert (cmd, text);
|
||||
break;
|
||||
|
||||
case INSERT_SEQ:
|
||||
for (guint j = 0; cmd->text[j]; j++)
|
||||
{
|
||||
const char seqtext[2] = { cmd->text[j], 0 };
|
||||
Command seq = { INSERT, cmd->location + j, 1, seqtext, NULL };
|
||||
command_insert (&seq, text);
|
||||
}
|
||||
break;
|
||||
|
||||
case DELETE_KEY:
|
||||
if (cmd->select == DO_SELECT)
|
||||
set_selection (text, cmd->location, cmd->end_location);
|
||||
else if (strlen (cmd->text) == 1)
|
||||
set_selection (text, cmd->location, -1);
|
||||
else
|
||||
set_selection (text, -1, -1);
|
||||
command_delete_key (cmd, text);
|
||||
break;
|
||||
|
||||
case BACKSPACE:
|
||||
if (cmd->select == DO_SELECT)
|
||||
set_selection (text, cmd->location, cmd->end_location);
|
||||
else if (strlen (cmd->text) == 1)
|
||||
set_selection (text, cmd->end_location, -1);
|
||||
else
|
||||
set_selection (text, -1, -1);
|
||||
command_delete_key (cmd, text);
|
||||
break;
|
||||
|
||||
case UNDO:
|
||||
command_undo (cmd, text);
|
||||
break;
|
||||
|
||||
case REDO:
|
||||
command_redo (cmd, text);
|
||||
break;
|
||||
|
||||
case BEGIN_USER:
|
||||
gtk_text_history_begin_user_action (text->history);
|
||||
break;
|
||||
|
||||
case END_USER:
|
||||
gtk_text_history_end_user_action (text->history);
|
||||
break;
|
||||
|
||||
case BEGIN_IRREVERSIBLE:
|
||||
gtk_text_history_begin_irreversible_action (text->history);
|
||||
break;
|
||||
|
||||
case END_IRREVERSIBLE:
|
||||
gtk_text_history_end_irreversible_action (text->history);
|
||||
break;
|
||||
|
||||
case MODIFIED:
|
||||
gtk_text_history_modified_changed (text->history, TRUE);
|
||||
break;
|
||||
|
||||
case UNMODIFIED:
|
||||
gtk_text_history_modified_changed (text->history, FALSE);
|
||||
break;
|
||||
|
||||
case SELECT:
|
||||
gtk_text_history_selection_changed (text->history,
|
||||
cmd->location,
|
||||
cmd->end_location);
|
||||
break;
|
||||
|
||||
case CHECK_SELECT:
|
||||
g_assert_cmpint (text->selection.insert, ==, cmd->location);
|
||||
g_assert_cmpint (text->selection.bound, ==, cmd->end_location);
|
||||
break;
|
||||
|
||||
case SET_MAX_UNDO:
|
||||
/* Not ideal use of location, but fine */
|
||||
gtk_text_history_set_max_undo_levels (text->history, cmd->location);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd->expected)
|
||||
g_assert_cmpstr (text->buf->str, ==, cmd->expected);
|
||||
|
||||
if (cmd->can_redo == SET)
|
||||
g_assert_cmpint (text->can_redo, ==, TRUE);
|
||||
else if (cmd->can_redo == UNSET)
|
||||
g_assert_cmpint (text->can_redo, ==, FALSE);
|
||||
|
||||
if (cmd->can_undo == SET)
|
||||
g_assert_cmpint (text->can_undo, ==, TRUE);
|
||||
else if (cmd->can_undo == UNSET)
|
||||
g_assert_cmpint (text->can_undo, ==, FALSE);
|
||||
|
||||
if (cmd->is_modified == SET)
|
||||
g_assert_cmpint (text->is_modified, ==, TRUE);
|
||||
else if (cmd->is_modified == UNSET)
|
||||
g_assert_cmpint (text->is_modified, ==, FALSE);
|
||||
}
|
||||
|
||||
text_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
test1 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ INSERT, 0, -1, "test", "test", SET, UNSET },
|
||||
{ INSERT, 2, -1, "s", "tesst", SET, UNSET },
|
||||
{ INSERT, 3, -1, "ss", "tesssst", SET, UNSET },
|
||||
{ DELETE_KEY, 2, 5, "sss", "test", SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "tesssst", SET, SET },
|
||||
{ REDO, -1, -1, NULL, "test", SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "tesssst", SET, SET },
|
||||
{ DELETE_KEY, 0, 7, "tesssst", "", SET, UNSET },
|
||||
{ INSERT, 0, -1, "z", "z", SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, "tesssst", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, "test", SET, SET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test2 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ BEGIN_IRREVERSIBLE, -1, -1, NULL, "", UNSET, UNSET },
|
||||
{ INSERT, 0, -1, "this is a test", "this is a test", UNSET, UNSET },
|
||||
{ END_IRREVERSIBLE, -1, -1, NULL, "this is a test", UNSET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test", UNSET, UNSET },
|
||||
{ REDO, -1, -1, NULL, "this is a test", UNSET, UNSET },
|
||||
{ BEGIN_USER, -1, -1, NULL, NULL, UNSET, UNSET },
|
||||
{ INSERT, 0, -1, "first", "firstthis is a test", UNSET, UNSET },
|
||||
{ INSERT, 5, -1, " ", "first this is a test", UNSET, UNSET },
|
||||
{ END_USER, -1, -1, NULL, "first this is a test", SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test", UNSET, SET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test", UNSET, SET },
|
||||
{ REDO, -1, -1, NULL, "first this is a test", SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test", UNSET, SET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test3 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ INSERT_SEQ, 0, -1, "this is a test of insertions.", "this is a test of insertions.", SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test of", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, "this is a", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, "this is", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, "this", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, "", UNSET, SET },
|
||||
{ UNDO, -1, -1, NULL, "" , UNSET, SET },
|
||||
{ REDO, -1, -1, NULL, "this", SET, SET },
|
||||
{ REDO, -1, -1, NULL, "this is", SET, SET },
|
||||
{ REDO, -1, -1, NULL, "this is a", SET, SET },
|
||||
{ REDO, -1, -1, NULL, "this is a test", SET, SET },
|
||||
{ REDO, -1, -1, NULL, "this is a test of", SET, SET },
|
||||
{ REDO, -1, -1, NULL, "this is a test of insertions.", SET, UNSET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test4 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ INSERT, 0, -1, "initial text", "initial text", SET, UNSET },
|
||||
/* Barrier */
|
||||
{ BEGIN_IRREVERSIBLE, -1, -1, NULL, NULL, UNSET, UNSET },
|
||||
{ END_IRREVERSIBLE, -1, -1, NULL, NULL, UNSET, UNSET },
|
||||
{ INSERT, 0, -1, "more text ", "more text initial text", SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "initial text", UNSET, SET },
|
||||
{ UNDO, -1, -1, NULL, "initial text", UNSET, SET },
|
||||
{ REDO, -1, -1, NULL, "more text initial text", SET, UNSET },
|
||||
/* Barrier */
|
||||
{ BEGIN_IRREVERSIBLE, UNSET, UNSET },
|
||||
{ END_IRREVERSIBLE, UNSET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "more text initial text", UNSET, UNSET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test5 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ INSERT, 0, -1, "initial text", "initial text", SET, UNSET },
|
||||
{ DELETE_KEY, 0, 12, "initial text", "", SET, UNSET },
|
||||
/* Add empty nested user action (should get ignored) */
|
||||
{ BEGIN_USER, -1, -1, NULL, NULL, UNSET, UNSET },
|
||||
{ BEGIN_USER, -1, -1, NULL, NULL, UNSET, UNSET },
|
||||
{ BEGIN_USER, -1, -1, NULL, NULL, UNSET, UNSET },
|
||||
{ END_USER, -1, -1, NULL, NULL, UNSET, UNSET },
|
||||
{ END_USER, -1, -1, NULL, NULL, UNSET, UNSET },
|
||||
{ END_USER, -1, -1, NULL, NULL, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "initial text" },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test6 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ INSERT_SEQ, 0, -1, " \t\t this is some text", " \t\t this is some text", SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, " \t\t this is some", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, " \t\t this is", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, " \t\t this", SET, SET },
|
||||
{ UNDO, -1, -1, NULL, "", UNSET, SET },
|
||||
{ UNDO, -1, -1, NULL, "", UNSET, SET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test7 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ MODIFIED, -1, -1, NULL, NULL, UNSET, UNSET, SET },
|
||||
{ UNMODIFIED, -1, -1, NULL, NULL, UNSET, UNSET, UNSET },
|
||||
{ INSERT, 0, -1, "foo bar", "foo bar", SET, UNSET, UNSET },
|
||||
{ MODIFIED, -1, -1, NULL, NULL, SET, UNSET, SET },
|
||||
{ UNDO, -1, -1, NULL, "", UNSET, SET, UNSET },
|
||||
{ REDO, -1, -1, NULL, "foo bar", SET, UNSET, SET },
|
||||
{ UNDO, -1, -1, NULL, "", UNSET, SET, UNSET },
|
||||
{ REDO, -1, -1, NULL, "foo bar", SET, UNSET, SET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test8 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ INSERT, 0, -1, "foo bar", "foo bar", SET, UNSET, UNSET },
|
||||
{ MODIFIED, -1, -1, NULL, NULL, SET, UNSET, SET },
|
||||
{ INSERT, 0, -1, "f", "ffoo bar", SET, UNSET, SET },
|
||||
{ UNMODIFIED, -1, -1, NULL, NULL, SET, UNSET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "foo bar", SET, SET, SET },
|
||||
{ UNDO, -1, -1, NULL, "", UNSET, SET, SET },
|
||||
{ REDO, -1, -1, NULL, "foo bar", SET, SET, SET },
|
||||
{ REDO, -1, -1, NULL, "ffoo bar", SET, UNSET, UNSET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test9 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ INSERT, 0, -1, "foo bar", "foo bar", SET, UNSET, UNSET },
|
||||
{ DELETE_KEY, 0, 3, "foo", " bar", SET, UNSET, UNSET, DO_SELECT },
|
||||
{ DELETE_KEY, 0, 4, " bar", "", SET, UNSET, UNSET, DO_SELECT },
|
||||
{ UNDO, -1, -1, NULL, " bar", SET, SET, UNSET },
|
||||
{ CHECK_SELECT, 0, 4, NULL, " bar", SET, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "foo bar", SET, SET, UNSET },
|
||||
{ CHECK_SELECT, 0, 3, NULL, "foo bar", SET, SET, UNSET },
|
||||
{ BEGIN_IRREVERSIBLE, -1, -1, NULL, "foo bar", UNSET, UNSET, UNSET },
|
||||
{ END_IRREVERSIBLE, -1, -1, NULL, "foo bar", UNSET, UNSET, UNSET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test10 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ BEGIN_USER }, { INSERT, 0, -1, "t", "t", UNSET, UNSET, UNSET }, { END_USER },
|
||||
{ BEGIN_USER }, { INSERT, 1, -1, " ", "t ", UNSET, UNSET, UNSET }, { END_USER },
|
||||
{ BEGIN_USER }, { INSERT, 2, -1, "t", "t t", UNSET, UNSET, UNSET }, { END_USER },
|
||||
{ BEGIN_USER }, { INSERT, 3, -1, "h", "t th", UNSET, UNSET, UNSET }, { END_USER },
|
||||
{ BEGIN_USER }, { INSERT, 4, -1, "i", "t thi", UNSET, UNSET, UNSET }, { END_USER },
|
||||
{ BEGIN_USER }, { INSERT, 5, -1, "s", "t this", UNSET, UNSET, UNSET }, { END_USER },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test11 (void)
|
||||
{
|
||||
/* Test backspace */
|
||||
static const Command commands[] = {
|
||||
{ INSERT_SEQ, 0, -1, "insert some text", "insert some text", SET, UNSET, UNSET },
|
||||
{ BACKSPACE, 15, 16, "t", "insert some tex", SET, UNSET, UNSET },
|
||||
{ BACKSPACE, 14, 15, "x", "insert some te", SET, UNSET, UNSET },
|
||||
{ BACKSPACE, 13, 14, "e", "insert some t", SET, UNSET, UNSET },
|
||||
{ BACKSPACE, 12, 13, "t", "insert some ", SET, UNSET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "insert some text", SET, SET, UNSET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test12 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ INSERT_SEQ, 0, -1, "this is a test\nmore", "this is a test\nmore", SET, UNSET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test\n", SET, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test", SET, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a", SET, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is", SET, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this", SET, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "", UNSET, SET, UNSET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test13 (void)
|
||||
{
|
||||
static const Command commands[] = {
|
||||
{ INSERT_SEQ, 0, -1, "this is a test\nmore", "this is a test\nmore", SET, UNSET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test\n", SET, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a test", SET, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a", UNSET, SET, UNSET },
|
||||
{ UNDO, -1, -1, NULL, "this is a", UNSET, SET, UNSET },
|
||||
{ SET_MAX_UNDO, 2, -1, NULL, "this is a", UNSET, SET, UNSET },
|
||||
{ REDO, -1, -1, NULL, "this is a test", SET, SET, UNSET },
|
||||
{ REDO, -1, -1, NULL, "this is a test\n", SET, UNSET, UNSET },
|
||||
{ REDO, -1, -1, NULL, "this is a test\n", SET, UNSET, UNSET },
|
||||
};
|
||||
|
||||
run_test (commands, G_N_ELEMENTS (commands), 3);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_test_add_func ("/Gtk/TextHistory/test1", test1);
|
||||
g_test_add_func ("/Gtk/TextHistory/test2", test2);
|
||||
g_test_add_func ("/Gtk/TextHistory/test3", test3);
|
||||
g_test_add_func ("/Gtk/TextHistory/test4", test4);
|
||||
g_test_add_func ("/Gtk/TextHistory/test5", test5);
|
||||
g_test_add_func ("/Gtk/TextHistory/test6", test6);
|
||||
g_test_add_func ("/Gtk/TextHistory/test7", test7);
|
||||
g_test_add_func ("/Gtk/TextHistory/test8", test8);
|
||||
g_test_add_func ("/Gtk/TextHistory/test9", test9);
|
||||
g_test_add_func ("/Gtk/TextHistory/test10", test10);
|
||||
g_test_add_func ("/Gtk/TextHistory/test11", test11);
|
||||
g_test_add_func ("/Gtk/TextHistory/test12", test12);
|
||||
g_test_add_func ("/Gtk/TextHistory/test13", test13);
|
||||
return g_test_run ();
|
||||
}
|
||||
@@ -358,6 +358,8 @@ test_introspection (void)
|
||||
const char *params;
|
||||
const char *property;
|
||||
} expected[] = {
|
||||
{ GTK_TYPE_TEXT, "text.undo", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "text.redo", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "clipboard.cut", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "clipboard.copy", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "clipboard.paste", NULL, NULL },
|
||||
|
||||
Reference in New Issue
Block a user