Compare commits

..

6 Commits

Author SHA1 Message Date
Emmanuele Bassi
8e39ff4271 ci: Enable libcloudproviders support
We ended up breaking the build when it's enabled, so we should test the
feature in our CI pipeline.
2020-06-09 15:47:36 +01:00
Emmanuele Bassi
dd7251cb9f Add libcloudproviders as a fallback subproject
We require a new version of libcloudproviders so that we can enable it
in our CI pipeline.
2020-06-09 15:47:36 +01:00
Emmanuele Bassi
2a7e4b278e ci: Move backend Meson flags into a variable
So we don't have to copy them around.
2020-06-09 15:47:36 +01:00
Emmanuele Bassi
04f25bf901 ci: Update the CI images 2020-06-09 15:47:36 +01:00
Emmanuele Bassi
a6049c3be4 ci: Rebase the Fedora CI image 2020-06-09 15:47:36 +01:00
Emmanuele Bassi
1b9d165252 ci: Add libcloudproviders to the base CI image 2020-06-09 15:47:36 +01:00
387 changed files with 24384 additions and 53369 deletions

View File

@@ -20,7 +20,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true -Dvulkan=yes"
FEATURE_FLAGS: "-Dcloudproviders=true"
MESON_TEST_TIMEOUT_MULTIPLIER: 2
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v17"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v18"
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
@@ -107,10 +107,10 @@ release-build:
- subprojects/libepoxy/
- subprojects/pango/
msys2-mingw64:
msys2-mingw32:
extends: .mingw-defaults
variables:
MSYSTEM: "MINGW64"
MSYSTEM: "MINGW32"
CHERE_INVOKING: "yes"
.flatpak-defaults:

View File

@@ -42,6 +42,7 @@ RUN dnf -y install \
json-glib-devel \
lcov \
libattr-devel \
libcloudproviders-devel \
libepoxy-devel \
libffi-devel \
libmount-devel \

View File

@@ -1,4 +1,4 @@
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v20
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}

View File

@@ -4,15 +4,8 @@ set -e
# We need to add a new remote for the upstream master, since this script could
# be running in a personal fork of the repository which has out of date branches.
if [ "${CI_PROJECT_NAMESPACE}" != "GNOME" ]; then
echo "Retrieving the current upstream repository from ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}..."
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
git fetch upstream
ORIGIN="upstream"
else
echo "Reusing the existing repository on ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}"
ORIGIN="origin"
fi
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
git fetch upstream
# Work out the newest common ancestor between the detached HEAD that this CI job
# has checked out, and the upstream target branch (which will typically be
@@ -20,7 +13,7 @@ fi
#
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if were running in
# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${ORIGIN}/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "upstream/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
git diff -U0 --no-color "${newest_common_ancestor_sha}" | .gitlab-ci/clang-format-diff.py -binary "clang-format" -p1
exit_status=$?

View File

@@ -94,7 +94,7 @@ do_css_basics (GtkWidget *do_widget)
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
container = gtk_scrolled_window_new ();
container = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), container);
child = gtk_text_view_new_with_buffer (text);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);

View File

@@ -132,7 +132,7 @@ do_css_multiplebgs (GtkWidget *do_widget)
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_paned_set_end_child (GTK_PANED (paned), sw);
child = gtk_text_view_new_with_buffer (text);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child);

View File

@@ -101,7 +101,7 @@ do_css_pixbufs (GtkWidget *do_widget)
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
container = gtk_scrolled_window_new ();
container = gtk_scrolled_window_new (NULL, NULL);
gtk_paned_set_end_child (GTK_PANED (paned), container);
child = gtk_text_view_new_with_buffer (text);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);

View File

@@ -119,7 +119,7 @@ do_css_shadows (GtkWidget *do_widget)
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
container = gtk_scrolled_window_new ();
container = gtk_scrolled_window_new (NULL, NULL);
gtk_paned_set_end_child (GTK_PANED (paned), container);
child = gtk_text_view_new_with_buffer (text);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);

View File

@@ -105,9 +105,6 @@
<file>zoom_in_cursor.png</file>
<file>zoom_out_cursor.png</file>
</gresource>
<gresource prefix="/dnd">
<file>dnd.css</file>
</gresource>
<gresource prefix="/fishbowl">
<file>fishbowl.ui</file>
<file>gtkfishbowl.c</file>
@@ -225,7 +222,6 @@
<file>listview_minesweeper.c</file>
<file>listview_settings.c</file>
<file>listview_weather.c</file>
<file>listview_words.c</file>
<file>list_store.c</file>
<file>markup.c</file>
<file>modelbutton.c</file>
@@ -300,7 +296,6 @@
</gresource>
<gresource prefix="/transparent">
<file>portland-rose.jpg</file>
<file>bluroverlay.h</file>
<file>bluroverlay.c</file>
</gresource>
<gresource prefix="/markup">

View File

@@ -25,36 +25,31 @@
#include <gtk/gtk.h>
#include <gtk/gtk-a11y.h>
struct _DemoTaggedEntry
{
GtkWidget parent_instance;
typedef struct {
GtkWidget *box;
GtkWidget *entry;
};
struct _DemoTaggedEntryClass
{
GtkWidgetClass parent_class;
};
} DemoTaggedEntryPrivate;
static void demo_tagged_entry_editable_init (GtkEditableInterface *iface);
G_DEFINE_TYPE_WITH_CODE (DemoTaggedEntry, demo_tagged_entry, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (DemoTaggedEntry)
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, demo_tagged_entry_editable_init))
static void
demo_tagged_entry_init (DemoTaggedEntry *entry)
{
entry->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_parent (entry->box, GTK_WIDGET (entry));
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
entry->entry = gtk_text_new ();
gtk_widget_set_hexpand (entry->entry, TRUE);
gtk_widget_set_vexpand (entry->entry, TRUE);
gtk_widget_set_hexpand (entry->box, FALSE);
gtk_widget_set_vexpand (entry->box, FALSE);
gtk_box_append (GTK_BOX (entry->box), entry->entry);
priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_parent (priv->box, GTK_WIDGET (entry));
priv->entry = gtk_text_new ();
gtk_widget_set_hexpand (priv->entry, TRUE);
gtk_widget_set_vexpand (priv->entry, TRUE);
gtk_widget_set_hexpand (priv->box, FALSE);
gtk_widget_set_vexpand (priv->box, FALSE);
gtk_box_append (GTK_BOX (priv->box), priv->entry);
gtk_editable_init_delegate (GTK_EDITABLE (entry));
}
@@ -62,16 +57,23 @@ static void
demo_tagged_entry_dispose (GObject *object)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (object);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
if (entry->entry)
if (priv->entry)
gtk_editable_finish_delegate (GTK_EDITABLE (entry));
g_clear_pointer (&entry->entry, gtk_widget_unparent);
g_clear_pointer (&entry->box, gtk_widget_unparent);
g_clear_pointer (&priv->entry, gtk_widget_unparent);
g_clear_pointer (&priv->box, gtk_widget_unparent);
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->dispose (object);
}
static void
demo_tagged_entry_finalize (GObject *object)
{
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->finalize (object);
}
static void
demo_tagged_entry_set_property (GObject *object,
guint prop_id,
@@ -96,12 +98,44 @@ demo_tagged_entry_get_property (GObject *object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
demo_tagged_entry_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_measure (priv->box, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
demo_tagged_entry_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_size_allocate (priv->box,
&(GtkAllocation) { 0, 0, width, height },
baseline);
}
static gboolean
demo_tagged_entry_grab_focus (GtkWidget *widget)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
return gtk_widget_grab_focus (entry->entry);
return gtk_widget_grab_focus (priv->entry);
}
static void
@@ -111,14 +145,16 @@ demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = demo_tagged_entry_dispose;
object_class->finalize = demo_tagged_entry_finalize;
object_class->get_property = demo_tagged_entry_get_property;
object_class->set_property = demo_tagged_entry_set_property;
widget_class->measure = demo_tagged_entry_measure;
widget_class->size_allocate = demo_tagged_entry_size_allocate;
widget_class->grab_focus = demo_tagged_entry_grab_focus;
gtk_editable_install_properties (object_class, 1);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ENTRY_ACCESSIBLE);
gtk_widget_class_set_css_name (widget_class, "entry");
}
@@ -126,7 +162,10 @@ demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
static GtkEditable *
demo_tagged_entry_get_delegate (GtkEditable *editable)
{
return GTK_EDITABLE (DEMO_TAGGED_ENTRY (editable)->entry);
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (editable);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
return GTK_EDITABLE (priv->entry);
}
static void
@@ -145,9 +184,11 @@ void
demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
GtkWidget *tag)
{
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
gtk_box_append (GTK_BOX (entry->box), tag);
gtk_box_append (GTK_BOX (priv->box), tag);
}
void
@@ -155,27 +196,30 @@ demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
GtkWidget *tag,
GtkWidget *sibling)
{
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
if (sibling == NULL)
gtk_box_append (GTK_BOX (entry->box), tag);
gtk_box_append (GTK_BOX (priv->box), tag);
else
gtk_box_insert_child_after (GTK_BOX (entry->box), tag, sibling);
gtk_box_insert_child_after (GTK_BOX (priv->box), tag, sibling);
}
void
demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
GtkWidget *tag)
{
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
gtk_box_remove (GTK_BOX (entry->box), tag);
gtk_box_remove (GTK_BOX (priv->box), tag);
}
struct _DemoTaggedEntryTag
{
GtkWidget parent;
GtkWidget *box;
GtkWidget *label;
GtkWidget *button;
@@ -206,11 +250,11 @@ static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, GTK_TYPE_WIDGET)
static void
on_released (GtkGestureClick *gesture,
int n_press,
double x,
double y,
DemoTaggedEntryTag *tag)
on_released (GtkGestureClick *gesture,
int n_press,
double x,
double y,
DemoTaggedEntryTag *tag)
{
g_signal_emit (tag, signals[SIGNAL_CLICKED], 0);
}
@@ -425,7 +469,7 @@ demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
image = gtk_image_new_from_icon_name ("window-close-symbolic");
tag->button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (tag->button), image);
gtk_box_append (GTK_BOX (tag->button), image);
gtk_widget_set_halign (tag->button, GTK_ALIGN_CENTER);
gtk_widget_set_valign (tag->button, GTK_ALIGN_CENTER);
gtk_button_set_has_frame (GTK_BUTTON (tag->button), FALSE);

View File

@@ -25,11 +25,39 @@
G_BEGIN_DECLS
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
G_DECLARE_FINAL_TYPE (DemoTaggedEntry, demo_tagged_entry, DEMO, TAGGED_ENTRY, GtkWidget)
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
#define DEMO_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntry))
#define DEMO_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
#define DEMO_IS_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY))
#define DEMO_IS_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY))
#define DEMO_TAGGED_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
#define DEMO_TYPE_TAGGED_ENTRY_TAG (demo_tagged_entry_tag_get_type ())
G_DECLARE_FINAL_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, DEMO, TAGGED_ENTRY_TAG, GtkWidget)
typedef struct _DemoTaggedEntry DemoTaggedEntry;
typedef struct _DemoTaggedEntryClass DemoTaggedEntryClass;
struct _DemoTaggedEntry
{
GtkWidget parent;
};
struct _DemoTaggedEntryClass
{
GtkWidgetClass parent_class;
};
#define DEMO_TYPE_TAGGED_ENTRY_TAG (demo_tagged_entry_tag_get_type ())
#define DEMO_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
#define DEMO_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
#define DEMO_IS_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG))
#define DEMO_IS_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG))
#define DEMO_TAGGED_ENTRY_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTagClass))
typedef struct _DemoTaggedEntryTag DemoTaggedEntryTag;
typedef struct _DemoTaggedEntryTagClass DemoTaggedEntryTagClass;
GType demo_tagged_entry_get_type (void) G_GNUC_CONST;
GType demo_tagged_entry_tag_get_type (void) G_GNUC_CONST;
GtkWidget * demo_tagged_entry_new (void);

View File

@@ -1,7 +1,6 @@
/* Dialogs
/* Dialogs and Message Boxes
*
* Dialogs are used to pop up transient windows for information
* and user feedback.
* Dialog widgets are used to pop up a transient window for user feedback.
*/
#include <glib/gi18n.h>
@@ -22,9 +21,10 @@ message_dialog_clicked (GtkButton *button,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK_CANCEL,
"Test message");
"This message box has been popped up the following\n"
"number of times:");
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
ngettext ("Has been shown once", "Has been shown %d times", i), i);
"%d", i);
g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
gtk_widget_show (dialog);
i++;
@@ -61,6 +61,8 @@ interactive_dialog_clicked (GtkButton *button,
{
GtkWidget *content_area;
GtkWidget *dialog;
GtkWidget *hbox;
GtkWidget *image;
GtkWidget *table;
GtkWidget *local_entry1;
GtkWidget *local_entry2;
@@ -69,24 +71,26 @@ interactive_dialog_clicked (GtkButton *button,
dialog = gtk_dialog_new_with_buttons ("Interactive Dialog",
GTK_WINDOW (window),
GTK_DIALOG_MODAL| GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_USE_HEADER_BAR,
_("_OK"), GTK_RESPONSE_OK,
_("_Cancel"), GTK_RESPONSE_CANCEL,
GTK_DIALOG_MODAL| GTK_DIALOG_DESTROY_WITH_PARENT,
_("_OK"),
GTK_RESPONSE_OK,
"_Cancel",
GTK_RESPONSE_CANCEL,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
table = gtk_grid_new ();
gtk_widget_set_hexpand (table, TRUE);
gtk_widget_set_vexpand (table, TRUE);
gtk_widget_set_halign (table, GTK_ALIGN_CENTER);
gtk_widget_set_valign (table, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (content_area), table);
gtk_grid_set_row_spacing (GTK_GRID (table), 6);
gtk_grid_set_column_spacing (GTK_GRID (table), 6);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
gtk_box_append (GTK_BOX (content_area), hbox);
image = gtk_image_new_from_icon_name ("dialog-question");
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_box_append (GTK_BOX (hbox), image);
table = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (table), 4);
gtk_grid_set_column_spacing (GTK_GRID (table), 4);
gtk_box_append (GTK_BOX (hbox), table);
label = gtk_label_new_with_mnemonic ("_Entry 1");
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
local_entry1 = gtk_entry_new ();
@@ -119,6 +123,7 @@ interactive_dialog_clicked (GtkButton *button,
GtkWidget *
do_dialog (GtkWidget *do_widget)
{
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *hbox;
@@ -131,16 +136,22 @@ do_dialog (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Dialogs");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_title (GTK_WINDOW (window), "Dialogs and Message Boxes");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
frame = gtk_frame_new ("Dialogs");
gtk_widget_set_margin_start (frame, 8);
gtk_widget_set_margin_end (frame, 8);
gtk_widget_set_margin_top (frame, 8);
gtk_widget_set_margin_bottom (frame, 8);
gtk_window_set_child (GTK_WINDOW (window), frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_widget_set_margin_start (vbox, 8);
gtk_widget_set_margin_end (vbox, 8);
gtk_widget_set_margin_top (vbox, 8);
gtk_widget_set_margin_bottom (vbox, 8);
gtk_window_set_child (GTK_WINDOW (window), vbox);
gtk_frame_set_child (GTK_FRAME (frame), vbox);
/* Standard message dialog */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);

View File

@@ -38,20 +38,15 @@ set_color (CanvasItem *item,
char *str;
GtkStyleContext *context;
GtkCssProvider *provider;
const char *old_class;
str = gdk_rgba_to_string (color);
css = g_strdup_printf ("* { background: %s; }", str);
css = g_strdup_printf ("* { background: %s; padding: 10px; margin: 1px; }", str);
context = gtk_widget_get_style_context (item->label);
provider = g_object_get_data (G_OBJECT (context), "style-provider");
if (provider)
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
if (old_class)
gtk_widget_remove_css_class (item->label, old_class);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, css, -1);
gtk_style_context_add_provider (gtk_widget_get_style_context (item->label), GTK_STYLE_PROVIDER (provider), 800);
@@ -61,27 +56,6 @@ set_color (CanvasItem *item,
g_free (css);
}
static void
set_css (CanvasItem *item,
const char *class)
{
GtkStyleContext *context;
GtkCssProvider *provider;
const char *old_class;
context = gtk_widget_get_style_context (item->label);
provider = g_object_get_data (G_OBJECT (context), "style-provider");
if (provider)
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
if (old_class)
gtk_widget_remove_css_class (item->label, old_class);
g_object_set_data_full (G_OBJECT (item->label), "css-class", g_strdup (class), g_free);
gtk_widget_add_css_class (item->label, class);
}
static gboolean
item_drag_drop (GtkDropTarget *dest,
const GValue *value,
@@ -91,10 +65,7 @@ item_drag_drop (GtkDropTarget *dest,
GtkWidget *label = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
CanvasItem *item = CANVAS_ITEM (gtk_widget_get_parent (gtk_widget_get_parent (label)));
if (G_VALUE_TYPE (value) == GDK_TYPE_RGBA)
set_color (item, g_value_get_boxed (value));
else if (G_VALUE_TYPE (value) == G_TYPE_STRING)
set_css (item, g_value_get_string (value));
set_color (item, g_value_get_boxed (value));
return TRUE;
}
@@ -161,13 +132,11 @@ canvas_item_init (CanvasItem *item)
GdkRGBA rgba;
GtkDropTarget *dest;
GtkGesture *gesture;
GType types[2] = { GDK_TYPE_RGBA, G_TYPE_STRING };
n_items++;
text = g_strdup_printf ("Item %d", n_items);
item->label = gtk_label_new (text);
gtk_widget_add_css_class (item->label, "canvasitem");
g_free (text);
item->fixed = gtk_fixed_new ();
@@ -185,8 +154,7 @@ canvas_item_init (CanvasItem *item)
item->angle = 0;
dest = gtk_drop_target_new (G_TYPE_INVALID, GDK_ACTION_COPY);
gtk_drop_target_set_gtypes (dest, types, G_N_ELEMENTS (types));
dest = gtk_drop_target_new (GDK_TYPE_RGBA, GDK_ACTION_COPY);
g_signal_connect (dest, "drop", G_CALLBACK (item_drag_drop), NULL);
gtk_widget_add_controller (GTK_WIDGET (item->label), GTK_EVENT_CONTROLLER (dest));
@@ -561,42 +529,6 @@ canvas_new (void)
return canvas;
}
static GdkContentProvider *
css_drag_prepare (GtkDragSource *source,
double x,
double y,
GtkWidget *button)
{
const char *class;
GdkPaintable *paintable;
class = (const char *)g_object_get_data (G_OBJECT (button), "css-class");
paintable = gtk_widget_paintable_new (button);
gtk_drag_source_set_icon (source, paintable, 0, 0);
g_object_unref (paintable);
return gdk_content_provider_new_typed (G_TYPE_STRING, class);
}
static GtkWidget *
css_button_new (const char *class)
{
GtkWidget *button;
GtkDragSource *source;
button = gtk_image_new ();
gtk_widget_set_size_request (button, 48, 32);
gtk_widget_add_css_class (button, class);
g_object_set_data (G_OBJECT (button), "css-class", (gpointer)class);
source = gtk_drag_source_new ();
g_signal_connect (source, "prepare", G_CALLBACK (css_drag_prepare), button);
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (source));
return button;
}
static GtkWidget *window = NULL;
GtkWidget *
@@ -616,18 +548,10 @@ do_dnd (GtkWidget *do_widget)
};
int i;
int x, y;
GtkCssProvider *provider;
button = gtk_color_button_new ();
g_object_unref (g_object_ref_sink (button));
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);
g_object_unref (provider);
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
@@ -659,7 +583,7 @@ do_dnd (GtkWidget *do_widget)
y += 100;
}
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_NEVER);
@@ -682,10 +606,6 @@ do_dnd (GtkWidget *do_widget)
NULL);
gtk_box_append (GTK_BOX (box3), swatch);
}
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow1"));
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow2"));
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow3"));
}
if (!gtk_widget_get_visible (window))

View File

@@ -1,37 +0,0 @@
label.canvasitem {
padding: 10px;
margin: 1px;
}
.canvasitem.rainbow1,
image.rainbow1 {
background: linear-gradient(140deg,red,orange,yellow,green,blue,purple);
}
.canvasitem.rainbow2,
image.rainbow2 {
animation: rainbow2 1s infinite linear;
}
@keyframes rainbow2 {
0% { background: linear-gradient(0deg,red,orange,yellow,green,blue,purple); }
25% { background: linear-gradient(90deg,red,orange,yellow,green,blue,purple); }
50% { background: linear-gradient(180deg,red,orange,yellow,green,blue,purple); }
75% { background: linear-gradient(270deg,red,orange,yellow,green,blue,purple); }
100% { background: linear-gradient(360deg,red,orange,yellow,green,blue,purple); }
}
.canvasitem.rainbow3,
image.rainbow3 {
animation: rainbow3 1s infinite linear;
}
@keyframes rainbow3 {
0% { background: linear-gradient(140deg,red,orange,yellow,green,blue,purple); }
16.6% { background: linear-gradient(140deg,purple,red,orange,yellow,green,blue); }
33.2% { background: linear-gradient(140deg,blue,purple,red,orange,yellow,green); }
50% { background: linear-gradient(140deg,green,blue,purple,red,orange,yellow); }
66.6% { background: linear-gradient(140deg,yellow,green,blue,purple,red,orange); }
83.2% { background: linear-gradient(140deg,orange,yellow,green,blue,purple,red); }
100% { background: linear-gradient(140deg,red,orange,yellow,green,blue,purple); }
}

View File

@@ -364,7 +364,7 @@ do_editable_cells (GtkWidget *do_widget)
gtk_box_append (GTK_BOX (vbox),
gtk_label_new ("Shopping list (you can edit the cells!)"));
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,

View File

@@ -1,4 +1,4 @@
/* Entry/Completion
/* Entry/Entry Completion
*
* GtkEntryCompletion provides a mechanism for adding support for
* completion in GtkEntry.
@@ -12,48 +12,22 @@
static GtkTreeModel *
create_completion_model (void)
{
const char *strings[] = {
"GNOME",
"gnominious",
"Gnomonic projection",
"Gnosophy",
"total",
"totally",
"toto",
"tottery",
"totterer",
"Totten trust",
"Tottenham hotspurs",
"totipotent",
"totipotency",
"totemism",
"totem pole",
"Totara",
"totalizer",
"totalizator",
"totalitarianism",
"total parenteral nutrition",
"total eclipse",
"Totipresence",
"Totipalmi",
"zombie",
"aæx",
"aæy",
"aæz",
NULL
};
int i;
GtkListStore *store;
GtkTreeIter iter;
store = gtk_list_store_new (1, G_TYPE_STRING);
for (i = 0; strings[i]; i++)
{
/* Append one word */
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, strings[i], -1);
}
/* Append one word */
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "GNOME", -1);
/* Append another word */
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "total", -1);
/* And another word */
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "totally", -1);
return GTK_TREE_MODEL (store);
}
@@ -74,7 +48,7 @@ do_entry_completion (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Completion");
gtk_window_set_title (GTK_WINDOW (window), "Entry Completion");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
@@ -86,7 +60,7 @@ do_entry_completion (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), vbox);
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), "Try writing <b>total</b> or <b>gnome</b> for example.");
gtk_label_set_markup (GTK_LABEL (label), "Completion demo, try writing <b>total</b> or <b>gnome</b> for example.");
gtk_box_append (GTK_BOX (vbox), label);
/* Create our entry */
@@ -107,9 +81,6 @@ do_entry_completion (GtkWidget *do_widget)
/* Use model column 0 as the text column */
gtk_entry_completion_set_text_column (completion, 0);
gtk_entry_completion_set_inline_completion (completion, TRUE);
gtk_entry_completion_set_inline_selection (completion, TRUE);
}
if (!gtk_widget_get_visible (window))

View File

@@ -1,8 +1,8 @@
/* Entry/Undo and Redo
/* Entry/Entry Undo
*
* GtkEntry can provide basic Undo/Redo support using standard keyboard
* accelerators such as Control+z to undo and Control+Shift+z to redo.
* Additionally, Control+y can be used to redo.
* 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.
*/
@@ -23,7 +23,7 @@ do_entry_undo (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Undo and Redo");
gtk_window_set_title (GTK_WINDOW (window), "Entry Undo");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);

View File

@@ -57,7 +57,7 @@ do_expander (GtkWidget *do_widget)
expander = gtk_expander_new ("Details:");
gtk_widget_set_vexpand (expander, TRUE);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), 100);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),

View File

@@ -130,7 +130,7 @@ create_demo_window (GtkWidget *do_widget)
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), sw);
fixed = gtk_fixed_new ();

View File

@@ -727,7 +727,7 @@ do_flowbox (GtkWidget *do_widget)
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
flowbox = gtk_flow_box_new ();
gtk_widget_set_valign (flowbox, GTK_ALIGN_START);

View File

@@ -108,6 +108,10 @@ gtk_fishbowl_measure (GtkWidget *widget,
{
child = value;
if (!gtk_widget_get_visible (child->widget))
continue;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_widget_measure (child->widget, orientation, -1, &child_min, &child_nat, NULL, NULL);
@@ -144,6 +148,9 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
{
child = value;
if (!gtk_widget_get_visible (child->widget))
continue;
gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
child_allocation.x = round (child->x * (width - child_requisition.width));
child_allocation.y = round (child->y * (height - child_requisition.height));
@@ -190,11 +197,17 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
GtkWidget *widget)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkWidget *widget_bowl = GTK_WIDGET (fishbowl);
if (g_hash_table_remove (priv->children, widget))
{
gboolean was_visible = gtk_widget_get_visible (widget);
gtk_widget_unparent (widget);
if (was_visible && gtk_widget_get_visible (widget_bowl))
gtk_widget_queue_resize (widget_bowl);
priv->count--;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
}

View File

@@ -260,7 +260,7 @@ do_hypertext (GtkWidget *do_widget)
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_enable_undo (buffer, TRUE);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);

View File

@@ -276,7 +276,7 @@ do_iconview (GtkWidget *do_widget)
gtk_box_append (GTK_BOX (tool_bar), home_button);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,

View File

@@ -269,7 +269,7 @@ do_list_store (GtkWidget *do_widget)
label = gtk_label_new ("This is the bug list (note: not based on real data, it would be nice to have a nice ODBC interface to bugzilla or so, though).");
gtk_box_append (GTK_BOX (vbox), label);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_NEVER,

View File

@@ -358,7 +358,7 @@ do_listbox (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), vbox);
label = gtk_label_new ("Messages from GTK and friends");
gtk_box_append (GTK_BOX (vbox), label);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand (scrolled, TRUE);
gtk_box_append (GTK_BOX (vbox), scrolled);

View File

@@ -188,7 +188,7 @@ do_listview_applauncher (GtkWidget *do_widget)
* because otherwise they might get too large or they might not
* be scrollable.
*/
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), sw);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), list);
}

View File

@@ -249,7 +249,7 @@ gtk_clock_tick (gpointer unused)
{
GtkClock *clock = l->data;
/* We will now return a different value for the time property,
/* We will now return a different value for the time porperty,
* so notify about that.
*/
g_object_notify_by_pspec (G_OBJECT (clock), properties[PROP_TIME]);
@@ -323,16 +323,16 @@ gtk_clock_init (GtkClock *self)
static GtkClock *
gtk_clock_new (const char *location,
GTimeZone *_tz)
GTimeZone *_timezone)
{
GtkClock *result;
result = g_object_new (GTK_TYPE_CLOCK,
"location", location,
"timezone", _tz,
"timezone", _timezone,
NULL);
g_clear_pointer (&_tz, g_time_zone_unref);
g_clear_pointer (&_timezone, g_time_zone_unref);
return result;
}
@@ -474,7 +474,7 @@ do_listview_clocks (GtkWidget *do_widget)
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
/* List widgets go into a scrolled window. Always. */
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), sw);
/* Create the factory that creates the listitems. Because we

View File

@@ -1,17 +1,12 @@
/* Lists/Colors
*
* This demo displays a grid of colors.
* This demo displays a list of named colors.
*
* It is using a GtkGridView, and shows how to display
* and sort the data in various ways. The controls for
* this are implemented using GtkDropDown.
*
* The dataset used here has up to 16777216 items.
*
* Note that this demo also functions as a performance
* test for some of the list model machinery, and the
* biggest sizes here can lock up the application for
* extended times when used with sorting.
* The dataset used here has 9283 items.
*/
#include <gtk/gtk.h>
@@ -28,8 +23,9 @@ struct _GtkColor
GObject parent_instance;
char *name;
GdkRGBA color;
GdkRGBA *color;
int h, s, v;
gboolean selected;
};
enum {
@@ -42,8 +38,9 @@ enum {
PROP_HUE,
PROP_SATURATION,
PROP_VALUE,
PROP_SELECTED,
N_COLOR_PROPS
N_PROPS
};
static void
@@ -54,7 +51,7 @@ gtk_color_snapshot (GdkPaintable *paintable,
{
GtkColor *self = GTK_COLOR (paintable);
gtk_snapshot_append_color (snapshot, &self->color, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_append_color (snapshot, self->color, &GRAPHENE_RECT_INIT (0, 0, width, height));
}
static int
@@ -85,82 +82,7 @@ G_DEFINE_TYPE_WITH_CODE (GtkColor, gtk_color, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_color_paintable_init))
static GParamSpec *color_properties[N_COLOR_PROPS] = { NULL, };
static void
rgb_to_hsv (GdkRGBA *rgba,
gdouble *h_out,
gdouble *s_out,
gdouble *v_out)
{
gdouble red, green, blue;
gdouble h, s, v;
gdouble min, max;
gdouble delta;
red = rgba->red;
green = rgba->green;
blue = rgba->blue;
h = 0.0;
if (red > green)
{
if (red > blue)
max = red;
else
max = blue;
if (green < blue)
min = green;
else
min = blue;
}
else
{
if (green > blue)
max = green;
else
max = blue;
if (red < blue)
min = red;
else
min = blue;
}
v = max;
if (max != 0.0)
s = (max - min) / max;
else
s = 0.0;
if (s == 0.0)
h = 0.0;
else
{
delta = max - min;
if (red == max)
h = (green - blue) / delta;
else if (green == max)
h = 2 + (blue - red) / delta;
else if (blue == max)
h = 4 + (red - green) / delta;
h /= 6.0;
if (h < 0.0)
h += 1.0;
else if (h > 1.0)
h -= 1.0;
}
*h_out = h;
*s_out = s;
*v_out = v;
}
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gtk_color_get_property (GObject *object,
@@ -177,19 +99,19 @@ gtk_color_get_property (GObject *object,
break;
case PROP_COLOR:
g_value_set_boxed (value, &self->color);
g_value_set_boxed (value, self->color);
break;
case PROP_RED:
g_value_set_float (value, self->color.red);
g_value_set_float (value, self->color->red);
break;
case PROP_GREEN:
g_value_set_float (value, self->color.green);
g_value_set_float (value, self->color->green);
break;
case PROP_BLUE:
g_value_set_float (value, self->color.blue);
g_value_set_float (value, self->color->blue);
break;
case PROP_HUE:
@@ -204,6 +126,10 @@ gtk_color_get_property (GObject *object,
g_value_set_int (value, self->v);
break;
case PROP_SELECTED:
g_value_set_boolean (value, self->selected);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -217,7 +143,6 @@ gtk_color_set_property (GObject *object,
GParamSpec *pspec)
{
GtkColor *self = GTK_COLOR (object);
double h, s, v;
switch (property_id)
{
@@ -226,11 +151,23 @@ gtk_color_set_property (GObject *object,
break;
case PROP_COLOR:
self->color = *(GdkRGBA *) g_value_dup_boxed (value);
rgb_to_hsv (&self->color, &h, &s, &v);
self->h = round (360 * h);
self->s = round (100 * s);
self->v = round (100 * v);
self->color = g_value_dup_boxed (value);
break;
case PROP_HUE:
self->h = g_value_get_int (value);
break;
case PROP_SATURATION:
self->s = g_value_get_int (value);
break;
case PROP_VALUE:
self->v = g_value_get_int (value);
break;
case PROP_SELECTED:
self->selected = g_value_get_boolean (value);
break;
default:
@@ -245,6 +182,7 @@ gtk_color_finalize (GObject *object)
GtkColor *self = GTK_COLOR (object);
g_free (self->name);
g_clear_pointer (&self->color, gdk_rgba_free);
G_OBJECT_CLASS (gtk_color_parent_class)->finalize (object);
}
@@ -258,24 +196,26 @@ gtk_color_class_init (GtkColorClass *klass)
gobject_class->set_property = gtk_color_set_property;
gobject_class->finalize = gtk_color_finalize;
color_properties[PROP_NAME] =
properties[PROP_NAME] =
g_param_spec_string ("name", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
color_properties[PROP_COLOR] =
properties[PROP_COLOR] =
g_param_spec_boxed ("color", NULL, NULL, GDK_TYPE_RGBA, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
color_properties[PROP_RED] =
properties[PROP_RED] =
g_param_spec_float ("red", NULL, NULL, 0, 1, 0, G_PARAM_READABLE);
color_properties[PROP_GREEN] =
properties[PROP_GREEN] =
g_param_spec_float ("green", NULL, NULL, 0, 1, 0, G_PARAM_READABLE);
color_properties[PROP_BLUE] =
properties[PROP_BLUE] =
g_param_spec_float ("blue", NULL, NULL, 0, 1, 0, G_PARAM_READABLE);
color_properties[PROP_HUE] =
g_param_spec_int ("hue", NULL, NULL, 0, 360, 0, G_PARAM_READABLE);
color_properties[PROP_SATURATION] =
g_param_spec_int ("saturation", NULL, NULL, 0, 100, 0, G_PARAM_READABLE);
color_properties[PROP_VALUE] =
g_param_spec_int ("value", NULL, NULL, 0, 100, 0, G_PARAM_READABLE);
properties[PROP_HUE] =
g_param_spec_int ("hue", NULL, NULL, 0, 360, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_SATURATION] =
g_param_spec_int ("saturation", NULL, NULL, 0, 100, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_VALUE] =
g_param_spec_int ("value", NULL, NULL, 0, 100, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_SELECTED] =
g_param_spec_boolean ("selected", NULL, NULL, FALSE, G_PARAM_READWRITE);
g_object_class_install_properties (gobject_class, N_COLOR_PROPS, color_properties);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
@@ -285,7 +225,8 @@ gtk_color_init (GtkColor *self)
static GtkColor *
gtk_color_new (const char *name,
float r, float g, float b)
float r, float g, float b,
int h, int s, int v)
{
GtkColor *result;
GdkRGBA color = { r, g, b, 1.0 };
@@ -293,206 +234,24 @@ gtk_color_new (const char *name,
result = g_object_new (GTK_TYPE_COLOR,
"name", name,
"color", &color,
"hue", h,
"saturation", s,
"value", v,
NULL);
return result;
}
#define N_COLORS (256 * 256 * 256)
#define GTK_TYPE_COLOR_LIST (gtk_color_list_get_type ())
G_DECLARE_FINAL_TYPE (GtkColorList, gtk_color_list, GTK, COLOR_LIST, GObject)
enum {
LIST_PROP_0,
LIST_PROP_SIZE,
N_LIST_PROPS
};
typedef struct _GtkColorList GtkColorList;
struct _GtkColorList
{
GObject parent_instance;
GtkColor **colors; /* Always N_COLORS */
guint size; /* How many colors we allow */
};
static GType
gtk_color_list_get_item_type (GListModel *list)
{
return GTK_TYPE_COLOR;
}
static guint
gtk_color_list_get_n_items (GListModel *list)
{
GtkColorList *self = GTK_COLOR_LIST (list);
return self->size;
}
static guint
position_to_color (guint position)
{
static guint map[] = {
0xFF0000, 0x00FF00, 0x0000FF,
0x7F0000, 0x007F00, 0x00007F,
0x3F0000, 0x003F00, 0x00003F,
0x1F0000, 0x001F00, 0x00001F,
0x0F0000, 0x000F00, 0x00000F,
0x070000, 0x000700, 0x000007,
0x030000, 0x000300, 0x000003,
0x010000, 0x000100, 0x000001
};
guint result, i;
result = 0;
for (i = 0; i < G_N_ELEMENTS (map); i++)
{
if (position & (1 << i))
result ^= map[i];
}
return result;
}
static gpointer
gtk_color_list_get_item (GListModel *list,
guint position)
{
GtkColorList *self = GTK_COLOR_LIST (list);
if (position >= self->size)
return NULL;
position = position_to_color (position);
if (self->colors[position] == NULL)
{
guint red, green, blue;
red = (position >> 16) & 0xFF;
green = (position >> 8) & 0xFF;
blue = position & 0xFF;
self->colors[position] = gtk_color_new ("", red / 255., green / 255., blue / 255.);
}
return g_object_ref (self->colors[position]);
}
static void
gtk_color_list_model_init (GListModelInterface *iface)
{
iface->get_item_type = gtk_color_list_get_item_type;
iface->get_n_items = gtk_color_list_get_n_items;
iface->get_item = gtk_color_list_get_item;
}
G_DEFINE_TYPE_WITH_CODE (GtkColorList, gtk_color_list, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
gtk_color_list_model_init))
static GParamSpec *list_properties[N_LIST_PROPS] = { NULL, };
static void
gtk_color_list_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkColorList *self = GTK_COLOR_LIST (object);
switch (property_id)
{
case LIST_PROP_SIZE:
g_value_set_uint (value, self->size);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_color_list_set_size (GtkColorList *self,
guint size)
{
guint old_size = self->size;
self->size = size;
if (self->size > old_size)
g_list_model_items_changed (G_LIST_MODEL (self), old_size, 0, self->size - old_size);
else if (old_size > self->size)
g_list_model_items_changed (G_LIST_MODEL (self), self->size, old_size - self->size, 0);
g_object_notify_by_pspec (G_OBJECT (self), list_properties[LIST_PROP_SIZE]);
}
static void
gtk_color_list_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkColorList *self = GTK_COLOR_LIST (object);
switch (property_id)
{
case LIST_PROP_SIZE:
gtk_color_list_set_size (self, g_value_get_uint (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_color_list_dispose (GObject *object)
{
GtkColorList *self = GTK_COLOR_LIST (object);
guint i;
for (i = 0; i < N_COLORS; i++)
{
g_clear_object (&self->colors[i]);
}
g_free (self->colors);
G_OBJECT_CLASS (gtk_color_parent_class)->finalize (object);
}
static void
gtk_color_list_class_init (GtkColorListClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gtk_color_list_get_property;
gobject_class->set_property = gtk_color_list_set_property;
gobject_class->dispose = gtk_color_list_dispose;
list_properties[LIST_PROP_SIZE] =
g_param_spec_uint ("size", NULL, NULL, 0, N_COLORS, 0, G_PARAM_READWRITE);
g_object_class_install_properties (gobject_class, N_LIST_PROPS, list_properties);
}
static void
gtk_color_list_init (GtkColorList *self)
static GListModel *
create_colors_model (void)
{
GListStore *result;
GtkColor *color;
GBytes *data;
char **lines;
guint i;
self->colors = g_new0 (GtkColor *, N_COLORS);
result = g_list_store_new (GTK_TYPE_COLOR);
data = g_resources_lookup_data ("/listview_colors/color.names.txt", 0, NULL);
lines = g_strsplit (g_bytes_get_data (data, NULL), "\n", 0);
@@ -501,7 +260,7 @@ gtk_color_list_init (GtkColorList *self)
const char *name;
char **fields;
int red, green, blue;
guint pos;
int h, s, v;
if (lines[i][0] == '#' || lines[i][0] == '\0')
continue;
@@ -511,24 +270,21 @@ gtk_color_list_init (GtkColorList *self)
red = atoi (fields[3]);
green = atoi (fields[4]);
blue = atoi (fields[5]);
h = atoi (fields[9]);
s = atoi (fields[10]);
v = atoi (fields[11]);
pos = ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | blue;
if (self->colors[pos] == NULL)
self->colors[pos] = gtk_color_new (name, red / 255., green / 255., blue / 255.);
color = gtk_color_new (name, red / 255., green / 255., blue / 255., h, s, v);
g_list_store_append (result, color);
g_object_unref (color);
g_strfreev (fields);
}
g_strfreev (lines);
g_bytes_unref (data);
}
static GListModel *
gtk_color_list_new (guint size)
{
return g_object_new (GTK_TYPE_COLOR_LIST,
"size", size,
NULL);
return G_LIST_MODEL (result);
}
static char *
@@ -539,9 +295,9 @@ get_rgb_markup (gpointer this,
return NULL;
return g_strdup_printf ("<b>R:</b> %d <b>G:</b> %d <b>B:</b> %d",
(int)(color->color.red * 255),
(int)(color->color.green * 255),
(int)(color->color.blue * 255));
(int)(color->color->red * 255),
(int)(color->color->green * 255),
(int)(color->color->blue * 255));
}
static char *
@@ -640,6 +396,29 @@ get_title (gpointer item)
return g_strdup ((char *)g_object_get_data (G_OBJECT (item), "title"));
}
static gboolean
set_item (GBinding *binding,
const GValue *from,
GValue *to,
gpointer data)
{
GObject *source = g_binding_get_source (binding);
GListModel *model;
guint selected;
gpointer item;
selected = g_value_get_uint (from);
model = gtk_drop_down_get_model (GTK_DROP_DOWN (source));
item = g_list_model_get_item (model, selected);
g_value_set_object (to, item);
g_clear_object (&item);
return TRUE;
}
GtkWidget *
create_color_grid (void)
{
@@ -659,9 +438,8 @@ create_color_grid (void)
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (gridview), 24);
gtk_grid_view_set_enable_rubberband (GTK_GRID_VIEW (gridview), TRUE);
model = G_LIST_MODEL (gtk_sort_list_model_new (gtk_color_list_new (0), NULL));
selection = G_LIST_MODEL (gtk_multi_selection_new (model));
model = G_LIST_MODEL (gtk_sort_list_model_new (create_colors_model (), NULL));
selection = G_LIST_MODEL (gtk_property_selection_new (model, "selected"));
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), selection);
g_object_unref (selection);
g_object_unref (model);
@@ -669,114 +447,6 @@ create_color_grid (void)
return gridview;
}
static gboolean
add_colors (GtkWidget *widget,
GdkFrameClock *clock,
gpointer data)
{
GtkColorList *colors = data;
guint limit;
limit = GPOINTER_TO_UINT (g_object_get_data (data, "limit"));
gtk_color_list_set_size (colors, MIN (limit, colors->size + MAX (1, limit / 4096)));
if (colors->size >= limit)
return G_SOURCE_REMOVE;
else
return G_SOURCE_CONTINUE;
}
static void
refill (GtkWidget *button,
GtkColorList *colors)
{
gtk_color_list_set_size (colors, 0);
gtk_widget_add_tick_callback (button, add_colors, g_object_ref (colors), g_object_unref);
}
static void
limit_changed_cb (GtkDropDown *dropdown,
GParamSpec *pspec,
GtkColorList *colors)
{
guint new_limit, old_limit;
old_limit = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (colors), "limit"));
new_limit = 1 << (3 * (gtk_drop_down_get_selected (dropdown) + 1));
g_object_set_data (G_OBJECT (colors), "limit", GUINT_TO_POINTER (new_limit));
if (old_limit == colors->size)
gtk_color_list_set_size (colors, new_limit);
}
static void
limit_changed_cb2 (GtkDropDown *dropdown,
GParamSpec *pspec,
GtkLabel *label)
{
char *string;
int len;
guint limit;
limit = 1 << (3 * (gtk_drop_down_get_selected (dropdown) + 1));
string = g_strdup_printf ("%'u", limit);
len = g_utf8_strlen (string, -1);
g_free (string);
gtk_label_set_width_chars (label, len + 2); /* for " /" */
}
static void
items_changed_cb (GListModel *model,
guint position,
guint removed,
guint added,
GtkWidget *label)
{
guint n = g_list_model_get_n_items (model);
char *text;
text = g_strdup_printf ("%'u /", n);
gtk_label_set_label (GTK_LABEL (label), text);
g_free (text);
}
static void
setup_number_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *label;
PangoAttrList *attrs;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 1);
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
gtk_list_item_set_child (item, label);
}
static void
bind_number_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *label;
guint limit;
char *string;
label = gtk_list_item_get_child (item);
limit = 1 << (3 * (gtk_list_item_get_position (item) + 1));
string = g_strdup_printf ("%'u", limit);
gtk_label_set_label (GTK_LABEL (label), string);
g_free (string);
}
static GtkWidget *window = NULL;
GtkWidget *
@@ -788,15 +458,11 @@ do_listview_colors (GtkWidget *do_widget)
GtkListItemFactory *factory;
GListStore *factories;
GListModel *model;
GtkSorter *sorter;
GtkSorter *multi_sorter;
GListStore *sorters;
GtkExpression *expression;
GtkWidget *button;
GtkWidget *label;
PangoAttrList *attrs;
char *string;
guint len;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Colors");
@@ -809,7 +475,7 @@ do_listview_colors (GtkWidget *do_widget)
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), sw);
gridview = create_color_grid ();
@@ -817,54 +483,8 @@ do_listview_colors (GtkWidget *do_widget)
model = gtk_grid_view_get_model (GTK_GRID_VIEW (gridview));
g_object_get (model, "model", &model, NULL);
button = gtk_button_new_with_mnemonic ("_Refill");
g_signal_connect (button, "clicked",
G_CALLBACK (refill),
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
label = gtk_label_new ("0 /");
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
string = g_strdup_printf ("%'u", 4096);
len = g_utf8_strlen (string, -1);
g_free (string);
gtk_label_set_width_chars (GTK_LABEL (label), len + 2);
gtk_label_set_xalign (GTK_LABEL (label), 1);
g_signal_connect (gtk_grid_view_get_model (GTK_GRID_VIEW (gridview)),
"items-changed", G_CALLBACK (items_changed_cb), label);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), label);
dropdown = gtk_drop_down_new ();
gtk_drop_down_set_from_strings (GTK_DROP_DOWN (dropdown), (const char *[]) { "8", "64", "512", "4096", "32768", "262144", "2097152", "16777216", NULL });
g_signal_connect (dropdown, "notify::selected",
G_CALLBACK (limit_changed_cb),
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
g_signal_connect (dropdown, "notify::selected",
G_CALLBACK (limit_changed_cb2),
label);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_number_item), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_number_item), NULL);
gtk_drop_down_set_factory (GTK_DROP_DOWN (dropdown), factory);
g_object_unref (factory);
gtk_drop_down_set_selected (GTK_DROP_DOWN (dropdown), 3); /* 4096 */
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), dropdown);
sorters = g_list_store_new (GTK_TYPE_SORTER);
/* An empty multisorter doesn't do any sorting and the sortmodel is
* smart enough to know that.
*/
sorter = gtk_multi_sorter_new ();
set_title (sorter, "Unsorted");
g_list_store_append (sorters, sorter);
g_object_unref (sorter);
sorter = gtk_string_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "name"));
set_title (sorter, "Name");
g_list_store_append (sorters, sorter);
@@ -935,7 +555,11 @@ do_listview_colors (GtkWidget *do_widget)
gtk_drop_down_set_model (GTK_DROP_DOWN (dropdown), G_LIST_MODEL (sorters));
g_object_unref (sorters);
g_object_bind_property (dropdown, "selected-item", model, "sorter", G_BINDING_SYNC_CREATE);
g_object_bind_property_full (dropdown, "selected",
model, "sorter",
G_BINDING_SYNC_CREATE,
set_item, NULL,
NULL, NULL);
factories = g_list_store_new (GTK_TYPE_LIST_ITEM_FACTORY);
@@ -966,7 +590,11 @@ do_listview_colors (GtkWidget *do_widget)
gtk_drop_down_set_model (GTK_DROP_DOWN (dropdown), G_LIST_MODEL (factories));
g_object_unref (factories);
g_object_bind_property (dropdown, "selected-item", gridview, "factory", G_BINDING_SYNC_CREATE);
g_object_bind_property_full (dropdown, "selected",
gridview, "factory",
G_BINDING_SYNC_CREATE,
set_item, NULL,
NULL, NULL);
g_object_unref (model);
}

View File

@@ -143,9 +143,8 @@ settings_key_new (GSettings *settings,
}
static void
item_value_changed (GtkEditableLabel *label,
GParamSpec *pspec,
GtkListItem *item)
item_value_changed (GtkListItem *item,
GtkEntry *entry)
{
SettingsKey *self;
const char *text;
@@ -153,9 +152,8 @@ item_value_changed (GtkEditableLabel *label,
GVariant *variant;
GError *error = NULL;
const char *name;
char *value;
text = gtk_editable_get_text (GTK_EDITABLE (label));
text = gtk_editable_get_text (GTK_EDITABLE (entry));
g_object_get (item, "item", &self, NULL);
g_object_unref (self);
@@ -168,25 +166,17 @@ item_value_changed (GtkEditableLabel *label,
{
g_warning ("%s", error->message);
g_clear_error (&error);
goto revert;
return;
}
if (!g_settings_schema_key_range_check (self->key, variant))
{
g_warning ("Not a valid value for %s", name);
goto revert;
return;
}
g_settings_set_value (self->settings, name, variant);
g_variant_unref (variant);
return;
revert:
gtk_widget_error_bell (GTK_WIDGET (label));
g_object_get (self, "value", &value, NULL);
gtk_editable_set_text (GTK_EDITABLE (label), value);
g_free (value);
}
static int

View File

@@ -113,13 +113,14 @@
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkEditableLabel">
<object class="GtkEntry">
<signal name="activate" handler="item_value_changed" object="GtkListItem" swapped="yes"/>
<property name="xalign">0</property>
<binding name="text">
<lookup name="value" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<signal name="notify::label" handler="item_value_changed"/>
</object>
</property>
</template>

View File

@@ -70,6 +70,7 @@ gtk_weather_info_new (GDateTime *timestamp,
{
result->temperature = copy_from->temperature;
result->weather_type = copy_from->weather_type;
g_object_unref (copy_from);
}
return result;
@@ -77,13 +78,13 @@ gtk_weather_info_new (GDateTime *timestamp,
static GDateTime *
parse_timestamp (const char *string,
GTimeZone *_tz)
GTimeZone *_timezone)
{
char *with_seconds;
GDateTime *result;
with_seconds = g_strconcat (string, ":00", NULL);
result = g_date_time_new_from_iso8601 (with_seconds, _tz);
result = g_date_time_new_from_iso8601 (with_seconds, _timezone);
g_free (with_seconds);
return result;
@@ -160,7 +161,6 @@ create_weather_model (void)
timestamp = g_date_time_new (utc, 2011, 1, 1, 0, 0, 0);
info = gtk_weather_info_new (timestamp, NULL);
g_list_store_append (store, info);
g_object_unref (info);
for (i = 0; lines[i] != NULL && *lines[i]; i++)
{
@@ -176,7 +176,6 @@ create_weather_model (void)
timestamp = new_timestamp;
info = gtk_weather_info_new (timestamp, info);
g_list_store_append (store, info);
g_object_unref (info);
}
info->temperature = parse_temperature (fields[1], info->temperature);
@@ -185,7 +184,6 @@ create_weather_model (void)
g_strfreev (fields);
}
g_date_time_unref (timestamp);
g_strfreev (lines);
g_bytes_unref (data);
g_time_zone_unref (utc);
@@ -313,7 +311,7 @@ do_listview_weather (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Weather");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), sw);
listview = create_weather_view ();
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);

View File

@@ -1,241 +0,0 @@
/* Lists/Words
*
* This demo shows filtering a long list - of words.
*
* You should have the file `/usr/share/dict/words` installed for
* this demo to work.
*/
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
static GtkWidget *progress;
const char *factory_text =
"<?xml version='1.0' encoding='UTF-8'?>\n"
"<interface>\n"
" <template class='GtkListItem'>\n"
" <property name='child'>\n"
" <object class='GtkLabel'>\n"
" <property name='ellipsize'>end</property>\n"
" <property name='xalign'>0</property>\n"
" <binding name='label'>\n"
" <lookup name='string' type='GtkStringObject'>\n"
" <lookup name='item'>GtkListItem</lookup>\n"
" </lookup>\n"
" </binding>\n"
" </object>\n"
" </property>\n"
" </template>\n"
"</interface>\n";
static void
update_title_cb (GtkFilterListModel *model)
{
guint total;
char *title;
guint pending;
total = g_list_model_get_n_items (gtk_filter_list_model_get_model (model));
pending = gtk_filter_list_model_get_pending (model);
title = g_strdup_printf ("%u lines", g_list_model_get_n_items (G_LIST_MODEL (model)));
gtk_widget_set_visible (progress, pending != 0);
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), (total - pending) / (double) total);
gtk_window_set_title (GTK_WINDOW (window), title);
g_free (title);
}
static void
read_lines_cb (GObject *object,
GAsyncResult *result,
gpointer data)
{
GBufferedInputStream *stream = G_BUFFERED_INPUT_STREAM (object);
GtkStringList *stringlist = data;
GError *error = NULL;
gsize size;
GPtrArray *lines;
gssize n_filled;
const char *buffer, *newline;
n_filled = g_buffered_input_stream_fill_finish (stream, result, &error);
if (n_filled < 0)
{
g_print ("Could not read data: %s\n", error->message);
g_clear_error (&error);
return;
}
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
if (n_filled == 0)
{
if (size)
gtk_string_list_take (stringlist, g_utf8_make_valid (buffer, size));
return;
}
lines = NULL;
while ((newline = memchr (buffer, '\n', size)))
{
if (newline > buffer)
{
if (lines == NULL)
lines = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (lines, g_utf8_make_valid (buffer, newline - buffer));
}
if (g_input_stream_skip (G_INPUT_STREAM (stream), newline - buffer + 1, NULL, &error) < 0)
{
g_clear_error (&error);
break;
}
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
}
if (lines == NULL)
{
g_buffered_input_stream_set_buffer_size (stream, g_buffered_input_stream_get_buffer_size (stream) + 4096);
}
else
{
g_ptr_array_add (lines, NULL);
gtk_string_list_splice (stringlist, g_list_model_get_n_items (G_LIST_MODEL (stringlist)), 0, (const char **) lines->pdata);
g_ptr_array_free (lines, TRUE);
}
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
}
static void
file_is_open_cb (GObject *file,
GAsyncResult *result,
gpointer data)
{
GError *error = NULL;
GFileInputStream *file_stream;
GBufferedInputStream *stream;
file_stream = g_file_read_finish (G_FILE (file), result, &error);
if (file_stream == NULL)
{
g_print ("Could not open file: %s\n", error->message);
g_error_free (error);
return;
}
stream = G_BUFFERED_INPUT_STREAM (g_buffered_input_stream_new (G_INPUT_STREAM (file_stream)));
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
g_object_unref (stream);
}
static void
load_file (GtkStringList *list,
GFile *file)
{
gtk_string_list_splice (list, 0, g_list_model_get_n_items (G_LIST_MODEL (list)), NULL);
g_file_read_async (file, G_PRIORITY_HIGH_IDLE, NULL, file_is_open_cb, list);
}
static void
file_selected_cb (GtkWidget *button,
GtkStringList *stringlist)
{
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button));
if (file)
{
load_file (stringlist, file);
g_object_unref (file);
}
}
GtkWidget *
do_listview_words (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *header, *listview, *sw, *vbox, *search_entry, *open_button, *overlay;
GtkFilterListModel *filter_model;
GtkNoSelection *selection;
GtkStringList *stringlist;
GtkFilter *filter;
GtkExpression *expression;
GFile *file;
file = g_file_new_for_path ("/usr/share/dict/words");
if (g_file_query_exists (file, NULL))
{
stringlist = gtk_string_list_new (NULL);
load_file (stringlist, file);
}
else
{
char **words;
words = g_strsplit ("lorem ipsum dolor sit amet consectetur adipisci elit sed eiusmod tempor incidunt labore et dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat", " ", -1);
stringlist = gtk_string_list_new ((const char **) words);
g_strfreev (words);
}
filter = gtk_string_filter_new ();
expression = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
gtk_expression_unref (expression);
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (stringlist), filter);
gtk_filter_list_model_set_incremental (filter_model, TRUE);
window = gtk_window_new ();
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
open_button = gtk_file_chooser_button_new ("_Open", GTK_FILE_CHOOSER_ACTION_OPEN);
g_signal_connect (open_button, "file-set", G_CALLBACK (file_selected_cb), stringlist);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), open_button);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), vbox);
search_entry = gtk_search_entry_new ();
g_object_bind_property (search_entry, "text", filter, "search", 0);
gtk_box_append (GTK_BOX (vbox), search_entry);
overlay = gtk_overlay_new ();
gtk_box_append (GTK_BOX (vbox), overlay);
progress = gtk_progress_bar_new ();
gtk_widget_set_halign (progress, GTK_ALIGN_FILL);
gtk_widget_set_valign (progress, GTK_ALIGN_START);
gtk_widget_set_hexpand (progress, TRUE);
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), progress);
sw = gtk_scrolled_window_new ();
gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
listview = gtk_list_view_new_with_factory (
gtk_builder_list_item_factory_new_from_bytes (NULL,
g_bytes_new_static (factory_text, strlen (factory_text))));
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
selection = gtk_no_selection_new (G_LIST_MODEL (filter_model));
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
g_object_unref (selection);
g_signal_connect (filter_model, "items-changed", G_CALLBACK (update_title_cb), progress);
g_signal_connect (filter_model, "notify::pending", G_CALLBACK (update_title_cb), progress);
update_title_cb (filter_model);
g_object_unref (filter_model);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -133,7 +133,7 @@ gtk_demo_run (GtkDemo *self,
}
return TRUE;
}
static void
activate_about (GSimpleAction *action,
GVariant *parameter,
@@ -602,7 +602,7 @@ display_image (const char *resource)
image = gtk_picture_new_for_resource (resource);
gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
gtk_widget_set_valign (image, GTK_ALIGN_CENTER);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), image);
return sw;
@@ -642,7 +642,7 @@ display_text (const char *resource)
g_bytes_unref (bytes);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
@@ -1035,6 +1035,8 @@ activate (GApplication *app)
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
g_signal_connect (listview, "activate", G_CALLBACK (activate_cb), window);
load_file (gtk_demos[0].name, gtk_demos[0].filename);
listmodel = create_demo_model ();
treemodel = gtk_tree_list_model_new (FALSE,
G_LIST_MODEL (listmodel),
@@ -1044,9 +1046,8 @@ activate (GApplication *app)
NULL);
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
g_signal_connect (selection, "notify::selected-item", G_CALLBACK (selection_cb), NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
selection_cb (selection, NULL, NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview),
G_LIST_MODEL (selection));
g_object_unref (builder);
}
@@ -1155,7 +1156,7 @@ out:
static void
print_version (void)
{
g_print ("gtk4-demo %d.%d.%d\n",
g_print ("gtk3-demo %d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
@@ -1197,6 +1198,16 @@ main (int argc, char **argv)
};
int i;
/* Most code in gtk-demo is intended to be exemplary, but not
* these few lines, which are just a hack so gtk-demo will work
* in the GTK tree without installing it.
*/
if (g_file_test ("../../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
{
g_setenv ("GTK_IM_MODULE_FILE", "../../modules/input/immodules.cache", TRUE);
}
/* -- End of hack -- */
app = gtk_application_new ("org.gtk.Demo4", G_APPLICATION_NON_UNIQUE|G_APPLICATION_HANDLES_COMMAND_LINE);
g_action_map_add_action_entries (G_ACTION_MAP (app),

View File

@@ -16,6 +16,15 @@
</item>
</section>
</menu>
<object class="GtkTreeStore" id="treestore">
<columns>
<column type="gchararray"/>
<column type="gchararray"/>
<column type="gchararray"/>
<column type="gpointer"/>
<column type="gint"/>
</columns>
</object>
<object class="GtkApplicationWindow" id="window">
<style>
<class name="devel"/>

View File

@@ -81,7 +81,7 @@ do_markup (GtkWidget *do_widget)
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 10);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 10);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
@@ -94,7 +94,7 @@ do_markup (GtkWidget *do_widget)
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view2), 10);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view2), 10);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);

View File

@@ -49,7 +49,6 @@ demos = files([
'listview_minesweeper.c',
'listview_settings.c',
'listview_weather.c',
'listview_words.c',
'markup.c',
'modelbutton.c',
'overlay.c',

View File

@@ -259,7 +259,7 @@
259|GTK+ and friends|GTKtoolkit|#java bindings version 4.0.16 released: http://article.gmane.org/gmane.comp.gnome.bindings.java/1796 #gtk|1276885917|0||0|0
260|GTK+ and friends|GTKtoolkit|RT @cwiiis: MxIconTheme and MxIcon respect system's icon theme (and changes) now in #mx master :) Made possible by @thosw's XSettings work|1276883019|0||0|0
261|GTK+ and friends|GTKtoolkit|#javascript mailing list just created. Discuss its usage in GObject libraries: GTK+, Glib ... http://ur1.ca/08lwz by @jwendell #gtk|1276842639|0||0|0
262|GTK+ and friends|GTKtoolkit|Note for Win32 users: XP theming is back in 2.90.3 . Please test. #gtk|1276829697|0||0|0
262|GTK+ and friends|GTKtoolkit|Note fot Win32 users: XP theming is back in 2.90.3 . Please test. #gtk|1276829697|0||0|0
263|GTK+ and friends|GTKtoolkit|GTK+ 2.90.3 (unstable) released: http://mail.gnome.org/archives/gtk-devel-list/2010-June/msg00137.html #gtk|1276829633|0||0|0
264|GTK+ and friends|GTKtoolkit|GLib 2.25.9 (unstable) released: http://ur1.ca/08hrl WARNING: API changes in GDBus, GSettings and GApplication #gtk|1276829581|0||0|0
265|scaroo|scaroo|RT @scaroo: #SeedKit does RGBA window with css shadows and stuff : http://dl.dropbox.com/u/5746554/seedkit-does-rgba.png|1276734086|0|GTKtoolkit|0|1

View File

@@ -40,7 +40,7 @@ do_overlay2 (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Decorative Overlay");
overlay = gtk_overlay_new ();
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);

View File

@@ -443,7 +443,7 @@ do_sliding_puzzle (GtkWidget *do_widget)
gtk_media_stream_set_muted (media, TRUE);
gtk_media_stream_play (media);
add_choice (choices, GDK_PAINTABLE (media));
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), choices);
gtk_grid_attach (GTK_GRID (tweaks), sw, 0, 0, 2, 1);

View File

@@ -40,7 +40,7 @@ do_tabs (GtkWidget *do_widget)
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_text (buffer, "one\ttwo\tthree\nfour\tfive\tsix\nseven\teight\tnine", -1);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);

View File

@@ -57,6 +57,7 @@ do_tagged_entry (GtkWidget *do_widget)
static GtkWidget *window = NULL;
GtkWidget *box;
GtkWidget *box2;
GtkWidget *header;
GtkWidget *entry;
GtkWidget *button;
@@ -65,9 +66,12 @@ do_tagged_entry (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Tagged Entry");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_title (GTK_WINDOW (window), "A tagged entry");
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_deletable (GTK_WINDOW (window), FALSE);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
@@ -91,6 +95,13 @@ do_tagged_entry (GtkWidget *do_widget)
button = gtk_check_button_new_with_mnemonic ("_Spinner");
g_signal_connect (button, "toggled", G_CALLBACK (toggle_spinner), entry);
gtk_box_append (GTK_BOX (box2), button);
button = gtk_button_new_with_mnemonic ("_Done");
gtk_widget_add_css_class (button, "suggested-action");
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
gtk_window_set_default_widget (GTK_WINDOW (window), button);
}
if (!gtk_widget_get_visible (window))

View File

@@ -156,7 +156,7 @@ create_text_view (GtkWidget *hbox,
GtkWidget *textview;
guint timeout;
swindow = gtk_scrolled_window_new ();
swindow = gtk_scrolled_window_new (NULL, NULL);
gtk_box_append (GTK_BOX (hbox), swindow);
textview = gtk_text_view_new ();
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (swindow), textview);

View File

@@ -4,7 +4,7 @@
* GtkTextBuffer. You can enable or disable undo support using
* gtk_text_buffer_set_enable_undo().
*
* Use Control+z to undo and Control+Shift+z or Control+y to
* Use Primary+Z to undo and Primary+Shift+Z or Primary+Y to
* redo previously undone operations.
*/
@@ -29,7 +29,7 @@ do_textundo (GtkWidget *do_widget)
gtk_window_set_default_size (GTK_WINDOW (window), 450, 450);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_title (GTK_WINDOW (window), "Undo and Redo");
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);
@@ -46,7 +46,7 @@ do_textundo (GtkWidget *do_widget)
-1);
gtk_text_buffer_end_irreversible_action (buffer);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);

View File

@@ -494,7 +494,7 @@ do_textview (GtkWidget *do_widget)
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view1));
view2 = gtk_text_view_new_with_buffer (buffer);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
@@ -504,7 +504,7 @@ do_textview (GtkWidget *do_widget)
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), view1);
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
@@ -590,7 +590,7 @@ easter_egg_callback (GtkWidget *button,
g_object_unref (buffer);
window = gtk_window_new ();
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);

View File

@@ -84,7 +84,7 @@ static TreeItem may[] =
static TreeItem june[] =
{
{ "June Fathers' Day", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL },
{ "Juneteenth (Liberation Day)", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL },
{ "Juneteenth (Liberation of Slaves)", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL },
{ "Flag Day", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, NULL },
{ NULL }
};
@@ -406,7 +406,7 @@ do_tree_store (GtkWidget *do_widget)
gtk_box_append (GTK_BOX (vbox),
gtk_label_new ("Jonathan's Holiday Card Planning Sheet"));
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,

View File

@@ -2,6 +2,7 @@
<gresources>
<gresource prefix="/org/gtk/iconbrowser/gtk">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">menus.ui</file>
<file>icon.list</file>
</gresource>
</gresources>

View File

@@ -1,156 +0,0 @@
#include "iconbrowsercontext.h"
struct _IbContext
{
GObject parent_instance;
char *id;
char *name;
char *description;
};
struct _IbContextClass
{
GObjectClass parent_class;
};
enum {
PROP_ID = 1,
PROP_NAME,
PROP_DESCRIPTION,
PROP_NUM_PROPERTIES
};
G_DEFINE_TYPE (IbContext, ib_context, G_TYPE_OBJECT)
static void
ib_context_init (IbContext *context)
{
}
static void
ib_context_finalize (GObject *object)
{
IbContext *context = IB_CONTEXT (object);
g_free (context->id);
g_free (context->name);
g_free (context->description);
G_OBJECT_CLASS (ib_context_parent_class)->finalize (object);
}
static void
ib_context_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
IbContext *context = IB_CONTEXT (object);
switch (property_id)
{
case PROP_ID:
g_free (context->id);
context->id = g_value_dup_string (value);
break;
case PROP_NAME:
g_free (context->name);
context->name = g_value_dup_string (value);
break;
case PROP_DESCRIPTION:
g_free (context->description);
context->description = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
ib_context_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
IbContext *context = IB_CONTEXT (object);
switch (property_id)
{
case PROP_ID:
g_value_set_string (value, context->id);
break;
case PROP_NAME:
g_value_set_string (value, context->name);
break;
case PROP_DESCRIPTION:
g_value_set_string (value, context->description);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
ib_context_class_init (IbContextClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GParamSpec *pspec;
object_class->finalize = ib_context_finalize;
object_class->set_property = ib_context_set_property;
object_class->get_property = ib_context_get_property;
pspec = g_param_spec_string ("id", "Id", "Id",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_ID, pspec);
pspec = g_param_spec_string ("name", "Name", "Name",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_NAME, pspec);
pspec = g_param_spec_string ("description", "Description", "Description",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_DESCRIPTION, pspec);
}
IbContext *
ib_context_new (const char *id,
const char *name,
const char *description)
{
return g_object_new (IB_TYPE_CONTEXT,
"id", id,
"name", name,
"description", description,
NULL);
}
const char *
ib_context_get_id (IbContext *context)
{
return context->id;
}
const char *
ib_context_get_name (IbContext *context)
{
return context->name;
}
const char *
ib_context_get_description (IbContext *context)
{
return context->description;
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include <gtk.h>
#define IB_TYPE_CONTEXT (ib_context_get_type ())
G_DECLARE_FINAL_TYPE (IbContext, ib_context, IB, CONTEXT, GObject)
IbContext *ib_context_new (const char *id,
const char *name,
const char *description);
const char *ib_context_get_id (IbContext *context);
const char *ib_context_get_name (IbContext *context);
const char *ib_context_get_description (IbContext *context);

View File

@@ -1,228 +0,0 @@
#include "iconbrowsericon.h"
struct _IbIcon
{
GObject parent_instance;
gboolean use_symbolic;
char *regular_name;
char *symbolic_name;
char *description;
char *context;
};
struct _IbIconClass
{
GObjectClass parent_class;
};
enum {
PROP_NAME = 1,
PROP_REGULAR_NAME,
PROP_SYMBOLIC_NAME,
PROP_USE_SYMBOLIC,
PROP_DESCRIPTION,
PROP_CONTEXT,
PROP_NUM_PROPERTIES
};
G_DEFINE_TYPE (IbIcon, ib_icon, G_TYPE_OBJECT)
static void
ib_icon_init (IbIcon *icon)
{
}
static void
ib_icon_finalize (GObject *object)
{
IbIcon *icon = IB_ICON (object);
g_free (icon->regular_name);
g_free (icon->symbolic_name);
g_free (icon->description);
g_free (icon->context);
G_OBJECT_CLASS (ib_icon_parent_class)->finalize (object);
}
static void
ib_icon_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
IbIcon *icon = IB_ICON (object);
switch (property_id)
{
case PROP_REGULAR_NAME:
g_free (icon->regular_name);
icon->regular_name = g_value_dup_string (value);
if (!icon->use_symbolic)
g_object_notify (object, "name");
break;
case PROP_SYMBOLIC_NAME:
g_free (icon->symbolic_name);
icon->symbolic_name = g_value_dup_string (value);
if (icon->use_symbolic)
g_object_notify (object, "name");
break;
case PROP_USE_SYMBOLIC:
icon->use_symbolic = g_value_get_boolean (value);
g_object_notify (object, "name");
break;
case PROP_DESCRIPTION:
g_free (icon->description);
icon->description = g_value_dup_string (value);
break;
case PROP_CONTEXT:
g_free (icon->context);
icon->context = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
ib_icon_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
IbIcon *icon = IB_ICON (object);
switch (property_id)
{
case PROP_NAME:
g_value_set_string (value, ib_icon_get_name (icon));
break;
case PROP_REGULAR_NAME:
g_value_set_string (value, icon->regular_name);
break;
case PROP_SYMBOLIC_NAME:
g_value_set_string (value, icon->symbolic_name);
break;
case PROP_USE_SYMBOLIC:
g_value_set_boolean (value, icon->use_symbolic);
break;
case PROP_DESCRIPTION:
g_value_set_string (value, icon->description);
break;
case PROP_CONTEXT:
g_value_set_string (value, icon->context);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
ib_icon_class_init (IbIconClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GParamSpec *pspec;
object_class->finalize = ib_icon_finalize;
object_class->set_property = ib_icon_set_property;
object_class->get_property = ib_icon_get_property;
pspec = g_param_spec_string ("name", "Name", "Name",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_NAME, pspec);
pspec = g_param_spec_string ("regular-name", "Regular Name", "Regular Name",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_REGULAR_NAME, pspec);
pspec = g_param_spec_string ("symbolic-name", "Symbolic Name", "Symbolic Name",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SYMBOLIC_NAME, pspec);
pspec = g_param_spec_boolean ("use-symbolic", "Use Symbolic", "Use Symbolic",
FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_USE_SYMBOLIC, pspec);
pspec = g_param_spec_string ("description", "Description", "Description",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_DESCRIPTION, pspec);
pspec = g_param_spec_string ("context", "Context", "Context",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONTEXT, pspec);
}
IbIcon *
ib_icon_new (const char *regular_name,
const char *symbolic_name,
const char *description,
const char *context)
{
return g_object_new (IB_TYPE_ICON,
"regular-name", regular_name,
"symbolic-name", symbolic_name,
"description", description,
"context", context,
NULL);
}
const char *
ib_icon_get_name (IbIcon *icon)
{
if (icon->use_symbolic)
return icon->symbolic_name;
else
return icon->regular_name;
}
const char *
ib_icon_get_regular_name (IbIcon *icon)
{
return icon->regular_name;
}
const char *
ib_icon_get_symbolic_name (IbIcon *icon)
{
return icon->symbolic_name;
}
gboolean
ib_icon_get_use_symbolic (IbIcon *icon)
{
return icon->use_symbolic;
}
const char *
ib_icon_get_description (IbIcon *icon)
{
return icon->description;
}
const char *
ib_icon_get_context (IbIcon *icon)
{
return icon->context;
}

View File

@@ -1,18 +0,0 @@
#pragma once
#include <gtk.h>
#define IB_TYPE_ICON (ib_icon_get_type ())
G_DECLARE_FINAL_TYPE (IbIcon, ib_icon, IB, ICON, GObject)
IbIcon *ib_icon_new (const char *regular_name,
const char *symbolic_name,
const char *description,
const char *context);
const char *ib_icon_get_name (IbIcon *icon);
const char *ib_icon_get_regular_name (IbIcon *icon);
const char *ib_icon_get_symbolic_name (IbIcon *icon);
gboolean ib_icon_get_use_symbolic (IbIcon *icon);
const char *ib_icon_get_description (IbIcon *icon);
const char *ib_icon_get_context (IbIcon *icon);

View File

@@ -1,22 +1,48 @@
#include <string.h>
#include "iconbrowserapp.h"
#include "iconbrowserwin.h"
#include "iconbrowsericon.h"
#include "iconbrowsercontext.h"
#include "iconstore.h"
#include <gtk/gtk.h>
/* Drag 'n Drop */
typedef struct
{
gchar *id;
gchar *name;
gchar *description;
} Context;
static void
context_free (gpointer data)
{
Context *context = data;
g_free (context->id);
g_free (context->name);
g_free (context->description);
g_free (context);
}
struct _IconBrowserWindow
{
GtkApplicationWindow parent;
GHashTable *contexts;
GtkWidget *context_list;
Context *current_context;
gboolean symbolic;
GtkWidget *symbolic_radio;
GtkWidget *searchbar;
GListModel *icon_filter_model;
GListStore *icon_store;
GListStore *context_store;
GtkFilter *name_filter;
GtkTreeModelFilter *filter_model;
GtkWidget *details;
GtkListStore *store;
GtkCellRenderer *cell;
GtkCellRenderer *text_cell;
GtkWidget *search;
GtkWidget *searchbar;
GtkWidget *searchentry;
GtkWidget *list;
GtkWidget *image1;
GtkWidget *image2;
GtkWidget *image3;
@@ -42,6 +68,87 @@ icon_browser_window_get_icon_theme (IconBrowserWindow *win)
return gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (win)));
}
static void
search_text_changed (GtkEntry *entry, IconBrowserWindow *win)
{
const gchar *text;
text = gtk_editable_get_text (GTK_EDITABLE (entry));
if (text[0] == '\0')
return;
gtk_tree_model_filter_refilter (win->filter_model);
}
static void
set_image (GtkWidget *image, const gchar *name, gint size)
{
gtk_image_set_from_icon_name (GTK_IMAGE (image), name);
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
}
static void
item_activated (GtkIconView *icon_view, GtkTreePath *path, IconBrowserWindow *win)
{
GtkIconTheme *icon_theme = icon_browser_window_get_icon_theme (win);
GtkTreeIter iter;
gchar *name;
gchar *description;
gint column;
gtk_tree_model_get_iter (GTK_TREE_MODEL (win->filter_model), &iter, path);
if (win->symbolic)
column = ICON_STORE_SYMBOLIC_NAME_COLUMN;
else
column = ICON_STORE_NAME_COLUMN;
gtk_tree_model_get (GTK_TREE_MODEL (win->filter_model), &iter,
column, &name,
ICON_STORE_DESCRIPTION_COLUMN, &description,
-1);
if (name == NULL || !gtk_icon_theme_has_icon (icon_theme, name))
{
g_free (description);
return;
}
gtk_window_set_title (GTK_WINDOW (win->details), name);
set_image (win->image1, name, 8);
set_image (win->image2, name, 16);
set_image (win->image3, name, 18);
set_image (win->image4, name, 24);
set_image (win->image5, name, 32);
set_image (win->image6, name, 48);
set_image (win->image7, name, 64);
if (win->symbolic)
{
gtk_widget_show (win->image8);
gtk_widget_show (win->label8);
set_image (win->image8, name, 64);
}
else
{
gtk_widget_hide (win->image8);
gtk_widget_hide (win->label8);
}
if (description && description[0])
{
gtk_label_set_text (GTK_LABEL (win->description), description);
gtk_widget_show (win->description);
}
else
{
gtk_widget_hide (win->description);
}
gtk_window_present (GTK_WINDOW (win->details));
g_free (name);
g_free (description);
}
static void
add_icon (IconBrowserWindow *win,
const gchar *name,
@@ -51,7 +158,6 @@ add_icon (IconBrowserWindow *win,
GtkIconTheme *icon_theme = icon_browser_window_get_icon_theme (win);
gchar *regular_name;
gchar *symbolic_name;
IbIcon *icon;
regular_name = g_strdup (name);
if (!gtk_icon_theme_has_icon (icon_theme, regular_name))
@@ -67,12 +173,12 @@ add_icon (IconBrowserWindow *win,
symbolic_name = NULL;
}
icon = ib_icon_new (regular_name, symbolic_name, description, context);
g_object_bind_property (win->symbolic_radio, "active",
icon, "use-symbolic",
G_BINDING_DEFAULT);
g_list_store_append (win->icon_store, icon);
g_object_unref (icon);
gtk_list_store_insert_with_values (win->store, NULL, -1,
ICON_STORE_NAME_COLUMN, regular_name,
ICON_STORE_SYMBOLIC_NAME_COLUMN, symbolic_name,
ICON_STORE_DESCRIPTION_COLUMN, description,
ICON_STORE_CONTEXT_COLUMN, context,
-1);
}
static void
@@ -81,11 +187,50 @@ add_context (IconBrowserWindow *win,
const gchar *name,
const gchar *description)
{
IbContext *context;
Context *c;
GtkWidget *row;
context = ib_context_new (id, name, description);
g_list_store_append (win->context_store, context);
g_object_unref (context);
c = g_new (Context, 1);
c->id = g_strdup (id);
c->name = g_strdup (name);
c->description = g_strdup (description);
g_hash_table_insert (win->contexts, c->id, c);
row = gtk_label_new (name);
gtk_label_set_xalign (GTK_LABEL (row), 0);
g_object_set_data (G_OBJECT (row), "context", c);
gtk_widget_show (row);
gtk_widget_set_margin_start (row, 10);
gtk_widget_set_margin_end (row, 10);
gtk_widget_set_margin_top (row, 10);
gtk_widget_set_margin_bottom (row, 10);
gtk_list_box_insert (GTK_LIST_BOX (win->context_list), row, -1);
/* set the tooltip on the list box row */
row = gtk_widget_get_parent (row);
gtk_widget_set_tooltip_text (row, description);
if (win->current_context == NULL)
win->current_context = c;
}
static void
selected_context_changed (GtkListBox *list, IconBrowserWindow *win)
{
GtkWidget *row;
GtkWidget *label;
row = GTK_WIDGET (gtk_list_box_get_selected_row (list));
if (row == NULL)
return;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (win->search), FALSE);
label = gtk_list_box_row_get_child (GTK_LIST_BOX_ROW (row));
win->current_context = g_object_get_data (G_OBJECT (label), "context");
gtk_tree_model_filter_refilter (win->filter_model);
}
static void
@@ -137,19 +282,6 @@ populate (IconBrowserWindow *win)
g_strfreev (groups);
}
static gboolean
filter_by_icon_name (gpointer item,
gpointer data)
{
return ib_icon_get_name (IB_ICON (item)) != NULL;
}
static void
symbolic_toggled (IconBrowserWindow *win)
{
gtk_filter_changed (win->name_filter, GTK_FILTER_CHANGE_DIFFERENT);
}
static void
copy_to_clipboard (GtkButton *button,
IconBrowserWindow *win)
@@ -160,60 +292,70 @@ copy_to_clipboard (GtkButton *button,
gdk_clipboard_set_text (clipboard, gtk_window_get_title (GTK_WINDOW (win->details)));
}
static void
set_image (GtkWidget *image, const gchar *name, gint size)
static gboolean
icon_visible_func (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
gtk_image_set_from_icon_name (GTK_IMAGE (image), name);
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
IconBrowserWindow *win = data;
gchar *context;
gchar *name;
gint column;
gboolean search;
const gchar *search_text;
gboolean visible;
search = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (win->search));
search_text = gtk_editable_get_text (GTK_EDITABLE (win->searchentry));
if (win->symbolic)
column = ICON_STORE_SYMBOLIC_NAME_COLUMN;
else
column = ICON_STORE_NAME_COLUMN;
gtk_tree_model_get (model, iter,
column, &name,
ICON_STORE_CONTEXT_COLUMN, &context,
-1);
if (!name)
visible = FALSE;
else if (search)
visible = strstr (name, search_text) != NULL;
else
visible = win->current_context != NULL && g_strcmp0 (context, win->current_context->id) == 0;
g_free (name);
g_free (context);
return visible;
}
static void
item_activated (GtkGridView *view,
guint position,
IconBrowserWindow *win)
symbolic_toggled (GtkToggleButton *toggle, IconBrowserWindow *win)
{
GListModel *model = gtk_grid_view_get_model (view);
IbIcon *icon = g_list_model_get_item (model, position);
const char *name;
const char *description;
gboolean symbolic;
gint column;
name = ib_icon_get_name (icon);
description = ib_icon_get_description (icon);
symbolic = ib_icon_get_use_symbolic (icon);
win->symbolic = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle));
gtk_window_set_title (GTK_WINDOW (win->details), name);
set_image (win->image1, name, 8);
set_image (win->image2, name, 16);
set_image (win->image3, name, 18);
set_image (win->image4, name, 24);
set_image (win->image5, name, 32);
set_image (win->image6, name, 48);
set_image (win->image7, name, 64);
if (symbolic)
{
gtk_widget_show (win->image8);
gtk_widget_show (win->label8);
set_image (win->image8, name, 64);
}
if (win->symbolic)
column = ICON_STORE_SYMBOLIC_NAME_COLUMN;
else
{
gtk_widget_hide (win->image8);
gtk_widget_hide (win->label8);
}
if (description && description[0])
{
gtk_label_set_text (GTK_LABEL (win->description), description);
gtk_widget_show (win->description);
}
else
{
gtk_widget_hide (win->description);
}
column = ICON_STORE_NAME_COLUMN;
gtk_window_present (GTK_WINDOW (win->details));
icon_store_set_text_column (ICON_STORE (win->store), column);
g_object_unref (icon);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (win->list), win->cell, "icon-name", column, NULL);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (win->list), win->text_cell, "text", column, NULL);
gtk_tree_model_filter_refilter (win->filter_model);
gtk_widget_queue_draw (win->list);
}
static void
search_mode_toggled (GObject *searchbar, GParamSpec *pspec, IconBrowserWindow *win)
{
if (gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (searchbar)))
gtk_list_box_unselect_all (GTK_LIST_BOX (win->context_list));
}
static GdkPaintable *
@@ -239,10 +381,7 @@ get_image_paintable (GtkImage *image)
gtk_widget_get_direction (GTK_WIDGET (image)),
0);
if (icon == NULL)
{
g_print ("no icon for %s\n", icon_name);
return NULL;
}
return NULL;
return GDK_PAINTABLE (icon);
case GTK_IMAGE_GICON:
case GTK_IMAGE_EMPTY:
@@ -280,10 +419,10 @@ drag_prepare_texture (GtkDragSource *source,
{
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (widget));
if (!GDK_IS_PAINTABLE (paintable))
if (!GDK_IS_TEXTURE (paintable))
return NULL;
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
}
static GdkContentProvider *
@@ -337,10 +476,17 @@ setup_scalable_image_dnd (GtkWidget *image)
static void
icon_browser_window_init (IconBrowserWindow *win)
{
GtkFilter *filter;
GdkContentFormats *list;
gtk_widget_init_template (GTK_WIDGET (win));
list = gdk_content_formats_new_for_gtype (G_TYPE_STRING);
gtk_icon_view_enable_model_drag_source (GTK_ICON_VIEW (win->list),
GDK_BUTTON1_MASK,
list,
GDK_ACTION_COPY);
gdk_content_formats_unref (list);
setup_image_dnd (win->image1);
setup_image_dnd (win->image2);
setup_image_dnd (win->image3);
@@ -350,16 +496,19 @@ icon_browser_window_init (IconBrowserWindow *win)
setup_image_dnd (win->image7);
setup_scalable_image_dnd (win->image8);
win->contexts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, context_free);
gtk_tree_model_filter_set_visible_func (win->filter_model, icon_visible_func, win, NULL);
gtk_window_set_transient_for (GTK_WINDOW (win->details), GTK_WINDOW (win));
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (win->searchbar), GTK_WIDGET (win));
g_signal_connect (win->searchbar, "notify::search-mode-enabled",
G_CALLBACK (search_mode_toggled), win);
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (win->searchbar),
GTK_WIDGET (win));
symbolic_toggled (GTK_TOGGLE_BUTTON (win->symbolic_radio), win);
populate (win);
filter = gtk_filter_list_model_get_filter (GTK_FILTER_LIST_MODEL (win->icon_filter_model));
win->name_filter = gtk_custom_filter_new (filter_by_icon_name, NULL, NULL);
gtk_multi_filter_append (GTK_MULTI_FILTER (filter), g_object_ref (win->name_filter));
}
static void
@@ -367,7 +516,7 @@ icon_browser_window_finalize (GObject *object)
{
IconBrowserWindow *win = ICON_BROWSER_WINDOW (object);
g_clear_object (&win->name_filter);
g_hash_table_unref (win->contexts);
G_OBJECT_CLASS (icon_browser_window_parent_class)->finalize (object);
}
@@ -379,19 +528,23 @@ icon_browser_window_class_init (IconBrowserWindowClass *class)
object_class->finalize = icon_browser_window_finalize;
g_type_ensure (IB_TYPE_ICON);
g_type_ensure (IB_TYPE_CONTEXT);
g_type_ensure (ICON_STORE_TYPE);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/iconbrowser/gtk/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, context_list);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, filter_model);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, symbolic_radio);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, searchbar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, icon_store);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, icon_filter_model);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, context_store);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, details);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, store);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, cell);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, text_cell);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, search);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, searchbar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, searchentry);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, list);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image1);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image2);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image3);
@@ -403,9 +556,11 @@ icon_browser_window_class_init (IconBrowserWindowClass *class)
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, label8);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, description);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), item_activated);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), copy_to_clipboard);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), selected_context_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), symbolic_toggled);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), copy_to_clipboard);
}
IconBrowserWindow *

View File

@@ -0,0 +1,91 @@
#include "iconstore.h"
#include <gtk/gtk.h>
struct _IconStore
{
GtkListStore parent;
gint text_column;
};
struct _IconStoreClass
{
GtkListStoreClass parent_class;
};
static void icon_store_drag_source_init (GtkTreeDragSourceIface *iface);
G_DEFINE_TYPE_WITH_CODE (IconStore, icon_store, GTK_TYPE_LIST_STORE,
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
icon_store_drag_source_init))
static void
icon_store_init (IconStore *store)
{
GType types[4] = { G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING };
gtk_list_store_set_column_types (GTK_LIST_STORE (store), 4, types);
store->text_column = ICON_STORE_NAME_COLUMN;
}
static void
icon_store_class_init (IconStoreClass *class)
{
}
static gboolean
row_draggable (GtkTreeDragSource *drag_source,
GtkTreePath *path)
{
return TRUE;
}
static gboolean
drag_data_delete (GtkTreeDragSource *drag_source,
GtkTreePath *path)
{
GtkTreeIter iter;
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path))
return gtk_list_store_remove (GTK_LIST_STORE (drag_source), &iter);
return FALSE;
}
static GdkContentProvider *
drag_data_get (GtkTreeDragSource *drag_source,
GtkTreePath *path)
{
GdkContentProvider *content;
GtkTreeIter iter;
gchar *text;
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path))
return NULL;
gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter,
ICON_STORE (drag_source)->text_column, &text,
-1);
content = gdk_content_provider_new_typed (G_TYPE_STRING, text);
g_free (text);
return content;
}
static void
icon_store_drag_source_init (GtkTreeDragSourceIface *iface)
{
iface->row_draggable = row_draggable;
iface->drag_data_delete = drag_data_delete;
iface->drag_data_get = drag_data_get;
}
void
icon_store_set_text_column (IconStore *store, gint text_column)
{
store->text_column = text_column;
}

View File

@@ -0,0 +1,26 @@
#ifndef __ICON_STORE_H
#define __ICON_STORE_H
#include <gtk/gtk.h>
#define ICON_STORE_TYPE (icon_store_get_type ())
#define ICON_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ICON_STORE_TYPE, IconStore))
typedef struct _IconStore IconStore;
typedef struct _IconStoreClass IconStoreClass;
enum {
ICON_STORE_NAME_COLUMN,
ICON_STORE_SYMBOLIC_NAME_COLUMN,
ICON_STORE_DESCRIPTION_COLUMN,
ICON_STORE_CONTEXT_COLUMN
};
GType icon_store_get_type (void);
void icon_store_set_text_column (IconStore *store,
gint column);
#endif /* __ICON_STORE_H */

View File

@@ -0,0 +1,10 @@
<interface>
<menu id="app-menu">
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">app.quit</attribute>
</item>
</section>
</menu>
</interface>

View File

@@ -2,8 +2,7 @@ iconbrowser_sources = [
'main.c',
'iconbrowserapp.c',
'iconbrowserwin.c',
'iconbrowsericon.c',
'iconbrowsercontext.c'
'iconstore.c'
]
iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
@@ -18,3 +17,14 @@ executable('gtk4-icon-browser',
gui_app: true,
link_args: extra_demo_ldflags,
install: true)
install_data('org.gtk.IconBrowser4.desktop', install_dir: gtk_applicationsdir)
# icons
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
foreach size: ['scalable', 'symbolic']
install_subdir('data/' + size,
install_dir: icontheme_dir
)
endforeach

View File

@@ -12,6 +12,10 @@
</item>
</section>
</menu>
<object class="IconStore" id="store"/>
<object class="GtkTreeModelFilter" id="filter_model">
<property name="child-model">store</property>
</object>
<template class="IconBrowserWindow" parent="GtkApplicationWindow">
<style>
<class name="devel"/>
@@ -38,7 +42,7 @@
<property name="draw-indicator">0</property>
<property name="label" translatable="yes">Symbolic</property>
<property name="group">normal_radio</property>
<signal name="notify::active" handler="symbolic_toggled" swapped="yes" after="yes"/>
<signal name="toggled" handler="symbolic_toggled"/>
</object>
</child>
</object>
@@ -67,44 +71,8 @@
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkListView">
<property name="model">
<object class="GtkSingleSelection" id="context_model">
<property name="model">
<object class="GListStore" id="context_store">
<property name="item-type">IbContext</property>
</object>
</property>
</object>
</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes">
<![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="name" type="IbContext">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]>
</property>
</object>
</property>
</object>
</child>
<object class="GtkListBox" id="context_list">
<signal name="selected-rows-changed" handler="selected_context_changed"/>
</object>
</child>
<child>
@@ -120,6 +88,7 @@
<property name="search-mode-enabled" bind-source="search" bind-property="active" bind-flags="bidirectional"/>
<child>
<object class="GtkSearchEntry" id="searchentry">
<signal name="search-changed" handler="search_text_changed"/>
</object>
</child>
</object>
@@ -130,91 +99,23 @@
<property name="vexpand">1</property>
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkGridView" id="list">
<signal name="activate" handler="item_activated"/>
<property name="single-click-activate">1</property>
<property name="model">
<object class="GtkNoSelection">
<property name="model">
<object class="GtkFilterListModel" id="icon_filter_model">
<property name="filter">
<object class="GtkEveryFilter">
<child>
<object class="GtkStringFilter">
<property name="expression">
<lookup name="name" type="IbIcon"/>
</property>
<binding name="search">
<lookup name="text" type="GtkSearchEntry">
searchentry
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkStringFilter">
<property name="ignore-case">0</property>
<property name="match-mode">exact</property>
<property name="expression">
<lookup name="context" type="IbIcon"/>
</property>
<binding name="search">
<lookup name="id" type="IbContext">
<lookup name="selected-item" type="GtkSingleSelection">
context_model
</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</property>
<property name="model">
<object class="GListStore" id="icon_store">
<property name="item-type">IbIcon</property>
</object>
</property>
</object>
</property>
<object class="GtkIconView" id="list">
<property name="model">filter_model</property>
<property name="selection-mode">none</property>
<property name="activate-on-single-click">1</property>
<signal name="item_activated" handler="item_activated"/>
<child>
<object class="GtkCellRendererPixbuf" id="cell">
<property name="xpad">10</property>
<property name="ypad">10</property>
</object>
</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes">
<![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkImage">
<property name="pixel-size">48</property>
<binding name="icon-name">
<lookup name="name" type="IbIcon">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<binding name="label">
<lookup name="name" type="IbIcon">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</property>
</template>
</interface>
]]>
</property>
</child>
<child>
<object class="GtkCellRendererText" id="text_cell">
<property name="xpad">10</property>
<property name="ypad">10</property>
</object>
</property>
</child>
</object>
</child>
</object>
@@ -224,7 +125,14 @@
</object>
</child>
</template>
<object class="GtkSizeGroup">
<property name="mode">vertical</property>
<widgets>
<widget name="normal_radio"/>
<widget name="symbolic_radio"/>
<widget name="search"/>
</widgets>
</object>
<object class="GtkDialog" id="details">
<property name="modal">1</property>
<property name="use-header-bar">1</property>
@@ -256,7 +164,7 @@
</object>
</child>
<child>
<object class="GtkImage" id="image2">
<object class="GtkImage" id="image2">
<property name="halign">center</property>
<property name="valign">end</property>
<accessibility>
@@ -465,7 +373,7 @@
</layout>
</object>
</child>
<child>
<child>
<object class="GtkLabel" id="label8">
<property name="halign">center</property>
<property name="valign">baseline</property>
@@ -496,7 +404,7 @@
<signal name="clicked" handler="copy_to_clipboard"/>
</object>
</child>
<child>
<child>
<object class="GtkLabel" id="description">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
@@ -511,4 +419,3 @@
</child>
</object>
</interface>

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<style>
<class name="devel"/>
</style>
<property name="title" translatable="yes">Help</property>
<property name="default-width">720</property>
<property name="default-height">520</property>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkTextView" id="text_view">
<property name="wrap-mode">word</property>
<property name="left-margin">20</property>
<property name="right-margin">20</property>
<property name="top-margin">20</property>
<property name="bottom-margin">20</property>
<property name="buffer">
<object class="GtkTextBuffer" id="buffer"/>
</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -51,121 +51,21 @@ node_editor_application_init (NodeEditorApplication *app)
}
static void
activate_about (GSimpleAction *action,
quit_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = user_data;
char *version;
GString *s;
GskRenderer *gsk_renderer;
const char *renderer;
s = g_string_new ("");
g_string_append (s, "System libraries\n");
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
gsk_renderer = gtk_native_get_renderer (GTK_NATIVE (gtk_application_get_active_window (app)));
if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskVulkanRenderer") == 0)
renderer = "Vulkan";
else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskGLRenderer") == 0)
renderer = "OpenGL";
else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskCairoRenderer") == 0)
renderer = "Cairo";
else
renderer = "Unknown";
g_string_append_printf (s, "\nRenderer\n\t%s", renderer);
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
PACKAGE_VERSION,
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
"program-name", "GTK Node Editor",
"version", version,
"copyright", "©2019—2020 The GTK Team",
"license-type", GTK_LICENSE_LGPL_2_1,
"website", "http://www.gtk.org",
"comments", "Program to test GTK rendering",
"authors", (const char *[]){ "Benjamin Otte", "Timm Bäder", NULL},
"logo-icon-name", "text-editor-symbolic",
"title", "About GTK Node Editor",
"system-information", s->str,
NULL);
g_string_free (s, TRUE);
g_free (version);
}
static void
activate_quit (GSimpleAction *action,
GVariant *parameter,
gpointer data)
gpointer data)
{
g_application_quit (G_APPLICATION (data));
}
static void
activate_inspector (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
gtk_window_set_interactive_debugging (TRUE);
}
static void
activate_help (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkBuilder *builder;
GtkWidget *window;
GtkTextBuffer *buffer;
GBytes *bytes;
const char *text;
gsize len;
builder = gtk_builder_new ();
gtk_builder_add_from_resource (builder, "/org/gtk/gtk4/node-editor/help-window.ui", NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
buffer = GTK_TEXT_BUFFER (gtk_builder_get_object (builder, "buffer"));
bytes = g_resources_lookup_data ("/org/gtk/gtk4/node-editor/node-format.md",
G_RESOURCE_LOOKUP_FLAGS_NONE,
NULL);
text = g_bytes_get_data (bytes, &len);
gtk_text_buffer_set_text (buffer, text, len);
g_bytes_unref (bytes);
gtk_window_present (GTK_WINDOW (window));
g_object_unref (builder);
}
static GActionEntry app_entries[] =
{
{ "about", activate_about, NULL, NULL, NULL },
{ "quit", activate_quit, NULL, NULL, NULL },
{ "inspector", activate_inspector, NULL, NULL, NULL },
{ "help", activate_help, NULL, NULL, NULL },
{ "quit", quit_activated, NULL, NULL, NULL }
};
static void
node_editor_application_startup (GApplication *app)
{
const char *help_accels[2] = { "F1", NULL };
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
const char *open_accels[2] = { "<Ctrl>O", NULL };
GtkCssProvider *provider;
@@ -175,7 +75,6 @@ node_editor_application_startup (GApplication *app)
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.help", help_accels);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);

View File

@@ -825,7 +825,6 @@ node_editor_window_create_renderer_widget (gpointer item,
gtk_widget_set_size_request (box, 120, 90);
label = gtk_label_new (g_object_get_data (G_OBJECT (paintable), "description"));
gtk_widget_add_css_class (label, "title-4");
gtk_box_append (GTK_BOX (box), label);
picture = gtk_picture_new_for_paintable (paintable);

View File

@@ -1,22 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="gear_menu">
<section>
<item>
<attribute name="label" translatable="yes">_Help</attribute>
<attribute name="action">app.help</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Inspector</attribute>
<attribute name="action">app.inspector</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_About Node Editor</attribute>
<attribute name="action">app.about</attribute>
</item>
</section>
</menu>
<object class="GtkPopover" id="testcase_popover">
<child>
<object class="GtkGrid">
@@ -136,13 +119,6 @@
<property name="popover">testcase_popover</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gear_menu_button">
<property name="valign">center</property>
<property name="menu-model">gear_menu</property>
<property name="icon-name">open-menu-symbolic</property>
</object>
</child>
</object>
</child>
<child>

View File

@@ -2,7 +2,5 @@
<gresources>
<gresource prefix="/org/gtk/gtk4/node-editor">
<file preprocess="xml-stripblanks">node-editor-window.ui</file>
<file preprocess="xml-stripblanks">help-window.ui</file>
<file>node-format.md</file>
</gresource>
</gresources>

View File

@@ -1,213 +0,0 @@
# The Node file format
GSK render nodes can be serialized and deserialized using APIs such as `gsk_render_node_serialize()` and `gsk_render_node_deserialize()`. The intended use for this is development - primarily the development of GTK - by allowing things such as creating testsuites and benchmarks, exchanging nodes in bug reports. GTK includes the `gtk4-node-editor` application for creating such test files.
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the aprsing APIs.
The grammar of a node text representation using [the CSS value definition syntax](https://drafts.csswg.org/css-values-3/#value-defs) looks like this:
**document**: `<node>\*`
**node**: container { <document> } | `<node-name> { <property>* }`
**property**: `<property-name>: <node> | <value> ;`
Each node has its own `<node-name>` and supports a custom set of properties, each with their own `<property-name>` and syntax. The following paragraphs document each of the nodes and their properties.
When serializing and the value of a property equals the default value, this value will not be serialized. Serialization aims to produce an output as small as possible.
# Nodes
### container
The **container** node is a special node that allows specifying a list of child nodes. Its contents follow the same rules as an empty document.
### blend
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| bottom | `<node>` | color { color: #AF0; } | always |
| mode | `<blend-mode>` | normal | non-default |
| top | `<node>` | color { } | always |
Creates a node like `gsk_blend_node_new()` with the given properties.
### blur
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| blur | `<number>` | 1 | non-default |
| child | `<node>` | color { } | always |
Creates a node like `gsk_blur_node_new()` with the given properties.
### border
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| color | `<color>{1,4}` | black | non-default |
| outline | `<rounded-rect>` | 50 | always |
| width | `<number>{1,4}` | 1 | non-default |
Creates a node like `gsk_border_node_new()` with the given properties.
For the color and width properties, the values follow the typical CSS order of top, right, bottom, left. If the last/left value isn't given, the 2nd/right value is used. If the 3rd/bottom value isn't given, the 1st/top value is used. And if the 2nd/right value also isn't given, the 1st/top value is used for every 4 values.
### clip
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| child | `<node>` | color { } | always |
| clip | `<rounded-rect>` | 50 | always |
Creates a node like `gsk_clip_node_new()` with the given properties.
As an extension, this node allows specifying a rounded rectangle for the clip property. If that rectangle is indeed rounded, a node like `gsk_rounded_clip_node_new()` will be created instead.
### color
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| color | `<color>` | #FF00CC | always |
Creates a node like `gsk_color_node_new()` with the given properties.
The color is chosen as an error pink so it is visible while also reminding people to change it.
### color-matrix
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| child | `<node>` | color { } | always |
| matrix | `<transform>` | none | non-default |
| offset | `<number>{4}` | 0 0 0 0 | non-default |
Creates a node like `gsk_color_matrix_node_new()` with the given properties.
The matrix property accepts a <transform> for compatibility purposes, but you should be aware that the allowed values are meant to be used on 3D transformations, so their naming might appear awkward. However, it is always possible to use the matrix3d() production to specify all 16 values individually.
### cross-fade
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| end | `<node>` | color { } | always |
| mode | `<number>` | 0.5 | non-default |
| start | `<node>` | color { color: #AF0; } | always |
Creates a node like `gsk_cross_fade_node_new()` with the given properties.
### debug
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| child | `<node>` | color { } | always |
| message | `<string>` | "" | non-default |
Creates a node like `gsk_debug_node_new()` with the given properties.
### inset-shadow
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| blur | `<number>` | 0 | non-default |
| color | `<color>` | black | non-default |
| dx | `<number>` | 1 | non-default |
| dy | `<number>` | 1 | non-default |
| outline | `<rounded-rect>` | 50 | always |
| spread | `<number>` | 0 | non-default |
Creates a node like `gsk_inset_shadow_node_new()` with the given properties.
### linear-gradient
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| end | `<point>` | 0 50 | always |
| start | `<point>` | 0 0 | always |
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
### opacity
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| child | `<node>` | color { } | always |
| opacity | `<number>` | 0.5 | non-default |
Creates a node like `gsk_transform_node_new()` with the given properties.
### outset-shadow
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| blur | `<number>` | 0 | non-default |
| color | `<color>` | black | non-default |
| dx | `<number>` | 1 | non-default |
| dy | `<number>` | 1 | non-default |
| outline | `<rounded-rect>` | 50 | always |
| spread | `<number>` | 0 | non-default |
Creates a node like `gsk_outset_shadow_node_new()` with the given properties.
### repeat
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | *bounds of child node* | non-default |
| child | `<node>` | color { } | always |
| child-bounds| `<rect>` | *bounds of child node* | non-default |
Creates a node like `gsk_repeat_node_new()` with the given properties.
### rounded-clip
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| child | `<node>` | color { } | always |
| clip | `<rounded-rect>` | 50 | always |
Creates a node like `gsk_rounded_clip_node_new()` with the given properties.
### shadow
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| child | `<node>` | color { } | always |
| shadow | `<shadow>` | black 1 1 | always |
Creates a node like `gsk_shadow_node_new()` with the given properties.
### text
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| color | `<color>` | black | non-default |
| font | `<string>` | "Cantarell 11" | always |
| glyphs | `<glyphs>` | "Hello" | always |
| offset | `<point>` | 0 0 | non-default |
Creates a node like `gsk_text_node_new()` with the given properties.
If the given font does not exist or the given glyphs are invalid for the given font, an error node will be returned.
### texture
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| texture | `<url>` | *see below* | always |
Creates a node like `gsk_texture_node_new()` with the given properties.
The default texture is a 10x10 checkerboard with the top left and bottom right 5x5 being in the color #FF00CC and the other part being transparent. A possible representation for this texture is `url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABmJLR0QA/wD/AP+gvaeTAAAAKUlEQVQYlWP8z3DmPwMaYGQwYUQXY0IXwAUGUCGGoxkYGBiweXAoeAYAz44F3e3U1xUAAAAASUVORK5CYII=")
`.
### transform
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| child | `<node>` | color { } | always |
| transform| `<transform>` | none | non-default |
Creates a node like `gsk_transform_node_new()` with the given properties.

View File

@@ -1,14 +1,7 @@
executable('gtk4-print-editor',
executable('print-editor',
['print-editor.c'],
c_args: common_cflags,
dependencies: libgtk_dep,
include_directories: confinc,
gui_app: true,
link_args: extra_demo_ldflags,
install: true)
# desktop file
install_data('org.gtk.PrintEditor4.desktop', install_dir: gtk_applicationsdir)
# appdata
install_data('org.gtk.PrintEditor4.appdata.xml', install_dir: gtk_appdatadir)
link_args: extra_demo_ldflags)

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>org.gtk.PrintEditor4.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>LGPL-2.0+</project_license>
<name>GTK Print Editor</name>
<summary>Program to demonstrate GTK printing</summary>
<description>
<p>
GTK Print Editor is a simple editor to demonstrate GTK printing.
</p>
</description>
<screenshots>
<screenshot>
<image>https://static.gnome.org/appdata/gtk4-print-editor/gtk-print-editor1.png</image>
<caption>Print Editor</caption>
</screenshot>
</screenshots>
<kudos>
<kudo>HiDpiIcon</kudo>
<kudo>ModernToolkit</kudo>
</kudos>
<url type="homepage">https://www.gtk.org</url>
<translation type="gettext">gtk-4.0</translation>
<update_contact>matthias.clasen_at_gmail.com</update_contact>
<developer_name>Matthias Clasen and others</developer_name>
<releases>
<release version="3.99.0" date="2020">
<description>
<p>A new developers snapshot towards GTK 4.0.</p>
</description>
</release>
</releases>
</component>

View File

@@ -1,10 +0,0 @@
[Desktop Entry]
Name=Print Editor
Comment=A simple editor demonstrating GTK printing
Exec=gtk4-print-editor %f
Icon=text-editor-symbolic
Terminal=false
Type=Application
StartupNotify=true
Categories=Development;GTK;
NoDisplay=true

View File

@@ -23,7 +23,7 @@ update_title (GtkWindow *window)
else
basename = g_file_get_basename (filename);
title = g_strdup_printf ("GTK Print Editor — %s", basename);
title = g_strdup_printf ("Simple Editor with printing - %s", basename);
g_free (basename);
gtk_window_set_title (window, title);
@@ -592,54 +592,18 @@ activate_about (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
char *version;
GString *sysinfo;
char *setting;
char **backends;
int i;
sysinfo = g_string_new ("System libraries\n");
g_string_append_printf (sysinfo, "\tGLib\t%d.%d.%d\n",
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (sysinfo, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (sysinfo, "\tGTK\t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
g_string_append (sysinfo, "\nPrint backends\n");
g_object_get (gtk_settings_get_default (), "gtk-print-backends", &setting, NULL);
backends = g_strsplit (setting, ",", -1);
for (i = 0; backends[i]; i++)
g_string_append_printf (sysinfo, "\t%s\n", backends[i]);
g_strfreev (backends);
g_free (setting);
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
PACKAGE_VERSION,
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
const gchar *authors[] = {
"Alexander Larsson",
NULL
};
gtk_show_about_dialog (GTK_WINDOW (main_window),
"program-name", "GTK Print Editor",
"version", version,
"copyright", "© 2006-2020 Red Hat, Inc",
"license-type", GTK_LICENSE_LGPL_2_1,
"website", "http://www.gtk.org",
"comments", "Program to demonstrate GTK printing",
"authors", (const char *[]){ "Alexander Larsson", NULL },
"name", "Print Test Editor",
"logo-icon-name", "text-editor-symbolic",
"title", "About GTK Print Editor",
"system-information", sysinfo->str,
"version", PACKAGE_VERSION,
"copyright", "© 2006-2020 Red Hat, Inc",
"comments", "Program to demonstrate GTK printing.",
"authors", authors,
NULL);
g_string_free (sysinfo, TRUE);
g_free (version);
}
static void
@@ -679,6 +643,23 @@ static const gchar ui_info[] =
"<interface>"
" <menu id='menubar'>"
" <submenu>"
" <attribute name='label'>_Application</attribute>"
" <section>"
" <item>"
" <attribute name='label'>_About</attribute>"
" <attribute name='action'>app.about</attribute>"
" <attribute name='accel'>&lt;Primary&gt;a</attribute>"
" </item>"
" </section>"
" <section>"
" <item>"
" <attribute name='label'>_Quit</attribute>"
" <attribute name='action'>app.quit</attribute>"
" <attribute name='accel'>&lt;Primary&gt;q</attribute>"
" </item>"
" </section>"
" </submenu>"
" <submenu>"
" <attribute name='label'>_File</attribute>"
" <section>"
" <item>"
@@ -715,23 +696,6 @@ static const gchar ui_info[] =
" <attribute name='action'>app.print</attribute>"
" </item>"
" </section>"
" <section>"
" <item>"
" <attribute name='label'>_Quit</attribute>"
" <attribute name='action'>app.quit</attribute>"
" <attribute name='accel'>&lt;Primary&gt;q</attribute>"
" </item>"
" </section>"
" </submenu>"
" <submenu>"
" <attribute name='label'>_Help</attribute>"
" <section>"
" <item>"
" <attribute name='label'>_About Print Editor</attribute>"
" <attribute name='action'>app.about</attribute>"
" <attribute name='accel'>&lt;Primary&gt;a</attribute>"
" </item>"
" </section>"
" </submenu>"
" </menu>"
"</interface>";
@@ -752,6 +716,25 @@ mark_set_callback (GtkTextBuffer *text_buffer,
update_statusbar ();
}
static gint
command_line (GApplication *application,
GApplicationCommandLine *command_line)
{
int argc;
char **argv;
argv = g_application_command_line_get_arguments (command_line, &argc);
if (argc == 2)
{
GFile *file = g_file_new_for_commandline_arg (argv[1]);
load_file (file);
g_object_unref (file);
}
return 0;
}
static void
startup (GApplication *app)
{
@@ -785,7 +768,7 @@ activate (GApplication *app)
gtk_window_set_child (GTK_WINDOW (main_window), box);
/* Create document */
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
@@ -826,20 +809,6 @@ activate (GApplication *app)
gtk_widget_show (main_window);
}
static void
open (GApplication *application,
GFile **files,
int n_files,
const char *hint)
{
if (n_files > 1)
g_warning ("Can only open a single file");
activate (application);
load_file (files[0]);
}
int
main (int argc, char **argv)
{
@@ -863,7 +832,7 @@ main (int argc, char **argv)
g_clear_error (&error);
}
app = gtk_application_new ("org.gtk.PrintEditor4", G_APPLICATION_HANDLES_OPEN);
app = gtk_application_new ("org.gtk.PrintEditor", 0);
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
@@ -871,7 +840,7 @@ main (int argc, char **argv)
g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
g_signal_connect (app, "open", G_CALLBACK (open), NULL);
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
g_application_run (G_APPLICATION (app), argc, argv);

View File

@@ -408,8 +408,6 @@ activate_print (GSimpleAction *action,
g_signal_connect (op, "draw-page", G_CALLBACK (print_operation_page), window);
g_signal_connect (op, "done", G_CALLBACK (print_operation_done), NULL);
gtk_print_operation_set_embed_page_setup (op, TRUE);
res = gtk_print_operation_run (op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, window, NULL);
if (res == GTK_PRINT_OPERATION_RESULT_IN_PROGRESS)

View File

@@ -207,6 +207,8 @@ GdkModifierType
GDK_MODIFIER_MASK
<SUBSECTION>
gdk_surface_get_support_multidevice
gdk_surface_set_support_multidevice
gdk_surface_get_device_cursor
gdk_surface_set_device_cursor
@@ -355,13 +357,17 @@ gdk_device_get_name
gdk_device_get_vendor_id
gdk_device_get_product_id
gdk_device_get_source
gdk_device_set_key
gdk_device_get_key
gdk_device_set_axis_use
gdk_device_get_axis_use
gdk_device_get_associated_device
gdk_device_list_physical_devices
gdk_device_list_slave_devices
gdk_device_get_device_type
gdk_device_get_display
gdk_device_get_has_cursor
gdk_device_get_n_axes
gdk_device_get_n_keys
gdk_device_get_axes
gdk_device_get_seat
gdk_device_get_num_touches
@@ -378,6 +384,9 @@ gdk_device_get_state
gdk_device_get_surface_at_position
GdkTimeCoord
gdk_device_get_axis
gdk_device_get_axis_names
gdk_device_get_axis_value
gdk_device_get_last_event_surface
<SUBSECTION>
gdk_device_tool_get_serial
@@ -438,7 +447,8 @@ gdk_seat_get_display
gdk_seat_get_capabilities
gdk_seat_get_pointer
gdk_seat_get_keyboard
gdk_seat_get_physical_devices
gdk_seat_get_slaves
gdk_seat_get_master_pointers
<SUBSECTION Standard>
GDK_SEAT
@@ -482,14 +492,12 @@ gdk_event_get_source_device
gdk_event_get_device_tool
gdk_event_get_time
gdk_event_get_display
gdk_event_get_seat
GdkEventSequence
gdk_event_get_event_sequence
gdk_event_get_modifier_state
gdk_event_get_position
gdk_event_get_axes
gdk_event_get_axis
gdk_event_get_history
gdk_event_get_pointer_emulated
gdk_event_triggers_context_menu
gdk_button_event_get_button
@@ -521,6 +529,7 @@ gdk_touchpad_event_get_pinch_scale
gdk_pad_event_get_axis_value
gdk_pad_event_get_button
gdk_pad_event_get_group_mode
gdk_motion_event_get_history
<SUBSECTION>
gdk_events_get_angle

View File

@@ -48,7 +48,6 @@
<chapter id="Lists">
<title>GListModel support</title>
<xi:include href="xml/gtkbitset.xml" />
<xi:include href="xml/gtkexpression.xml" />
<xi:include href="xml/gtkfilterlistmodel.xml" />
<section>
@@ -73,10 +72,9 @@
<xi:include href="xml/gtknoselection.xml" />
<xi:include href="xml/gtksingleselection.xml" />
<xi:include href="xml/gtkmultiselection.xml" />
<xi:include href="xml/gtkpropertyselection.xml" />
</section>
<xi:include href="xml/gtkbookmarklist.xml" />
<xi:include href="xml/gtkdirectorylist.xml" />
<xi:include href="xml/gtkstringlist.xml" />
</chapter>
<chapter id="ListContainers">
@@ -218,7 +216,6 @@
<xi:include href="xml/gtkspinbutton.xml" />
<xi:include href="xml/gtksearchentry.xml" />
<xi:include href="xml/gtksearchbar.xml" />
<xi:include href="xml/gtkeditablelabel.xml" />
</chapter>
<chapter id="TextWidgetObjects">

View File

@@ -312,8 +312,6 @@ gtk_list_box_bind_model
gtk_list_box_row_new
gtk_list_box_row_changed
gtk_list_box_row_is_selected
gtk_list_box_row_get_child
gtk_list_box_row_set_child
gtk_list_box_row_get_header
gtk_list_box_row_set_header
gtk_list_box_row_get_index
@@ -341,69 +339,21 @@ gtk_list_box_get_type
gtk_list_box_row_get_type
</SECTION>
<SECTION>
<FILE>gtkbitset</FILE>
<TITLE>GtkBitset</TITLE>
GtkBitset
gtk_bitset_ref
gtk_bitset_unref
gtk_bitset_new_empty
gtk_bitset_new_range
gtk_bitset_copy
<SUBSECTION>
gtk_bitset_contains
gtk_bitset_is_empty
gtk_bitset_equals
gtk_bitset_get_minimum
gtk_bitset_get_maximum
gtk_bitset_get_size
gtk_bitset_get_size_in_range
gtk_bitset_get_nth
<SUBSECTION>
gtk_bitset_remove_all
gtk_bitset_add
gtk_bitset_remove
gtk_bitset_add_range
gtk_bitset_remove_range
gtk_bitset_add_range_closed
gtk_bitset_remove_range_closed
gtk_bitset_add_rectangle
gtk_bitset_remove_rectangle
gtk_bitset_union
gtk_bitset_intersect
gtk_bitset_subtract
gtk_bitset_difference
gtk_bitset_shift_left
gtk_bitset_shift_right
gtk_bitset_slice
<SUBSECTION>
GtkBitsetIter
gtk_bitset_iter_init_first
gtk_bitset_iter_init_last
gtk_bitset_iter_init_at
gtk_bitset_iter_next
gtk_bitset_iter_previous
gtk_bitset_iter_get_value
gtk_bitset_iter_is_valid
<SUBSECTION Private>
GTK_TYPE_BITSET
gtk_bitset_get_type
</SECTION>
<SECTION>
<FILE>gtkselectionmodel</FILE>
<TITLE>GtkSelectionModel</TITLE>
GtkSelectionModel
gtk_selection_model_is_selected
gtk_selection_model_get_selection
gtk_selection_model_get_selection_in_range
gtk_selection_model_select_item
gtk_selection_model_unselect_item
gtk_selection_model_select_range
gtk_selection_model_unselect_range
gtk_selection_model_select_all
gtk_selection_model_unselect_all
gtk_selection_model_set_selection
GtkSelectionCallback
gtk_selection_model_select_callback
gtk_selection_model_unselect_callback
gtk_selection_model_query_range
<SUBSECTION>
gtk_selection_model_selection_changed
<SUBSECTION Standard>
@@ -454,6 +404,15 @@ gtk_multi_selection_new
gtk_multi_selection_get_type
</SECTION>
<SECTION>
<FILE>gtkpropertyselection</FILE>
<TITLE>GtkPropertySelection</TITLE>
GtkPropertySelection
gtk_property_selection_new
<SUBSECTION Private>
gtk_property_selection_get_type
</SECTION>
<SECTION>
<FILE>gtklistitem</FILE>
<TITLE>GtkListItem</TITLE>
@@ -465,8 +424,6 @@ gtk_list_item_set_child
gtk_list_item_get_selected
gtk_list_item_get_selectable
gtk_list_item_set_selectable
gtk_list_item_get_activatable
gtk_list_item_set_activatable
<SUBSECTION Standard>
GTK_LIST_ITEM
GTK_LIST_ITEM_CLASS
@@ -630,7 +587,6 @@ gtk_column_view_column_get_type
<TITLE>GtkGridView</TITLE>
GtkGridView
gtk_grid_view_new
gtk_grid_view_new_with_factory
gtk_grid_view_set_model
gtk_grid_view_get_model
gtk_grid_view_set_max_columns
@@ -641,8 +597,6 @@ gtk_grid_view_set_single_click_activate
gtk_grid_view_get_single_click_activate
gtk_grid_view_set_enable_rubberband
gtk_grid_view_get_enable_rubberband
gtk_grid_view_set_factory
gtk_grid_view_get_factory
<SUBSECTION Standard>
GTK_GRID_VIEW
GTK_GRID_VIEW_CLASS
@@ -1026,18 +980,6 @@ GTK_EDITABLE_GET_IFACE
gtk_editable_get_type
</SECTION>
<SECTION>
<FILE>gtkeditablelabel</FILE>
<TITLE>GtkEditableLabel</TITLE>
GtkEditableLabel
gtk_editable_label_new
gtk_editable_label_get_editing
gtk_editable_label_start_editing
gtk_editable_label_stop_editing
<SUBSECTION Private>
gtk_editable_label_get_type
</SECTION>
<SECTION>
<FILE>gtktext</FILE>
<TITLE>GtkText</TITLE>
@@ -1458,21 +1400,6 @@ GTK_DIRECTORY_LIST_GET_CLASS
gtk_directory_list_get_type
</SECTION>
<SECTION>
<FILE>gtkbookmarklist</FILE>
<TITLE>GtkBookmarkList</TITLE>
GtkBookmarkList
gtk_bookmark_list_new
gtk_bookmark_list_get_filename
gtk_bookmark_list_set_attributes
gtk_bookmark_list_get_attributes
gtk_bookmark_list_set_io_priority
gtk_bookmark_list_get_io_priority
gtk_bookmark_list_is_loading
<SUBSECTION Standard>
GTK_TYPE_BOOKMARK_LIST
</SECTION>
<SECTION>
<FILE>gtkfilter</FILE>
<TITLE>GtkFilter</TITLE>
@@ -1482,6 +1409,8 @@ gtk_filter_get_strictness
<SUBSECTION>
GtkFilterChange
gtk_filter_changed
<SUBSECTION>
gtk_custom_filter_new
<SUBSECTION Standard>
GTK_FILTER
GTK_IS_FILTER
@@ -1499,7 +1428,6 @@ gtk_filter_get_type
GtkCustomFilter
GtkCustomFilterFunc
gtk_custom_filter_new
gtk_custom_filter_set_filter_func
<SUBSECTION Standard>
GTK_CUSTOM_FILTER
GTK_IS_CUSTOM_FILTER
@@ -1544,9 +1472,6 @@ gtk_filter_list_model_set_model
gtk_filter_list_model_get_model
gtk_filter_list_model_set_filter
gtk_filter_list_model_get_filter
gtk_filter_list_model_set_incremental
gtk_filter_list_model_get_incremental
gtk_filter_list_model_get_pending
<SUBSECTION Standard>
GTK_FILTER_LIST_MODEL
GTK_IS_FILTER_LIST_MODEL
@@ -1566,9 +1491,6 @@ gtk_fixed_new
gtk_fixed_put
gtk_fixed_remove
gtk_fixed_move
gtk_fixed_get_child_position
gtk_fixed_get_child_transform
gtk_fixed_set_child_transform
<SUBSECTION Standard>
GTK_FIXED
GTK_IS_FIXED
@@ -2782,8 +2704,6 @@ gtk_numeric_sorter_get_type
<TITLE>GtkCustomSorter</TITLE>
GtkCustomSorter
gtk_custom_sorter_new
gtk_custom_sorter_set_sort_func
<SUBSECTION Standard>
GTK_CUSTOM_SORTER
GTK_IS_CUSTOM_SORTER
@@ -4552,8 +4472,11 @@ gtk_widget_has_visible_focus
gtk_widget_is_drawable
gtk_widget_set_receives_default
gtk_widget_get_receives_default
gtk_widget_set_support_multidevice
gtk_widget_get_support_multidevice
gtk_widget_get_realized
gtk_widget_get_mapped
gtk_widget_device_is_shadowed
gtk_widget_get_opacity
gtk_widget_set_opacity
gtk_widget_get_overflow
@@ -6108,16 +6031,6 @@ gtk_header_bar_get_type
GtkStackPage
gtk_stack_page_get_visible
gtk_stack_page_set_visible
gtk_stack_page_get_title
gtk_stack_page_set_title
gtk_stack_page_get_name
gtk_stack_page_set_name
gtk_stack_page_get_needs_attention
gtk_stack_page_set_needs_attention
gtk_stack_page_get_use_underline
gtk_stack_page_set_use_underline
gtk_stack_page_get_icon_name
gtk_stack_page_set_icon_name
gtk_stack_page_get_child
GtkStack
gtk_stack_new
@@ -7588,7 +7501,6 @@ gtk_drop_down_set_model
gtk_drop_down_get_model
gtk_drop_down_set_selected
gtk_drop_down_get_selected
gtk_drop_down_get_selected_item
gtk_drop_down_set_factory
gtk_drop_down_get_factory
gtk_drop_down_set_list_factory
@@ -7602,17 +7514,3 @@ GTK_TYPE_DROP_DOWN
<SUBSECTION Private>
gtk_drop_down_get_type
</SECTION>
<SECTION>
<FILE>gtkstringlist</FILE>
<TITLE>GtkStringList</TITLE>
GtkStringList
gtk_string_list_new
gtk_string_list_append
gtk_string_list_take
gtk_string_list_remove
gtk_string_list_splice
gtk_string_list_get_string
GtkStringObject
gtk_string_object_get_string
</SECTION>

View File

@@ -18,8 +18,6 @@ gtk_aspect_frame_get_type
gtk_assistant_get_type
gtk_assistant_page_get_type
gtk_bin_layout_get_type
gtk_bitset_get_type
gtk_bookmark_list_get_type
gtk_box_get_type
gtk_box_layout_get_type
gtk_buildable_get_type
@@ -70,7 +68,6 @@ gtk_drop_target_get_type
gtk_drop_target_async_get_type
gtk_drop_down_get_type
gtk_editable_get_type
gtk_editable_label_get_type
gtk_emoji_chooser_get_type
gtk_entry_buffer_get_type
gtk_entry_completion_get_type
@@ -172,6 +169,7 @@ gtk_print_operation_preview_get_type
gtk_print_settings_get_type
@DISABLE_ON_W32@gtk_print_unix_dialog_get_type
gtk_progress_bar_get_type
gtk_property_selection_get_type
gtk_radio_button_get_type
gtk_range_get_type
gtk_recent_manager_get_type
@@ -210,8 +208,6 @@ gtk_stack_sidebar_get_type
gtk_stack_switcher_get_type
gtk_statusbar_get_type
gtk_string_filter_get_type
gtk_string_list_get_type
gtk_string_object_get_type
gtk_string_sorter_get_type
gtk_switch_get_type
gtk_level_bar_get_type

View File

@@ -5,7 +5,7 @@ in what happens to translate a key press or mouse motion of the users into a
change of a GTK widget, you should read this chapter. This knowledge will also
be useful if you decide to implement your own widgets.
## Devices and events
Devices and events
The most basic input devices that every computer user has interacted with are
keyboards and mice; beyond these, GTK supports touchpads, touchscreens and
@@ -13,14 +13,14 @@ more exotic input devices such as graphics tablets. Inside GTK, every such
input device is represented by a #GdkDevice object.
To simplify dealing with the variability between these input devices, GTK
has a concept of logical and physical devices. The concrete physical devices that
has a concept of master and slave devices. The concrete physical devices that
have many different characteristics (mice may have 2 or 3 or 8 buttons,
keyboards have different layouts and may or may not have a separate number
block, etc) are represented as physical devices. Each physical device is
associated with a virtual logical device. Logical devices always come in
block, etc) are represented as slave devices. Each slave device is
associated with a virtual master device. Master devices always come in
pointer/keyboard pairs - you can think of such a pair as a 'seat'.
GTK widgets generally deal with the logical devices, and thus can be used
GTK widgets generally deal with the master devices, and thus can be used
with any pointing device or keyboard.
When a user interacts with an input device (e.g. moves a mouse or presses

View File

@@ -176,6 +176,7 @@ private_headers = [
'gtkroundedboxprivate.h',
'gtkscalerprivate.h',
'gtksearchentryprivate.h',
'gtkset.h',
'gtksettingsprivate.h',
'gtkshortcutcontrollerprivate.h',
'gtkshortcutsshortcutprivate.h',
@@ -215,7 +216,6 @@ private_headers = [
'gtkwin32themeprivate.h',
'gtkwindowprivate.h',
'gtk-text-input-client-protocol.h',
'roaring.h',
]
images = [

View File

@@ -457,11 +457,6 @@ as property. GtkNotebook and GtkAssistant are similar.
gtk4-builder-tool can help with this conversion, with the --3to4 option
of the simplify command.
### Adapt to GtkScrolledWindow API changes
The constructor for GtkScrolledWindow no longer takes the adjustments
as arguments - these were almost always %NULL.
### Adapt to GtkBin removal
The abstract base class GtkBin for single-child containers has been
@@ -643,7 +638,7 @@ nodes.
If you are using a #GtkDrawingArea for custom drawing, you need to switch
to using gtk_drawing_area_set_draw_func() to set a draw function instead
of connecting a handler to the #GtkWidget::draw signal.
of connnecting a handler to the #GtkWidget::draw signal.
### Stop using APIs to query GdkSurfaces
@@ -945,18 +940,3 @@ You can replace calls to <function>gtk_dialog_run()</function>
by specifying that the #GtkDialog must be modal using
gtk_window_set_modal() or the %GTK_DIALOG_MODAL flag, and
connecting to the #GtkDialog::response signal.
## Changes to consider after the switch
GTK 4 has a number of new features that you may want to take
advantage of once the dust has settled over the initial migration.
### Consider porting to the new list widgets
In GTK 2 and 3, GtkTreeModel and GtkCellRenderer and widgets using
these were the primary way of displaying data and lists. GTK 4 brings
a new family of widgets for this purpose that uses list models instead
of tree models, and widgets instead of cell renderers.
To learn more about the new list widgets, you can read the [List Widget
Overview](#ListWidget).

View File

@@ -4,10 +4,9 @@
GTK inspects a number of environment variables in addition to
standard variables like `LANG`, `PATH`, `HOME` or `DISPLAY`; mostly
to determine paths to look for certain files. The [X11](#x11-envar),
[Wayland](#wayland-envar), [Windows](#win32-envar) and
[Broadway](#broadway-envar) GDK backends use some additional
environment variables.
to determine paths to look for certain files. The [X11]{#x11-envar},
[Windows]{#win32-envar} and [Broadway]{#broadway-envar} GDK backends
use some additional environment variables.
### GTK_DEBUG {#GTK_Debug-Options}

View File

@@ -4,8 +4,8 @@ GTK provides powerful widgets to display and edit lists of data. This document
gives an overview over the concepts and how they work together to allow
developers to implement lists.
Lists are intended to be used whenever developers want to display many objects
in roughly the same way.
Lists are intended to be used whenever developers want to display lists of
objects in roughly the same way.
Lists are perfectly fine to be used for very short list of only 2 or 3 elements,
but generally scale fine to millions of items. Of course, the larger the list
@@ -32,8 +32,8 @@ be provided in 3 ways or combinations thereof:
specific data, like #GtkDirectoryList. And there are models like #GListStore
that allow building lists manually.
* Wrapping list models like #GtkFilterListModel or #GtkSortListModel
modify, adapt or combine other models.
* Wrapping list models exists like #GtkFilterListModel or #GtkSortListModel
that modify or adapt or combine other models.
* Last but not least, developers are encouraged to create their own #GListModel
implementations. The interface is kept deliberately small to make this easy.
@@ -44,9 +44,8 @@ multiple different models at once.
The elements in a model are called **_items_**. All items are #GObjects.
Every item in a model has a **_position_** which is the unsigned integer that
describes where in the model the item is located. The first item in a model is
at position 0. The position of an item can of course change as other items are
added or removed from the model.
describes where in the model the item is located. This position can of course
change as items are added or removed from the model.
It is important to be aware of the difference between items and positions
because the mapping from position to item is not permanent, so developers
@@ -81,7 +80,7 @@ The behavior of selection models - ie which items they allow selecting and
what effect this has on other items - is completely up to the selection model.
As such, single-selections, multi-selections or sharing selection state between
different selection models and/or views is possible. The selection state of an
item is exposed in the listitem via the #GtkListItem:selected property.
item is exposed in the listitem via the GtkListItem:selected property.
Views and listitems also support activation. Activation means that double
clicking or pressing enter while inside a focused row will cause the view

View File

@@ -7,13 +7,4 @@ the Wayland backend by setting `GDK_BACKEND=wayland`.
On UNIX, the Wayland backend is enabled by default, so you don't need to
do anything special when compiling it, and everything should "just work."
## Wayland-specific environment variables {#wayland-envar}
### WAYLAND_DISPLAY
Specifies the name of the Wayland display to use. Typically, wayland-0
or wayland-1.
### XDG_RUNTIME_DIR
Used to locate the Wayland socket to use.
Currently, the Wayland backend does not use any additional environment variables.

View File

@@ -16,6 +16,7 @@ variables.
### GDK_IGNORE_WINTAB
If this variable is set, GTK doesn't use the Wintab API for tablet support.
</para>
### GDK_USE_WINTAB
@@ -36,10 +37,10 @@ can override GTK settings in the `settings.ini` file or at runtime in the
GTK Inspector.
Themes are loaded from normal Windows variants of the XDG locations:
`%HOME%/icons/THEME/cursors`,
`%APPDATA%/icons/THEME/cursors`,
`%HOME%/icons/THEME/cursors`,
`%APPDATA%/icons/THEME/cursors`,
`RUNTIME_PREFIX/share/icons/THEME/cursors`
The `gtk-cursor-theme-size` setting is ignored, GTK will use
The `gtk-cursor-theme-size`> setting is ignored, GTK will use
the cursor size that Windows tells it to use.

View File

@@ -881,7 +881,7 @@ create_scrolledwindow (void)
{
GtkWidget *scrolledwin, *label;
scrolledwin = gtk_scrolled_window_new ();
scrolledwin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
label = gtk_label_new ("Scrolled Window");

View File

@@ -258,7 +258,7 @@ example_app_window_open (ExampleAppWindow *win,
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -43,7 +43,7 @@ example_app_window_open (ExampleAppWindow *win,
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -53,7 +53,7 @@ example_app_window_open (ExampleAppWindow *win,
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -76,7 +76,7 @@ example_app_window_open (ExampleAppWindow *win,
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -77,7 +77,7 @@ example_app_window_open (ExampleAppWindow *win,
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -130,7 +130,7 @@ example_app_window_open (ExampleAppWindow *win,
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -222,7 +222,7 @@ example_app_window_open (ExampleAppWindow *win,
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -256,7 +256,7 @@ example_app_window_open (ExampleAppWindow *win,
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -252,7 +252,7 @@ new_window (GApplication *app,
gtk_grid_attach (GTK_GRID (grid), toolbar, 0, 0, 1, 1);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -86,7 +86,7 @@ new_window (GApplication *app,
grid = gtk_grid_new ();
gtk_window_set_child (GTK_WINDOW (window), grid);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -21,7 +21,7 @@ new_window (GApplication *app,
overlay = gtk_overlay_new ();
gtk_window_set_child (GTK_WINDOW (window), overlay);
scrolled = gtk_scrolled_window_new ();
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();

View File

@@ -73,8 +73,8 @@ gdk_broadway_device_init (GdkBroadwayDevice *device_core)
device = GDK_DEVICE (device_core);
_gdk_device_add_axis (device, GDK_AXIS_X, 0, 0, 1);
_gdk_device_add_axis (device, GDK_AXIS_Y, 0, 0, 1);
_gdk_device_add_axis (device, NULL, GDK_AXIS_X, 0, 0, 1);
_gdk_device_add_axis (device, NULL, GDK_AXIS_Y, 0, 0, 1);
}
static void
@@ -157,7 +157,7 @@ _gdk_broadway_surface_grab_check_unmap (GdkSurface *surface,
seat = gdk_display_get_default_seat (display);
devices = gdk_seat_get_physical_devices (seat, GDK_SEAT_CAPABILITY_ALL);
devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_ALL);
devices = g_list_prepend (devices, gdk_seat_get_keyboard (seat));
devices = g_list_prepend (devices, gdk_seat_get_pointer (seat));

View File

@@ -119,7 +119,7 @@ create_core_pointer (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Core Pointer",
"type", GDK_DEVICE_TYPE_LOGICAL,
"type", GDK_DEVICE_TYPE_MASTER,
"source", GDK_SOURCE_MOUSE,
"has-cursor", TRUE,
"display", display,
@@ -131,7 +131,7 @@ create_core_keyboard (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Core Keyboard",
"type", GDK_DEVICE_TYPE_LOGICAL,
"type", GDK_DEVICE_TYPE_MASTER,
"source", GDK_SOURCE_KEYBOARD,
"has-cursor", FALSE,
"display", display,
@@ -143,7 +143,7 @@ create_pointer (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Pointer",
"type", GDK_DEVICE_TYPE_PHYSICAL,
"type", GDK_DEVICE_TYPE_SLAVE,
"source", GDK_SOURCE_MOUSE,
"has-cursor", TRUE,
"display", display,
@@ -155,7 +155,7 @@ create_keyboard (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Keyboard",
"type", GDK_DEVICE_TYPE_PHYSICAL,
"type", GDK_DEVICE_TYPE_SLAVE,
"source", GDK_SOURCE_KEYBOARD,
"has-cursor", FALSE,
"display", display,
@@ -167,7 +167,7 @@ create_touchscreen (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
"name", "Touchscreen",
"type", GDK_DEVICE_TYPE_PHYSICAL,
"type", GDK_DEVICE_TYPE_SLAVE,
"source", GDK_SOURCE_TOUCHSCREEN,
"has-cursor", FALSE,
"display", display,
@@ -196,15 +196,15 @@ _gdk_broadway_display_open (const gchar *display_name)
_gdk_device_set_associated_device (broadway_display->pointer, broadway_display->core_pointer);
_gdk_device_set_associated_device (broadway_display->keyboard, broadway_display->core_keyboard);
_gdk_device_set_associated_device (broadway_display->touchscreen, broadway_display->core_pointer);
_gdk_device_add_physical_device (broadway_display->core_pointer, broadway_display->touchscreen);
_gdk_device_add_slave (broadway_display->core_pointer, broadway_display->touchscreen);
seat = gdk_seat_default_new_for_logical_pair (broadway_display->core_pointer,
broadway_display->core_keyboard);
seat = gdk_seat_default_new_for_master_pair (broadway_display->core_pointer,
broadway_display->core_keyboard);
gdk_display_add_seat (display, seat);
gdk_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), broadway_display->pointer);
gdk_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), broadway_display->keyboard);
gdk_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), broadway_display->touchscreen);
gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), broadway_display->pointer);
gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), broadway_display->keyboard);
gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), broadway_display->touchscreen);
g_object_unref (seat);
gdk_event_init (display);

View File

@@ -1107,12 +1107,13 @@ create_moveresize_surface (MoveResizeData *mv_resize,
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
status = gdk_device_grab (pointer,
mv_resize->moveresize_emulation_surface,
FALSE,
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK,
NULL,
timestamp);
mv_resize->moveresize_emulation_surface,
GDK_OWNERSHIP_APPLICATION,
FALSE,
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK,
NULL,
timestamp);
G_GNUC_END_IGNORE_DEPRECATIONS;
if (status != GDK_GRAB_SUCCESS)

View File

@@ -40,15 +40,4 @@ void gdk_surface_set_widget (GdkSurface *surface,
gpointer widget);
gpointer gdk_surface_get_widget (GdkSurface *surface);
typedef struct
{
const char *key;
guint value;
const char *help;
} GdkDebugKey;
guint gdk_parse_debug_var (const char *variable,
const GdkDebugKey *keys,
guint nkeys);
#endif /* __GDK__PRIVATE_H__ */

146
gdk/gdk.c
View File

@@ -42,8 +42,6 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <fribidi.h>
@@ -130,28 +128,28 @@ static int gdk_initialized = 0; /* 1 if the library is initi
*/
#ifdef G_ENABLE_DEBUG
static const GdkDebugKey gdk_debug_keys[] = {
{ "misc", GDK_DEBUG_MISC, "Miscellaneous information" },
{ "events", GDK_DEBUG_EVENTS, "Information about events" },
{ "dnd", GDK_DEBUG_DND, "Information about Drag-and-Drop" },
{ "input", GDK_DEBUG_INPUT, "Information about input (Windows)" },
{ "eventloop", GDK_DEBUG_EVENTLOOP, "Information about event loop operation (Quartz)" },
{ "frames", GDK_DEBUG_FRAMES, "Information about the frame clock" },
{ "settings", GDK_DEBUG_SETTINGS, "Information about xsettings" },
{ "opengl", GDK_DEBUG_OPENGL, "Information about OpenGL" },
{ "vulkan", GDK_DEBUG_VULKAN, "Information about Vulkan" },
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)" },
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support" },
{ "gl-software", GDK_DEBUG_GL_SOFTWARE, "Force OpenGL software rendering" },
{ "gl-texture-rect", GDK_DEBUG_GL_TEXTURE_RECT, "Use OpenGL texture rectangle extension" },
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context" },
{ "gl-gles", GDK_DEBUG_GL_GLES, "Use a GLES OpenGL context" },
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL" },
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support" },
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings" },
static const GDebugKey gdk_debug_keys[] = {
{ "misc", GDK_DEBUG_MISC },
{ "events", GDK_DEBUG_EVENTS },
{ "dnd", GDK_DEBUG_DND },
{ "input", GDK_DEBUG_INPUT },
{ "eventloop", GDK_DEBUG_EVENTLOOP },
{ "frames", GDK_DEBUG_FRAMES },
{ "settings", GDK_DEBUG_SETTINGS },
{ "opengl", GDK_DEBUG_OPENGL },
{ "vulkan", GDK_DEBUG_VULKAN },
{ "selection", GDK_DEBUG_SELECTION },
{ "clipboard", GDK_DEBUG_CLIPBOARD },
{ "nograbs", GDK_DEBUG_NOGRABS },
{ "gl-disable", GDK_DEBUG_GL_DISABLE },
{ "gl-software", GDK_DEBUG_GL_SOFTWARE },
{ "gl-texture-rect", GDK_DEBUG_GL_TEXTURE_RECT },
{ "gl-legacy", GDK_DEBUG_GL_LEGACY },
{ "gl-gles", GDK_DEBUG_GL_GLES },
{ "gl-debug", GDK_DEBUG_GL_DEBUG },
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE },
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE },
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS },
};
#endif
@@ -201,93 +199,6 @@ gdk_ensure_resources (void)
g_once (&register_resources_once, register_resources, NULL);
}
guint
gdk_parse_debug_var (const char *variable,
const GdkDebugKey *keys,
guint nkeys)
{
guint i;
guint result = 0;
const char *string;
const gchar *p;
const gchar *q;
gboolean invert;
gboolean help;
string = g_getenv (variable);
if (string == NULL)
return 0;
p = string;
invert = FALSE;
help = FALSE;
while (*p)
{
q = strpbrk (p, ":;, \t");
if (!q)
q = p + strlen (p);
if (3 == q - p && g_ascii_strncasecmp ("all", p, q - p) == 0)
{
invert = TRUE;
}
else if (4 == q - p && g_ascii_strncasecmp ("help", p, q - p) == 0)
{
help = TRUE;
}
else
{
for (i = 0; i < nkeys; i++)
{
if (strlen (keys[i].key) == q - p &&
g_ascii_strncasecmp (keys[i].key, p, q - p) == 0)
{
result |= keys[i].value;
break;
}
}
if (i == nkeys)
{
char *val = g_strndup (p, q - p);
fprintf (stderr, "Unrecognized value \"%s\". Try %s=help\n", val, variable);
g_free (val);
}
}
p = q;
if (*p)
p++;
}
if (help)
{
int max_width = 4;
for (i = 0; i < nkeys; i++)
max_width = MAX (max_width, strlen (keys[i].key));
max_width += 4;
fprintf (stderr, "Supported %s values:\n", variable);
for (i = 0; i < nkeys; i++)
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values");
fprintf (stderr, " %s%*s%s\n", "help", max_width - 4, " ", "Print this help");
fprintf (stderr, "\nMultiple values can be given, separated by : or space.\n");
}
if (invert)
{
guint all_flags = 0;
for (i = 0; i < nkeys; i++)
all_flags |= keys[i].value;
result = all_flags & (~result);
}
return result;
}
void
gdk_pre_parse (void)
{
@@ -296,12 +207,13 @@ gdk_pre_parse (void)
gdk_ensure_resources ();
#ifdef G_ENABLE_DEBUG
_gdk_debug_flags = gdk_parse_debug_var ("GDK_DEBUG",
gdk_debug_keys,
G_N_ELEMENTS (gdk_debug_keys));
#else
if (g_getenv ("GDK_DEBUG"))
g_warning ("GDK_DEBUG set but ignored because GTK isn't built with G_ENABLE_DEBUG");
{
gchar *debug_string = getenv("GDK_DEBUG");
if (debug_string != NULL)
_gdk_debug_flags = g_parse_debug_string (debug_string,
(GDebugKey *) gdk_debug_keys,
G_N_ELEMENTS (gdk_debug_keys));
}
#endif /* G_ENABLE_DEBUG */
if (g_getenv ("GTK_TRACE_FD"))

View File

@@ -1290,7 +1290,7 @@ gdk_clipboard_set_valist (GdkClipboard *clipboard,
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
/* we purposely leak the value here, it might not be
* in a sane state if an error condition occurred
* in a sane state if an error condition occoured
*/
return;
}

View File

@@ -156,7 +156,7 @@ gdk_content_provider_new_typed (GType type,
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
/* we purposely leak the value here, it might not be
* in a sane state if an error condition occurred
* in a sane state if an error condition occoured
*/
}
va_end (args);

View File

@@ -36,7 +36,7 @@
* as a keyboard, a mouse, a touchpad, etc.
*
* See the #GdkSeat documentation for more information
* about the various kinds of logical and physical devices, and their
* about the various kinds of master and slave devices, and their
* relationships.
*/
@@ -51,7 +51,9 @@ typedef struct _GdkAxisInfo GdkAxisInfo;
struct _GdkAxisInfo
{
char *label;
GdkAxisUse use;
gdouble min_axis;
gdouble max_axis;
gdouble min_value;
@@ -152,16 +154,15 @@ gdk_device_class_init (GdkDeviceClass *klass)
P_("Device type"),
P_("Device role in the device manager"),
GDK_TYPE_DEVICE_TYPE,
GDK_DEVICE_TYPE_LOGICAL,
GDK_DEVICE_TYPE_MASTER,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:associated-device:
*
* Associated pointer or keyboard with this device, if any. Devices of
* type #GDK_DEVICE_TYPE_LOGICAL always come in keyboard/pointer pairs.
* Other device types will have a %NULL associated device.
* Associated pointer or keyboard with this device, if any. Devices of type #GDK_DEVICE_TYPE_MASTER
* always come in keyboard/pointer pairs. Other device types will have a %NULL associated device.
*/
device_props[PROP_ASSOCIATED_DEVICE] =
g_param_spec_object ("associated-device",
@@ -188,7 +189,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
* GdkDevice:has-cursor:
*
* Whether the device is represented by a cursor on the screen. Devices of type
* %GDK_DEVICE_TYPE_LOGICAL will have %TRUE here.
* %GDK_DEVICE_TYPE_MASTER will have %TRUE here.
*/
device_props[PROP_HAS_CURSOR] =
g_param_spec_boolean ("has-cursor",
@@ -334,11 +335,11 @@ gdk_device_class_init (GdkDeviceClass *klass)
*
* The ::changed signal is emitted either when the #GdkDevice
* has changed the number of either axes or keys. For example
* on X11 this will normally happen when the physical device
* routing events through the logical device changes (for
* example, user switches from the USB mouse to a tablet); in
* that case the logical device will change to reflect the axes
* and keys on the new physical device.
* In X this will normally happen when the slave device routing
* events through the master device changes (for example, user
* switches from the USB mouse to a tablet), in that case the
* master device will change to reflect the new slave device
* axes and keys.
*/
signals[CHANGED] =
g_signal_new (g_intern_static_string ("changed"),
@@ -365,10 +366,19 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_TYPE_NONE, 1, GDK_TYPE_DEVICE_TOOL);
}
static void
gdk_device_axis_info_clear (gpointer data)
{
GdkAxisInfo *info = data;
g_free (info->label);
}
static void
gdk_device_init (GdkDevice *device)
{
device->axes = g_array_new (FALSE, TRUE, sizeof (GdkAxisInfo));
g_array_set_clear_func (device->axes, gdk_device_axis_info_clear);
}
static void
@@ -383,6 +393,7 @@ gdk_device_finalize (GObject *object)
}
g_clear_pointer (&device->name, g_free);
g_clear_pointer (&device->keys, g_free);
g_clear_pointer (&device->vendor_id, g_free);
g_clear_pointer (&device->product_id, g_free);
@@ -395,14 +406,14 @@ gdk_device_dispose (GObject *object)
GdkDevice *device = GDK_DEVICE (object);
GdkDevice *associated = device->associated;
if (associated && device->type == GDK_DEVICE_TYPE_PHYSICAL)
_gdk_device_remove_physical_device (associated, device);
if (associated && device->type == GDK_DEVICE_TYPE_SLAVE)
_gdk_device_remove_slave (associated, device);
if (associated)
{
device->associated = NULL;
if (device->type == GDK_DEVICE_TYPE_LOGICAL &&
if (device->type == GDK_DEVICE_TYPE_MASTER &&
associated->associated == device)
_gdk_device_set_associated_device (associated, NULL);
@@ -540,23 +551,21 @@ gdk_device_get_property (GObject *object,
* the axes of @device in, or %NULL.
* @mask: (optional) (out): location to store the modifiers, or %NULL.
*
* Gets the current state of a pointer device relative to @surface. As a
* physical devices coordinates are those of its logical pointer, this
* function may not be called on devices of type %GDK_DEVICE_TYPE_PHYSICAL,
* unless there is an ongoing grab on them.
*
* See also: gdk_seat_grab().
* Gets the current state of a pointer device relative to @surface. As a slave
* devices coordinates are those of its master pointer, this
* function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
* unless there is an ongoing grab on them. See gdk_seat_grab().
*/
void
gdk_device_get_state (GdkDevice *device,
GdkSurface *surface,
GdkSurface *surface,
gdouble *axes,
GdkModifierType *mask)
{
g_return_if_fail (GDK_IS_DEVICE (device));
g_return_if_fail (device->source != GDK_SOURCE_KEYBOARD);
g_return_if_fail (GDK_IS_SURFACE (surface));
g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_PHYSICAL ||
g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE ||
gdk_display_device_is_grabbed (gdk_device_get_display (device), device));
if (GDK_DEVICE_GET_CLASS (device)->get_state)
@@ -578,7 +587,7 @@ gdk_device_get_position (GdkDevice *device,
{
g_return_if_fail (GDK_IS_DEVICE (device));
g_return_if_fail (device->source != GDK_SOURCE_KEYBOARD);
g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_PHYSICAL ||
g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE ||
gdk_display_device_is_grabbed (gdk_device_get_display (device), device));
_gdk_device_query_state (device, NULL, NULL, x, y, NULL);
@@ -596,8 +605,8 @@ gdk_device_get_position (GdkDevice *device,
* double precision. Returns %NULL if the surface tree under @device is not known to GDK (for example,
* belongs to another application).
*
* As a physical device coordinates are those of its logical pointer, this
* function may not be called on devices of type %GDK_DEVICE_TYPE_PHYSICAL,
* As a slave device coordinates are those of its master pointer, This
* function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
* unless there is an ongoing grab on them, see gdk_seat_grab().
*
* Returns: (nullable) (transfer none): the #GdkSurface under the
@@ -613,7 +622,7 @@ gdk_device_get_surface_at_position (GdkDevice *device,
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
g_return_val_if_fail (device->source != GDK_SOURCE_KEYBOARD, NULL);
g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_PHYSICAL ||
g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE ||
gdk_display_device_is_grabbed (gdk_device_get_display (device), device), NULL);
surface = _gdk_device_surface_at_position (device, &tmp_x, &tmp_y, NULL);
@@ -675,6 +684,79 @@ gdk_device_get_source (GdkDevice *device)
return device->source;
}
/**
* gdk_device_get_n_keys:
* @device: a #GdkDevice
*
* Returns the number of keys the device currently has.
*
* Returns: the number of keys.
**/
gint
gdk_device_get_n_keys (GdkDevice *device)
{
g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
return device->num_keys;
}
/**
* gdk_device_get_key:
* @device: a #GdkDevice.
* @index_: the index of the macro button to get.
* @keyval: (out): return value for the keyval.
* @modifiers: (out): return value for modifiers.
*
* If @index_ has a valid keyval, this function will return %TRUE
* and fill in @keyval and @modifiers with the keyval settings.
*
* Returns: %TRUE if keyval is set for @index.
**/
gboolean
gdk_device_get_key (GdkDevice *device,
guint index_,
guint *keyval,
GdkModifierType *modifiers)
{
g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
g_return_val_if_fail (index_ < device->num_keys, FALSE);
if (!device->keys[index_].keyval &&
!device->keys[index_].modifiers)
return FALSE;
if (keyval)
*keyval = device->keys[index_].keyval;
if (modifiers)
*modifiers = device->keys[index_].modifiers;
return TRUE;
}
/**
* gdk_device_set_key:
* @device: a #GdkDevice
* @index_: the index of the macro button to set
* @keyval: the keyval to generate
* @modifiers: the modifiers to set
*
* Specifies the X key event to generate when a macro button of a device
* is pressed.
**/
void
gdk_device_set_key (GdkDevice *device,
guint index_,
guint keyval,
GdkModifierType modifiers)
{
g_return_if_fail (GDK_IS_DEVICE (device));
g_return_if_fail (index_ < device->num_keys);
device->keys[index_].keyval = keyval;
device->keys[index_].modifiers = modifiers;
}
/**
* gdk_device_get_axis_use:
* @device: a pointer #GdkDevice.
@@ -699,6 +781,47 @@ gdk_device_get_axis_use (GdkDevice *device,
return info->use;
}
/**
* gdk_device_set_axis_use:
* @device: a pointer #GdkDevice
* @index_: the index of the axis
* @use: specifies how the axis is used
*
* Specifies how an axis of a device is used.
**/
void
gdk_device_set_axis_use (GdkDevice *device,
guint index_,
GdkAxisUse use)
{
GdkAxisInfo *info;
g_return_if_fail (GDK_IS_DEVICE (device));
g_return_if_fail (device->source != GDK_SOURCE_KEYBOARD);
g_return_if_fail (index_ < device->axes->len);
info = &g_array_index (device->axes, GdkAxisInfo, index_);
info->use = use;
switch ((guint) use)
{
case GDK_AXIS_X:
case GDK_AXIS_Y:
info->min_axis = 0;
info->max_axis = 0;
break;
case GDK_AXIS_XTILT:
case GDK_AXIS_YTILT:
info->min_axis = -1;
info->max_axis = 1;
break;
default:
info->min_axis = 0;
info->max_axis = 1;
break;
}
}
/**
* gdk_device_get_display:
* @device: a #GdkDevice
@@ -720,14 +843,15 @@ gdk_device_get_display (GdkDevice *device)
* gdk_device_get_associated_device:
* @device: a #GdkDevice
*
* Returns the #GdkDevice associated to @device:
* Returns the associated device to @device, if @device is of type
* %GDK_DEVICE_TYPE_MASTER, it will return the paired pointer or
* keyboard.
*
* - if @device is of type %GDK_DEVICE_TYPE_LOGICAL, it will return
* the paired pointer or keyboard.
* - if @device is of type %GDK_DEVICE_TYPE_PHYSICAL, it will return
* the logical device to which @device is attached to.
* - if @device is of type %GDK_DEVICE_TYPE_FLOATING, %NULL will be
* returned, as there is no associated device.
* If @device is of type %GDK_DEVICE_TYPE_SLAVE, it will return
* the master device to which @device is attached to.
*
* If @device is of type %GDK_DEVICE_TYPE_FLOATING, %NULL will be
* returned, as there is no associated device.
*
* Returns: (nullable) (transfer none): The associated device, or
* %NULL
@@ -771,59 +895,63 @@ _gdk_device_set_associated_device (GdkDevice *device,
if (associated)
device->associated = g_object_ref (associated);
if (device->type != GDK_DEVICE_TYPE_LOGICAL)
if (device->type != GDK_DEVICE_TYPE_MASTER)
{
if (device->associated)
_gdk_device_set_device_type (device, GDK_DEVICE_TYPE_PHYSICAL);
_gdk_device_set_device_type (device, GDK_DEVICE_TYPE_SLAVE);
else
_gdk_device_set_device_type (device, GDK_DEVICE_TYPE_FLOATING);
}
}
/**
* gdk_device_list_physical_devices:
* @device: a logical #GdkDevice
* gdk_device_list_slave_devices:
* @device: a #GdkDevice
*
* Returns the list of physical devices attached to the given logical
* #GdkDevice.
* If the device if of type %GDK_DEVICE_TYPE_MASTER, it will return
* the list of slave devices attached to it, otherwise it will return
* %NULL
*
* Returns: (nullable) (transfer container) (element-type GdkDevice):
* the list of physical devices attached to a logical #GdkDevice
*/
* the list of slave devices, or %NULL. The list must be
* freed with g_list_free(), the contents of the list are
* owned by GTK+ and should not be freed.
**/
GList *
gdk_device_list_physical_devices (GdkDevice *device)
gdk_device_list_slave_devices (GdkDevice *device)
{
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
g_return_val_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_LOGICAL, NULL);
g_return_val_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER, NULL);
return g_list_copy (device->physical_devices);
return g_list_copy (device->slaves);
}
void
_gdk_device_add_physical_device (GdkDevice *device,
GdkDevice *physical)
_gdk_device_add_slave (GdkDevice *device,
GdkDevice *slave)
{
g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_LOGICAL);
g_return_if_fail (gdk_device_get_device_type (physical) != GDK_DEVICE_TYPE_LOGICAL);
g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER);
g_return_if_fail (gdk_device_get_device_type (slave) != GDK_DEVICE_TYPE_MASTER);
if (!g_list_find (device->physical_devices, physical))
device->physical_devices = g_list_prepend (device->physical_devices, physical);
if (!g_list_find (device->slaves, slave))
device->slaves = g_list_prepend (device->slaves, slave);
}
void
_gdk_device_remove_physical_device (GdkDevice *device,
GdkDevice *physical)
_gdk_device_remove_slave (GdkDevice *device,
GdkDevice *slave)
{
GList *elem;
g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_LOGICAL);
g_return_if_fail (gdk_device_get_device_type (physical) != GDK_DEVICE_TYPE_LOGICAL);
g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER);
g_return_if_fail (gdk_device_get_device_type (slave) != GDK_DEVICE_TYPE_MASTER);
elem = g_list_find (device->physical_devices, physical);
if (elem == NULL)
elem = g_list_find (device->slaves, slave);
if (!elem)
return;
device->physical_devices = g_list_delete_link (device->physical_devices, elem);
device->slaves = g_list_delete_link (device->slaves, elem);
}
/**
@@ -837,7 +965,7 @@ _gdk_device_remove_physical_device (GdkDevice *device,
GdkDeviceType
gdk_device_get_device_type (GdkDevice *device)
{
g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_DEVICE_TYPE_LOGICAL);
g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_DEVICE_TYPE_MASTER);
return device->type;
}
@@ -859,6 +987,89 @@ gdk_device_get_n_axes (GdkDevice *device)
return device->axes->len;
}
/**
* gdk_device_get_axis_names:
* @device: a #GdkDevice
*
* Returns a null-terminated array of strings, containing the labels for
* the axes that @device currently has.
* If the device has no axes, %NULL is returned.
*
* Returns: (nullable) (transfer full): A null-terminated string array,
* free with g_strfreev().
**/
char **
gdk_device_get_axis_names (GdkDevice *device)
{
GPtrArray *axes;
gint i;
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
g_return_val_if_fail (device->source != GDK_SOURCE_KEYBOARD, NULL);
if (device->axes->len == 0)
return NULL;
axes = g_ptr_array_new ();
for (i = 0; i < device->axes->len; i++)
{
GdkAxisInfo axis_info;
axis_info = g_array_index (device->axes, GdkAxisInfo, i);
g_ptr_array_add (axes, g_strdup (axis_info.label));
}
g_ptr_array_add (axes, NULL);
return (char **) g_ptr_array_free (axes, FALSE);
}
/**
* gdk_device_get_axis_value: (skip)
* @device: a pointer #GdkDevice.
* @axes: (array): pointer to an array of axes
* @axis_label: name of the label
* @value: (out): location to store the found value.
*
* Interprets an array of double as axis values for a given device,
* and locates the value in the array for a given axis label, as returned
* by gdk_device_get_axes()
*
* Returns: %TRUE if the given axis use was found, otherwise %FALSE.
**/
gboolean
gdk_device_get_axis_value (GdkDevice *device,
gdouble *axes,
const char *axis_label,
gdouble *value)
{
gint i;
g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
g_return_val_if_fail (device->source != GDK_SOURCE_KEYBOARD, FALSE);
if (axes == NULL)
return FALSE;
for (i = 0; i < device->axes->len; i++)
{
GdkAxisInfo axis_info;
axis_info = g_array_index (device->axes, GdkAxisInfo, i);
if (!g_str_equal (axis_info.label, axis_label))
continue;
if (value)
*value = axes[i];
return TRUE;
}
return FALSE;
}
/**
* gdk_device_get_axis: (skip)
* @device: a #GdkDevice
@@ -924,6 +1135,7 @@ get_native_grab_event_mask (GdkEventMask grab_mask)
GdkGrabStatus
gdk_device_grab (GdkDevice *device,
GdkSurface *surface,
GdkGrabOwnership grab_ownership,
gboolean owner_events,
GdkEventMask event_mask,
GdkCursor *cursor,
@@ -957,6 +1169,7 @@ gdk_device_grab (GdkDevice *device,
_gdk_display_add_device_grab (display,
device,
surface,
grab_ownership,
owner_events,
event_mask,
serial,
@@ -993,6 +1206,7 @@ _gdk_device_reset_axes (GdkDevice *device)
guint
_gdk_device_add_axis (GdkDevice *device,
const char *label_name,
GdkAxisUse use,
gdouble min_value,
gdouble max_value,
@@ -1002,6 +1216,7 @@ _gdk_device_add_axis (GdkDevice *device,
guint pos;
axis_info.use = use;
axis_info.label = g_strdup (label_name);
axis_info.min_value = min_value;
axis_info.max_value = max_value;
axis_info.resolution = resolution;
@@ -1037,11 +1252,12 @@ _gdk_device_add_axis (GdkDevice *device,
void
_gdk_device_get_axis_info (GdkDevice *device,
guint index_,
GdkAxisUse *use,
gdouble *min_value,
gdouble *max_value,
gdouble *resolution)
guint index_,
const char **label_name,
GdkAxisUse *use,
gdouble *min_value,
gdouble *max_value,
gdouble *resolution)
{
GdkAxisInfo *info;
@@ -1050,12 +1266,23 @@ _gdk_device_get_axis_info (GdkDevice *device,
info = &g_array_index (device->axes, GdkAxisInfo, index_);
*label_name = info->label;
*use = info->use;
*min_value = info->min_value;
*max_value = info->max_value;
*resolution = info->resolution;
}
void
_gdk_device_set_keys (GdkDevice *device,
guint num_keys)
{
g_free (device->keys);
device->num_keys = num_keys;
device->keys = g_new0 (GdkDeviceKey, num_keys);
}
static GdkAxisInfo *
find_axis_info (GArray *array,
GdkAxisUse use)
@@ -1076,10 +1303,10 @@ find_axis_info (GArray *array,
gboolean
_gdk_device_translate_surface_coord (GdkDevice *device,
GdkSurface *surface,
guint index_,
gdouble value,
gdouble *axis_value)
GdkSurface *surface,
guint index_,
gdouble value,
gdouble *axis_value)
{
GdkAxisInfo axis_info;
GdkAxisInfo *axis_info_x, *axis_info_y;
@@ -1282,9 +1509,36 @@ _gdk_device_surface_at_position (GdkDevice *device,
mask);
}
/**
* gdk_device_get_last_event_surface:
* @device: a #GdkDevice, with a source other than %GDK_SOURCE_KEYBOARD
*
* Gets information about which surface the given pointer device is in, based on events
* that have been received so far from the display server. If another application
* has a pointer grab, or this application has a grab with owner_events = %FALSE,
* %NULL may be returned even if the pointer is physically over one of this
* application's surfaces.
*
* Returns: (transfer none) (allow-none): the last surface the device
*/
GdkSurface *
gdk_device_get_last_event_surface (GdkDevice *device)
{
GdkDisplay *display;
GdkPointerSurfaceInfo *info;
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
g_return_val_if_fail (device->source != GDK_SOURCE_KEYBOARD, NULL);
display = gdk_device_get_display (device);
info = _gdk_display_get_pointer_info (display, device);
return info->surface_under_pointer;
}
/**
* gdk_device_get_vendor_id:
* @device: a physical #GdkDevice
* @device: a slave #GdkDevice
*
* Returns the vendor ID of this device, or %NULL if this information couldn't
* be obtained. This ID is retrieved from the device, and is thus constant for
@@ -1319,14 +1573,14 @@ const gchar *
gdk_device_get_vendor_id (GdkDevice *device)
{
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_LOGICAL, NULL);
g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER, NULL);
return device->vendor_id;
}
/**
* gdk_device_get_product_id:
* @device: a physical #GdkDevice
* @device: a slave #GdkDevice
*
* Returns the product ID of this device, or %NULL if this information couldn't
* be obtained. This ID is retrieved from the device, and is thus constant for
@@ -1338,7 +1592,7 @@ const gchar *
gdk_device_get_product_id (GdkDevice *device)
{
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_LOGICAL, NULL);
g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER, NULL);
return device->product_id;
}
@@ -1393,7 +1647,7 @@ gdk_device_update_tool (GdkDevice *device,
GdkDeviceTool *tool)
{
g_return_if_fail (GDK_IS_DEVICE (device));
g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_LOGICAL);
g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER);
if (g_set_object (&device->last_tool, tool))
{

View File

@@ -40,15 +40,19 @@ typedef struct _GdkTimeCoord GdkTimeCoord;
* @GDK_SOURCE_MOUSE: the device is a mouse. (This will be reported for the core
* pointer, even if it is something else, such as a trackball.)
* @GDK_SOURCE_PEN: the device is a stylus of a graphics tablet or similar device.
* @GDK_SOURCE_ERASER: the device is an eraser. Typically, this would be the other end
* of a stylus on a graphics tablet.
* @GDK_SOURCE_CURSOR: the device is a graphics tablet “puck” or similar device.
* @GDK_SOURCE_KEYBOARD: the device is a keyboard.
* @GDK_SOURCE_TOUCHSCREEN: the device is a direct-input touch device, such
* as a touchscreen or tablet
* as a touchscreen or tablet. This device type has been added in 3.4.
* @GDK_SOURCE_TOUCHPAD: the device is an indirect touch device, such
* as a touchpad
* @GDK_SOURCE_TRACKPOINT: the device is a trackpoint
* as a touchpad. This device type has been added in 3.4.
* @GDK_SOURCE_TRACKPOINT: the device is a trackpoint. This device type has been
* added in 3.22
* @GDK_SOURCE_TABLET_PAD: the device is a "pad", a collection of buttons,
* rings and strips found in drawing tablets
* rings and strips found in drawing tablets. This device type has been
* added in 3.22.
*
* An enumeration describing the type of an input device in general terms.
*/
@@ -56,6 +60,7 @@ typedef enum
{
GDK_SOURCE_MOUSE,
GDK_SOURCE_PEN,
GDK_SOURCE_ERASER,
GDK_SOURCE_CURSOR,
GDK_SOURCE_KEYBOARD,
GDK_SOURCE_TOUCHSCREEN,
@@ -66,34 +71,36 @@ typedef enum
/**
* GdkDeviceType:
* @GDK_DEVICE_TYPE_LOGICAL: Device is a logical device. There will
* be an associated focus indicator on the screen.
* @GDK_DEVICE_TYPE_PHYSICAL: Device is a physical device.
* @GDK_DEVICE_TYPE_FLOATING: Device is a physical device, currently
* not attached to any seat.
* @GDK_DEVICE_TYPE_MASTER: Device is a master (or virtual) device. There will
* be an associated focus indicator on the screen.
* @GDK_DEVICE_TYPE_SLAVE: Device is a slave (or physical) device.
* @GDK_DEVICE_TYPE_FLOATING: Device is a physical device, currently not attached to
* any seat.
*
* Indicates the device type.
*/
typedef enum {
GDK_DEVICE_TYPE_LOGICAL,
GDK_DEVICE_TYPE_PHYSICAL,
GDK_DEVICE_TYPE_MASTER,
GDK_DEVICE_TYPE_SLAVE,
GDK_DEVICE_TYPE_FLOATING
} GdkDeviceType;
/* We don't allocate each coordinate this big, but we use it to
* be ANSI compliant and avoid accessing past the defined limits.
*/
#define GDK_MAX_TIMECOORD_AXES 128
/**
* GdkTimeCoord:
* @time: The timestamp for this event.
* @flags: Flags indicating what axes are present
* @axes: axis values
* @axes: the values of the devices axes.
*
* A #GdkTimeCoord stores a single event in a motion history.
*/
struct _GdkTimeCoord
{
guint32 time;
GdkAxisFlags flags;
double axes[GDK_AXIS_LAST];
gdouble axes[GDK_MAX_TIMECOORD_AXES];
};
GDK_AVAILABLE_IN_ALL
@@ -108,9 +115,26 @@ gboolean gdk_device_get_has_cursor (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
GdkInputSource gdk_device_get_source (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
gint gdk_device_get_n_keys (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
gboolean gdk_device_get_key (GdkDevice *device,
guint index_,
guint *keyval,
GdkModifierType *modifiers);
GDK_AVAILABLE_IN_ALL
void gdk_device_set_key (GdkDevice *device,
guint index_,
guint keyval,
GdkModifierType modifiers);
GDK_AVAILABLE_IN_ALL
GdkAxisUse gdk_device_get_axis_use (GdkDevice *device,
guint index_);
GDK_AVAILABLE_IN_ALL
void gdk_device_set_axis_use (GdkDevice *device,
guint index_,
GdkAxisUse use);
GDK_AVAILABLE_IN_ALL
@@ -125,6 +149,14 @@ GdkSurface * gdk_device_get_surface_at_position (GdkDevice *device,
GDK_AVAILABLE_IN_ALL
gint gdk_device_get_n_axes (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
char ** gdk_device_get_axis_names (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
gboolean gdk_device_get_axis_value (GdkDevice *device,
gdouble *axes,
const char *axis_label,
gdouble *value);
GDK_AVAILABLE_IN_ALL
gboolean gdk_device_get_axis (GdkDevice *device,
gdouble *axes,
@@ -136,11 +168,14 @@ GdkDisplay * gdk_device_get_display (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
GdkDevice * gdk_device_get_associated_device (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
GList * gdk_device_list_physical_devices (GdkDevice *device);
GList * gdk_device_list_slave_devices (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
GdkDeviceType gdk_device_get_device_type (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
GdkSurface *gdk_device_get_last_event_surface (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
const gchar *gdk_device_get_vendor_id (GdkDevice *device);
GDK_AVAILABLE_IN_ALL

View File

@@ -31,6 +31,13 @@ G_BEGIN_DECLS
#define GDK_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE, GdkDeviceClass))
typedef struct _GdkDeviceClass GdkDeviceClass;
typedef struct _GdkDeviceKey GdkDeviceKey;
struct _GdkDeviceKey
{
guint keyval;
GdkModifierType modifiers;
};
struct _GdkDevice
{
@@ -39,13 +46,15 @@ struct _GdkDevice
gchar *name;
GdkInputSource source;
gboolean has_cursor;
gint num_keys;
GdkAxisFlags axis_flags;
GdkDeviceKey *keys;
GdkDisplay *display;
/* The paired logical device for logical devices,
* or the associated logical device for physical ones
/* Paired master for master,
* associated master for slaves
*/
GdkDevice *associated;
GList *physical_devices;
GList *slaves;
GdkDeviceType type;
GArray *axes;
guint num_touches;
@@ -97,16 +106,21 @@ void _gdk_device_set_associated_device (GdkDevice *device,
void _gdk_device_reset_axes (GdkDevice *device);
guint _gdk_device_add_axis (GdkDevice *device,
const char *label_atom,
GdkAxisUse use,
gdouble min_value,
gdouble max_value,
gdouble resolution);
void _gdk_device_get_axis_info (GdkDevice *device,
guint index,
GdkAxisUse *use,
gdouble *min_value,
gdouble *max_value,
gdouble *resolution);
guint index,
const char**label_atom,
GdkAxisUse *use,
gdouble *min_value,
gdouble *max_value,
gdouble *resolution);
void _gdk_device_set_keys (GdkDevice *device,
guint num_keys);
gboolean _gdk_device_translate_surface_coord (GdkDevice *device,
GdkSurface *surface,
@@ -132,11 +146,10 @@ gboolean _gdk_device_translate_axis (GdkDevice *device,
GdkTimeCoord ** _gdk_device_allocate_history (GdkDevice *device,
gint n_events);
void _gdk_device_add_physical_device (GdkDevice *device,
GdkDevice *physical);
void _gdk_device_remove_physical_device (GdkDevice *device,
GdkDevice *physical);
void _gdk_device_add_slave (GdkDevice *device,
GdkDevice *slave);
void _gdk_device_remove_slave (GdkDevice *device,
GdkDevice *slave);
void _gdk_device_query_state (GdkDevice *device,
GdkSurface *surface,
GdkSurface **child_surface,

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