Compare commits
56 Commits
async-dial
...
popovers
Author | SHA1 | Date | |
---|---|---|---|
|
9271fa8bc7 | ||
|
d8fa2b3d03 | ||
|
d8aa468eec | ||
|
7378331a19 | ||
|
8375987cce | ||
|
671875dd6e | ||
|
908bae6e2d | ||
|
9ee8e02d42 | ||
|
7cf6174709 | ||
|
000cd7d8c5 | ||
|
426acda929 | ||
|
0d36d5bee1 | ||
|
96e35b1dc3 | ||
|
beeb4e1436 | ||
|
d2cbbd84f8 | ||
|
f7824bdc51 | ||
|
6961a64fbd | ||
|
12f0603857 | ||
|
52fe7ca9bd | ||
|
7a4655c875 | ||
|
fe9cfbe1d9 | ||
|
2eae9dea7c | ||
|
d4e367756d | ||
|
c5611872ab | ||
|
922b36e420 | ||
|
8e6fa0313b | ||
|
8b9efb612f | ||
|
e67116dbb6 | ||
|
b3ec18dda9 | ||
|
4aa457fcc9 | ||
|
86c3c2c323 | ||
|
0db0eb77a0 | ||
|
f4dc912b7e | ||
|
771c6152cc | ||
|
7a5199b11a | ||
|
32e49cc101 | ||
|
e6667092d5 | ||
|
e02a3d1dd8 | ||
|
e6dd8c9ca9 | ||
|
40557bf64d | ||
|
bb3e912b59 | ||
|
8a4f597379 | ||
|
3ce119c47f | ||
|
3132921942 | ||
|
fe288b426e | ||
|
a4c306deb4 | ||
|
2bfab05858 | ||
|
173e5b5df0 | ||
|
a171b0e3d3 | ||
|
96cec1b630 | ||
|
ac1a647c93 | ||
|
5bb749c662 | ||
|
3ad4f3dec5 | ||
|
5028e55ee8 | ||
|
706afc07ac | ||
|
3b86dec4dc |
@@ -41,6 +41,7 @@ demos = \
|
|||||||
panes.c \
|
panes.c \
|
||||||
pickers.c \
|
pickers.c \
|
||||||
pixbufs.c \
|
pixbufs.c \
|
||||||
|
popover.c \
|
||||||
printing.c \
|
printing.c \
|
||||||
revealer.c \
|
revealer.c \
|
||||||
rotated_text.c \
|
rotated_text.c \
|
||||||
|
@@ -110,6 +110,7 @@
|
|||||||
<file>panes.c</file>
|
<file>panes.c</file>
|
||||||
<file>pickers.c</file>
|
<file>pickers.c</file>
|
||||||
<file>pixbufs.c</file>
|
<file>pixbufs.c</file>
|
||||||
|
<file>popover.c</file>
|
||||||
<file>printing.c</file>
|
<file>printing.c</file>
|
||||||
<file>revealer.c</file>
|
<file>revealer.c</file>
|
||||||
<file>rotated_text.c</file>
|
<file>rotated_text.c</file>
|
||||||
@@ -133,4 +134,7 @@
|
|||||||
<file>messages.txt</file>
|
<file>messages.txt</file>
|
||||||
<file>apple-red.png</file>
|
<file>apple-red.png</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
|
<gresource prefix="/popover">
|
||||||
|
<file>popover.ui</file>
|
||||||
|
</gresource>
|
||||||
</gresources>
|
</gresources>
|
||||||
|
185
demos/gtk-demo/popover.c
Normal file
185
demos/gtk-demo/popover.c
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
/* Popovers
|
||||||
|
*
|
||||||
|
* A bubble-like window containing contextual information or options.
|
||||||
|
* GtkPopovers can be attached to any widget, and will be displayed
|
||||||
|
* within the same window, but on top of all its content.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
toggle_changed_cb (GtkToggleButton *button,
|
||||||
|
GtkWidget *popover)
|
||||||
|
{
|
||||||
|
gtk_widget_set_visible (popover,
|
||||||
|
gtk_toggle_button_get_active (button));
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
create_popover (GtkWidget *parent,
|
||||||
|
GtkWidget *child,
|
||||||
|
GtkPositionType pos)
|
||||||
|
{
|
||||||
|
GtkWidget *popover;
|
||||||
|
|
||||||
|
popover = gtk_popover_new (parent);
|
||||||
|
gtk_popover_set_position (GTK_POPOVER (popover), pos);
|
||||||
|
gtk_container_add (GTK_CONTAINER (popover), child);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (popover), 6);
|
||||||
|
gtk_widget_show (child);
|
||||||
|
|
||||||
|
return popover;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
create_complex_popover (GtkWidget *parent,
|
||||||
|
GtkPositionType pos)
|
||||||
|
{
|
||||||
|
GtkWidget *popover, *window, *content;
|
||||||
|
GtkBuilder *builder;
|
||||||
|
|
||||||
|
builder = gtk_builder_new ();
|
||||||
|
gtk_builder_add_from_resource (builder, "/popover/popover.ui", NULL);
|
||||||
|
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||||
|
content = gtk_bin_get_child (GTK_BIN (window));
|
||||||
|
g_object_ref (content);
|
||||||
|
gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (content)),
|
||||||
|
content);
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
g_object_unref (builder);
|
||||||
|
|
||||||
|
popover = create_popover (parent, content, GTK_POS_BOTTOM);
|
||||||
|
g_object_unref (content);
|
||||||
|
|
||||||
|
gtk_widget_set_size_request (popover, 200, -1);
|
||||||
|
gtk_widget_set_vexpand (popover, TRUE);
|
||||||
|
|
||||||
|
gtk_widget_set_margin_start (popover, 10);
|
||||||
|
gtk_widget_set_margin_end (popover, 10);
|
||||||
|
gtk_widget_set_margin_bottom (popover, 10);
|
||||||
|
|
||||||
|
return popover;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
entry_size_allocate_cb (GtkEntry *entry,
|
||||||
|
GtkAllocation *allocation,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkEntryIconPosition popover_pos;
|
||||||
|
GtkPopover *popover = user_data;
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
if (gtk_widget_is_visible (GTK_WIDGET (popover)))
|
||||||
|
{
|
||||||
|
popover_pos =
|
||||||
|
GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (entry),
|
||||||
|
"popover-icon-pos"));
|
||||||
|
gtk_entry_get_icon_area (entry, popover_pos, &rect);
|
||||||
|
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
entry_icon_press_cb (GtkEntry *entry,
|
||||||
|
GtkEntryIconPosition icon_pos,
|
||||||
|
GdkEvent *event,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkWidget *popover = user_data;
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
gtk_entry_get_icon_area (entry, icon_pos, &rect);
|
||||||
|
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
|
||||||
|
gtk_widget_show (popover);
|
||||||
|
|
||||||
|
g_object_set_data (G_OBJECT (entry), "popover-icon-pos",
|
||||||
|
GUINT_TO_POINTER (icon_pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
day_selected_cb (GtkCalendar *calendar,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
GtkAllocation allocation;
|
||||||
|
GtkWidget *popover;
|
||||||
|
GdkEvent *event;
|
||||||
|
|
||||||
|
event = gtk_get_current_event ();
|
||||||
|
|
||||||
|
if (event->type != GDK_BUTTON_PRESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gdk_window_coords_to_parent (event->button.window,
|
||||||
|
event->button.x, event->button.y,
|
||||||
|
&event->button.x, &event->button.y);
|
||||||
|
gtk_widget_get_allocation (GTK_WIDGET (calendar), &allocation);
|
||||||
|
rect.x = event->button.x - allocation.x;
|
||||||
|
rect.y = event->button.y - allocation.y;
|
||||||
|
rect.width = rect.height = 1;
|
||||||
|
|
||||||
|
popover = create_popover (GTK_WIDGET (calendar),
|
||||||
|
gtk_entry_new (),
|
||||||
|
GTK_POS_BOTTOM);
|
||||||
|
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
|
||||||
|
|
||||||
|
gtk_widget_show (popover);
|
||||||
|
|
||||||
|
gdk_event_free (event);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_popover (GtkWidget *do_widget)
|
||||||
|
{
|
||||||
|
static GtkWidget *window = NULL;
|
||||||
|
GtkWidget *popover, *box, *widget;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 24);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (box), 24);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), box);
|
||||||
|
|
||||||
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
|
widget = gtk_toggle_button_new_with_label ("Button");
|
||||||
|
popover = create_popover (widget,
|
||||||
|
gtk_label_new ("This popover does not grab input"),
|
||||||
|
GTK_POS_TOP);
|
||||||
|
gtk_popover_set_modal (GTK_POPOVER (popover), FALSE);
|
||||||
|
g_signal_connect (widget, "toggled",
|
||||||
|
G_CALLBACK (toggle_changed_cb), popover);
|
||||||
|
gtk_container_add (GTK_CONTAINER (box), widget);
|
||||||
|
|
||||||
|
widget = gtk_entry_new ();
|
||||||
|
popover = create_complex_popover (widget, GTK_POS_TOP);
|
||||||
|
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (widget),
|
||||||
|
GTK_ENTRY_ICON_PRIMARY, "edit-find");
|
||||||
|
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (widget),
|
||||||
|
GTK_ENTRY_ICON_SECONDARY, "edit-clear");
|
||||||
|
|
||||||
|
g_signal_connect (widget, "icon-press",
|
||||||
|
G_CALLBACK (entry_icon_press_cb), popover);
|
||||||
|
g_signal_connect (widget, "size-allocate",
|
||||||
|
G_CALLBACK (entry_size_allocate_cb), popover);
|
||||||
|
gtk_container_add (GTK_CONTAINER (box), widget);
|
||||||
|
|
||||||
|
widget = gtk_calendar_new ();
|
||||||
|
g_signal_connect (widget, "day-selected",
|
||||||
|
G_CALLBACK (day_selected_cb), NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (box), widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible (window))
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
103
demos/gtk-demo/popover.ui
Normal file
103
demos/gtk-demo/popover.ui
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generated with glade 3.16.0 on Wed Nov 13 16:45:55 2013 -->
|
||||||
|
<interface>
|
||||||
|
<!-- interface-requires gtk+ 3.10 -->
|
||||||
|
<object class="GtkListStore" id="liststore1">
|
||||||
|
<columns>
|
||||||
|
<!-- column-name Name -->
|
||||||
|
<column type="gchararray"/>
|
||||||
|
</columns>
|
||||||
|
<data>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 1</col>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 2</col>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 3</col>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 4</col>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 5</col>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 6</col>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 7</col>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 8</col>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 9</col>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<col id="0" translatable="yes">Item 10</col>
|
||||||
|
</row>
|
||||||
|
</data>
|
||||||
|
</object>
|
||||||
|
<object class="GtkWindow" id="window">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="entry1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="primary_icon_name">edit-find</property>
|
||||||
|
<property name="secondary_icon_name">edit-clear</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeView" id="treeview1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<property name="model">liststore1</property>
|
||||||
|
<property name="headers_visible">False</property>
|
||||||
|
<property name="enable_search">False</property>
|
||||||
|
<property name="search_column">2</property>
|
||||||
|
<child internal-child="selection">
|
||||||
|
<object class="GtkTreeSelection" id="treeview-selection1"/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn" id="column1">
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText" id="cellrenderer1"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">0</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
@@ -190,6 +190,7 @@
|
|||||||
<xi:include href="xml/gtkmenutoolbutton.xml" />
|
<xi:include href="xml/gtkmenutoolbutton.xml" />
|
||||||
<xi:include href="xml/gtktoggletoolbutton.xml" />
|
<xi:include href="xml/gtktoggletoolbutton.xml" />
|
||||||
<xi:include href="xml/gtkradiotoolbutton.xml" />
|
<xi:include href="xml/gtkradiotoolbutton.xml" />
|
||||||
|
<xi:include href="xml/gtkpopover.xml" />
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="SelectorWidgets">
|
<chapter id="SelectorWidgets">
|
||||||
|
@@ -7831,3 +7831,18 @@ gtk_flow_box_child_get_index
|
|||||||
gtk_flow_box_child_is_selected
|
gtk_flow_box_child_is_selected
|
||||||
gtk_flow_box_child_changed
|
gtk_flow_box_child_changed
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>gtkpopover</FILE>
|
||||||
|
<TITLE>GtkPopover</TITLE>
|
||||||
|
GtkPopover
|
||||||
|
gtk_popover_new
|
||||||
|
gtk_popover_set_relative_to
|
||||||
|
gtk_popover_get_relative_to
|
||||||
|
gtk_popover_set_pointing_to
|
||||||
|
gtk_popover_get_pointing_to
|
||||||
|
gtk_popover_set_position
|
||||||
|
gtk_popover_get_position
|
||||||
|
gtk_popover_set_modal
|
||||||
|
gtk_popover_get_modal
|
||||||
|
</SECTION>
|
||||||
|
@@ -126,6 +126,7 @@ gtk_paned_get_type
|
|||||||
gtk_paper_size_get_type
|
gtk_paper_size_get_type
|
||||||
gtk_places_sidebar_get_type
|
gtk_places_sidebar_get_type
|
||||||
@ENABLE_ON_X11@gtk_plug_get_type
|
@ENABLE_ON_X11@gtk_plug_get_type
|
||||||
|
gtk_popover_get_type
|
||||||
@DISABLE_ON_W32@gtk_printer_get_type
|
@DISABLE_ON_W32@gtk_printer_get_type
|
||||||
gtk_print_context_get_type
|
gtk_print_context_get_type
|
||||||
@DISABLE_ON_W32@gtk_print_job_get_type
|
@DISABLE_ON_W32@gtk_print_job_get_type
|
||||||
|
@@ -296,6 +296,7 @@ gtk_public_h_sources = \
|
|||||||
gtkpapersize.h \
|
gtkpapersize.h \
|
||||||
gtkplacessidebar.h \
|
gtkplacessidebar.h \
|
||||||
gtkplug.h \
|
gtkplug.h \
|
||||||
|
gtkpopover.h \
|
||||||
gtkprintcontext.h \
|
gtkprintcontext.h \
|
||||||
gtkprintoperation.h \
|
gtkprintoperation.h \
|
||||||
gtkprintoperationpreview.h \
|
gtkprintoperationpreview.h \
|
||||||
@@ -411,7 +412,6 @@ gtk_private_h_sources = \
|
|||||||
gtkbookmarksmanager.h \
|
gtkbookmarksmanager.h \
|
||||||
gtkborderimageprivate.h \
|
gtkborderimageprivate.h \
|
||||||
gtkboxprivate.h \
|
gtkboxprivate.h \
|
||||||
gtkbubblewindowprivate.h \
|
|
||||||
gtkbuilderprivate.h \
|
gtkbuilderprivate.h \
|
||||||
gtkbuttonprivate.h \
|
gtkbuttonprivate.h \
|
||||||
gtkcairoblurprivate.h \
|
gtkcairoblurprivate.h \
|
||||||
@@ -489,6 +489,7 @@ gtk_private_h_sources = \
|
|||||||
gtkkeyhash.h \
|
gtkkeyhash.h \
|
||||||
gtklabelprivate.h \
|
gtklabelprivate.h \
|
||||||
gtklockbuttonprivate.h \
|
gtklockbuttonprivate.h \
|
||||||
|
gtkmagnifierprivate.h \
|
||||||
gtkmenubuttonprivate.h \
|
gtkmenubuttonprivate.h \
|
||||||
gtkmenuprivate.h \
|
gtkmenuprivate.h \
|
||||||
gtkmenuitemprivate.h \
|
gtkmenuitemprivate.h \
|
||||||
@@ -628,7 +629,6 @@ gtk_base_c_sources = \
|
|||||||
gtkborder.c \
|
gtkborder.c \
|
||||||
gtkborderimage.c \
|
gtkborderimage.c \
|
||||||
gtkbox.c \
|
gtkbox.c \
|
||||||
gtkbubblewindow.c \
|
|
||||||
gtkbuildable.c \
|
gtkbuildable.c \
|
||||||
gtkbuilder.c \
|
gtkbuilder.c \
|
||||||
gtkbuilderparser.c \
|
gtkbuilderparser.c \
|
||||||
@@ -763,6 +763,7 @@ gtk_base_c_sources = \
|
|||||||
gtkliststore.c \
|
gtkliststore.c \
|
||||||
gtklockbutton.c \
|
gtklockbutton.c \
|
||||||
gtkmain.c \
|
gtkmain.c \
|
||||||
|
gtkmagnifier.c \
|
||||||
gtkmarshalers.c \
|
gtkmarshalers.c \
|
||||||
gtkmenu.c \
|
gtkmenu.c \
|
||||||
gtkmenubar.c \
|
gtkmenubar.c \
|
||||||
@@ -800,6 +801,7 @@ gtk_base_c_sources = \
|
|||||||
gtkprivatetypebuiltins.c \
|
gtkprivatetypebuiltins.c \
|
||||||
gtkprogressbar.c \
|
gtkprogressbar.c \
|
||||||
gtkpixelcache.c \
|
gtkpixelcache.c \
|
||||||
|
gtkpopover.c \
|
||||||
gtkradiobutton.c \
|
gtkradiobutton.c \
|
||||||
gtkradiomenuitem.c \
|
gtkradiomenuitem.c \
|
||||||
gtkradiotoolbutton.c \
|
gtkradiotoolbutton.c \
|
||||||
|
@@ -524,9 +524,11 @@ gail_focus_notify (GtkWidget *widget)
|
|||||||
/*
|
/*
|
||||||
* Do not report focus on redundant object
|
* Do not report focus on redundant object
|
||||||
*/
|
*/
|
||||||
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||||
if (atk_obj &&
|
if (atk_obj &&
|
||||||
(atk_object_get_role(atk_obj) != ATK_ROLE_REDUNDANT_OBJECT))
|
(atk_object_get_role(atk_obj) != ATK_ROLE_REDUNDANT_OBJECT))
|
||||||
atk_focus_tracker_notify (atk_obj);
|
atk_focus_tracker_notify (atk_obj);
|
||||||
|
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||||
if (atk_obj && transient)
|
if (atk_obj && transient)
|
||||||
g_object_unref (atk_obj);
|
g_object_unref (atk_obj);
|
||||||
if (subsequent_focus_widget)
|
if (subsequent_focus_widget)
|
||||||
@@ -976,8 +978,10 @@ _gtk_accessibility_init (void)
|
|||||||
initialized = TRUE;
|
initialized = TRUE;
|
||||||
quark_focus_object = g_quark_from_static_string ("gail-focus-object");
|
quark_focus_object = g_quark_from_static_string ("gail-focus-object");
|
||||||
|
|
||||||
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||||
atk_focus_tracker_init (gail_focus_tracker_init);
|
atk_focus_tracker_init (gail_focus_tracker_init);
|
||||||
focus_tracker_id = atk_add_focus_tracker (gail_focus_tracker);
|
focus_tracker_id = atk_add_focus_tracker (gail_focus_tracker);
|
||||||
|
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||||
|
|
||||||
_gtk_accessibility_override_atk_util ();
|
_gtk_accessibility_override_atk_util ();
|
||||||
do_window_event_initialization ();
|
do_window_event_initialization ();
|
||||||
|
@@ -144,6 +144,7 @@
|
|||||||
#include <gtk/gtkpapersize.h>
|
#include <gtk/gtkpapersize.h>
|
||||||
#include <gtk/gtkpaned.h>
|
#include <gtk/gtkpaned.h>
|
||||||
#include <gtk/gtkplacessidebar.h>
|
#include <gtk/gtkplacessidebar.h>
|
||||||
|
#include <gtk/gtkpopover.h>
|
||||||
#include <gtk/gtkprintcontext.h>
|
#include <gtk/gtkprintcontext.h>
|
||||||
#include <gtk/gtkprintoperation.h>
|
#include <gtk/gtkprintoperation.h>
|
||||||
#include <gtk/gtkprintoperationpreview.h>
|
#include <gtk/gtkprintoperationpreview.h>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,81 +0,0 @@
|
|||||||
/* GTK - The GIMP Toolkit
|
|
||||||
* Copyright © 2013 Carlos Garnacho <carlosg@gnome.org>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GTK_BUBBLE_WINDOW_H__
|
|
||||||
#define __GTK_BUBBLE_WINDOW_H__
|
|
||||||
|
|
||||||
#include <gtk/gtkwindow.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GTK_TYPE_BUBBLE_WINDOW (_gtk_bubble_window_get_type ())
|
|
||||||
#define GTK_BUBBLE_WINDOW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_BUBBLE_WINDOW, GtkBubbleWindow))
|
|
||||||
#define GTK_BUBBLE_WINDOW_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GTK_TYPE_BUBBLE_WINDOW, GtkBubbleWindowClass))
|
|
||||||
#define GTK_IS_BUBBLE_WINDOW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_BUBBLE_WINDOW))
|
|
||||||
#define GTK_IS_BUBBLE_WINDOW_CLASS(o) (G_TYPE_CHECK_CLASS_TYPE ((o), GTK_TYPE_BUBBLE_WINDOW))
|
|
||||||
#define GTK_BUBBLE_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_BUBBLE_WINDOW, GtkBubbleWindowClass))
|
|
||||||
|
|
||||||
typedef struct _GtkBubbleWindow GtkBubbleWindow;
|
|
||||||
typedef struct _GtkBubbleWindowClass GtkBubbleWindowClass;
|
|
||||||
|
|
||||||
struct _GtkBubbleWindow
|
|
||||||
{
|
|
||||||
GtkWindow parent_instance;
|
|
||||||
|
|
||||||
/*< private >*/
|
|
||||||
gpointer priv;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GtkBubbleWindowClass
|
|
||||||
{
|
|
||||||
GtkWindowClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType _gtk_bubble_window_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
GtkWidget * _gtk_bubble_window_new (void);
|
|
||||||
|
|
||||||
void _gtk_bubble_window_set_relative_to (GtkBubbleWindow *window,
|
|
||||||
GdkWindow *relative_to);
|
|
||||||
GdkWindow * _gtk_bubble_window_get_relative_to (GtkBubbleWindow *window);
|
|
||||||
|
|
||||||
void _gtk_bubble_window_set_pointing_to (GtkBubbleWindow *window,
|
|
||||||
cairo_rectangle_int_t *rect);
|
|
||||||
gboolean _gtk_bubble_window_get_pointing_to (GtkBubbleWindow *window,
|
|
||||||
cairo_rectangle_int_t *rect);
|
|
||||||
void _gtk_bubble_window_set_position (GtkBubbleWindow *window,
|
|
||||||
GtkPositionType position);
|
|
||||||
|
|
||||||
GtkPositionType
|
|
||||||
_gtk_bubble_window_get_position (GtkBubbleWindow *window);
|
|
||||||
|
|
||||||
void _gtk_bubble_window_popup (GtkBubbleWindow *window,
|
|
||||||
GdkWindow *relative_to,
|
|
||||||
cairo_rectangle_int_t *pointing_to,
|
|
||||||
GtkPositionType position);
|
|
||||||
|
|
||||||
void _gtk_bubble_window_popdown (GtkBubbleWindow *window);
|
|
||||||
|
|
||||||
gboolean _gtk_bubble_window_grab (GtkBubbleWindow *window,
|
|
||||||
GdkDevice *device,
|
|
||||||
guint32 activate_time);
|
|
||||||
|
|
||||||
void _gtk_bubble_window_ungrab (GtkBubbleWindow *window);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GTK_BUBBLE_WINDOW_H__ */
|
|
129
gtk/gtkentry.c
129
gtk/gtkentry.c
@@ -63,8 +63,9 @@
|
|||||||
#include "gtkwidgetprivate.h"
|
#include "gtkwidgetprivate.h"
|
||||||
#include "gtkstylecontextprivate.h"
|
#include "gtkstylecontextprivate.h"
|
||||||
#include "gtktexthandleprivate.h"
|
#include "gtktexthandleprivate.h"
|
||||||
#include "gtkbubblewindowprivate.h"
|
#include "gtkpopover.h"
|
||||||
#include "gtktoolbar.h"
|
#include "gtktoolbar.h"
|
||||||
|
#include "gtkmagnifierprivate.h"
|
||||||
|
|
||||||
#include "a11y/gtkentryaccessible.h"
|
#include "a11y/gtkentryaccessible.h"
|
||||||
|
|
||||||
@@ -158,11 +159,14 @@ struct _GtkEntryPrivate
|
|||||||
|
|
||||||
gchar *placeholder_text;
|
gchar *placeholder_text;
|
||||||
|
|
||||||
GtkBubbleWindow *bubble_window;
|
GtkWidget *bubble_window;
|
||||||
GtkTextHandle *text_handle;
|
GtkTextHandle *text_handle;
|
||||||
GtkWidget *selection_bubble;
|
GtkWidget *selection_bubble;
|
||||||
guint selection_bubble_timeout_id;
|
guint selection_bubble_timeout_id;
|
||||||
|
|
||||||
|
GtkWidget *magnifier_popover;
|
||||||
|
GtkWidget *magnifier;
|
||||||
|
|
||||||
gfloat xalign;
|
gfloat xalign;
|
||||||
|
|
||||||
gint ascent; /* font ascent in pango units */
|
gint ascent; /* font ascent in pango units */
|
||||||
@@ -2665,6 +2669,18 @@ gtk_entry_init (GtkEntry *entry)
|
|||||||
G_CALLBACK (gtk_entry_handle_dragged), entry);
|
G_CALLBACK (gtk_entry_handle_dragged), entry);
|
||||||
g_signal_connect (priv->text_handle, "drag-finished",
|
g_signal_connect (priv->text_handle, "drag-finished",
|
||||||
G_CALLBACK (gtk_entry_handle_drag_finished), entry);
|
G_CALLBACK (gtk_entry_handle_drag_finished), entry);
|
||||||
|
|
||||||
|
priv->magnifier = _gtk_magnifier_new (GTK_WIDGET (entry));
|
||||||
|
gtk_widget_set_size_request (priv->magnifier, 100, 60);
|
||||||
|
_gtk_magnifier_set_magnification (GTK_MAGNIFIER (priv->magnifier), 2.0);
|
||||||
|
priv->magnifier_popover = gtk_popover_new (GTK_WIDGET (entry));
|
||||||
|
gtk_style_context_add_class (gtk_widget_get_style_context (priv->magnifier_popover),
|
||||||
|
GTK_STYLE_CLASS_OSD);
|
||||||
|
gtk_popover_set_modal (GTK_POPOVER (priv->magnifier_popover), FALSE);
|
||||||
|
gtk_container_add (GTK_CONTAINER (priv->magnifier_popover),
|
||||||
|
priv->magnifier);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (priv->magnifier_popover), 4);
|
||||||
|
gtk_widget_show (priv->magnifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2904,6 +2920,7 @@ gtk_entry_finalize (GObject *object)
|
|||||||
if (priv->selection_bubble)
|
if (priv->selection_bubble)
|
||||||
gtk_widget_destroy (priv->selection_bubble);
|
gtk_widget_destroy (priv->selection_bubble);
|
||||||
|
|
||||||
|
gtk_widget_destroy (priv->magnifier_popover);
|
||||||
g_object_unref (priv->text_handle);
|
g_object_unref (priv->text_handle);
|
||||||
g_free (priv->placeholder_text);
|
g_free (priv->placeholder_text);
|
||||||
g_free (priv->im_module);
|
g_free (priv->im_module);
|
||||||
@@ -3209,7 +3226,6 @@ gtk_entry_realize (GtkWidget *widget)
|
|||||||
|
|
||||||
gtk_entry_adjust_scroll (entry);
|
gtk_entry_adjust_scroll (entry);
|
||||||
gtk_entry_update_primary_selection (entry);
|
gtk_entry_update_primary_selection (entry);
|
||||||
_gtk_text_handle_set_relative_to (priv->text_handle, priv->text_area);
|
|
||||||
|
|
||||||
/* If the icon positions are already setup, create their windows.
|
/* If the icon positions are already setup, create their windows.
|
||||||
* Otherwise if they don't exist yet, then construct_icon_info()
|
* Otherwise if they don't exist yet, then construct_icon_info()
|
||||||
@@ -3237,7 +3253,6 @@ gtk_entry_unrealize (GtkWidget *widget)
|
|||||||
gtk_entry_reset_layout (entry);
|
gtk_entry_reset_layout (entry);
|
||||||
|
|
||||||
gtk_im_context_set_client_window (priv->im_context, NULL);
|
gtk_im_context_set_client_window (priv->im_context, NULL);
|
||||||
_gtk_text_handle_set_relative_to (priv->text_handle, NULL);
|
|
||||||
|
|
||||||
clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_PRIMARY);
|
clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_PRIMARY);
|
||||||
if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry))
|
if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry))
|
||||||
@@ -4062,13 +4077,22 @@ gtk_entry_move_handle (GtkEntry *entry,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
GtkAllocation primary, secondary;
|
||||||
GdkRectangle rect;
|
GdkRectangle rect;
|
||||||
|
gint win_x, win_y;
|
||||||
|
|
||||||
rect.x = CLAMP (x, 0, gdk_window_get_width (priv->text_area));
|
get_icon_allocations (entry, &primary, &secondary);
|
||||||
rect.y = y;
|
gtk_entry_get_text_area_size (entry, &win_x, &win_y, NULL, NULL);
|
||||||
|
rect.x = CLAMP (x, 0, gdk_window_get_width (priv->text_area)) + win_x;
|
||||||
|
rect.y = y + win_y;
|
||||||
rect.width = 1;
|
rect.width = 1;
|
||||||
rect.height = height;
|
rect.height = height;
|
||||||
|
|
||||||
|
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
|
||||||
|
rect.x += secondary.width;
|
||||||
|
else
|
||||||
|
rect.x += primary.width;
|
||||||
|
|
||||||
_gtk_text_handle_set_visible (priv->text_handle, pos, TRUE);
|
_gtk_text_handle_set_visible (priv->text_handle, pos, TRUE);
|
||||||
_gtk_text_handle_set_position (priv->text_handle, pos, &rect);
|
_gtk_text_handle_set_position (priv->text_handle, pos, &rect);
|
||||||
}
|
}
|
||||||
@@ -4412,7 +4436,10 @@ gtk_entry_button_release (GtkWidget *widget,
|
|||||||
priv->in_drag = 0;
|
priv->in_drag = 0;
|
||||||
}
|
}
|
||||||
else if (is_touchscreen)
|
else if (is_touchscreen)
|
||||||
gtk_entry_selection_bubble_popup_set (entry);
|
{
|
||||||
|
gtk_entry_selection_bubble_popup_set (entry);
|
||||||
|
gtk_widget_hide (priv->magnifier_popover);
|
||||||
|
}
|
||||||
|
|
||||||
priv->button = 0;
|
priv->button = 0;
|
||||||
priv->device = NULL;
|
priv->device = NULL;
|
||||||
@@ -4435,6 +4462,36 @@ _gtk_entry_get_selected_text (GtkEntry *entry)
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_entry_show_magnifier (GtkEntry *entry,
|
||||||
|
gint x,
|
||||||
|
gint y)
|
||||||
|
{
|
||||||
|
GtkAllocation allocation, primary, secondary;
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
GtkEntryPrivate *priv;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (GTK_WIDGET (entry), &allocation);
|
||||||
|
get_icon_allocations (entry, &primary, &secondary);
|
||||||
|
|
||||||
|
priv = entry->priv;
|
||||||
|
rect.x = CLAMP (x, 0, allocation.width - primary.width - secondary.width);
|
||||||
|
rect.width = 1;
|
||||||
|
rect.y = 0;
|
||||||
|
rect.height = allocation.height;
|
||||||
|
|
||||||
|
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
|
||||||
|
rect.x += secondary.width;
|
||||||
|
else
|
||||||
|
rect.x += primary.width;
|
||||||
|
|
||||||
|
_gtk_magnifier_set_coords (GTK_MAGNIFIER (priv->magnifier), rect.x,
|
||||||
|
rect.y + allocation.height / 2);
|
||||||
|
gtk_popover_set_pointing_to (GTK_POPOVER (priv->magnifier_popover),
|
||||||
|
&rect);
|
||||||
|
gtk_widget_show (priv->magnifier_popover);
|
||||||
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
gtk_entry_motion_notify (GtkWidget *widget,
|
gtk_entry_motion_notify (GtkWidget *widget,
|
||||||
GdkEventMotion *event)
|
GdkEventMotion *event)
|
||||||
@@ -4603,10 +4660,19 @@ gtk_entry_motion_notify (GtkWidget *widget,
|
|||||||
|
|
||||||
/* Update touch handles' position */
|
/* Update touch handles' position */
|
||||||
if (test_touchscreen || input_source == GDK_SOURCE_TOUCHSCREEN)
|
if (test_touchscreen || input_source == GDK_SOURCE_TOUCHSCREEN)
|
||||||
gtk_entry_update_handles (entry,
|
{
|
||||||
(priv->current_pos == priv->selection_bound) ?
|
gint x, y;
|
||||||
GTK_TEXT_HANDLE_MODE_CURSOR :
|
|
||||||
GTK_TEXT_HANDLE_MODE_SELECTION);
|
gtk_entry_update_handles (entry,
|
||||||
|
(priv->current_pos == priv->selection_bound) ?
|
||||||
|
GTK_TEXT_HANDLE_MODE_CURSOR :
|
||||||
|
GTK_TEXT_HANDLE_MODE_SELECTION);
|
||||||
|
|
||||||
|
gtk_entry_get_text_area_size (entry, &x, &y, NULL, NULL);
|
||||||
|
x += event->x;
|
||||||
|
y += event->y;
|
||||||
|
gtk_entry_show_magnifier (entry, x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -6403,6 +6469,7 @@ gtk_entry_handle_dragged (GtkTextHandle *handle,
|
|||||||
{
|
{
|
||||||
gint cursor_pos, selection_bound_pos, tmp_pos;
|
gint cursor_pos, selection_bound_pos, tmp_pos;
|
||||||
GtkEntryPrivate *priv = entry->priv;
|
GtkEntryPrivate *priv = entry->priv;
|
||||||
|
GtkAllocation primary, secondary;
|
||||||
GtkTextHandleMode mode;
|
GtkTextHandleMode mode;
|
||||||
gint *min, *max;
|
gint *min, *max;
|
||||||
|
|
||||||
@@ -6411,6 +6478,14 @@ gtk_entry_handle_dragged (GtkTextHandle *handle,
|
|||||||
cursor_pos = priv->current_pos;
|
cursor_pos = priv->current_pos;
|
||||||
selection_bound_pos = priv->selection_bound;
|
selection_bound_pos = priv->selection_bound;
|
||||||
mode = _gtk_text_handle_get_mode (handle);
|
mode = _gtk_text_handle_get_mode (handle);
|
||||||
|
|
||||||
|
get_icon_allocations (entry, &primary, &secondary);
|
||||||
|
|
||||||
|
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
|
||||||
|
x -= secondary.width;
|
||||||
|
else
|
||||||
|
x -= primary.width;
|
||||||
|
|
||||||
tmp_pos = gtk_entry_find_position (entry, x + priv->scroll_offset);
|
tmp_pos = gtk_entry_find_position (entry, x + priv->scroll_offset);
|
||||||
|
|
||||||
if (mode == GTK_TEXT_HANDLE_MODE_CURSOR ||
|
if (mode == GTK_TEXT_HANDLE_MODE_CURSOR ||
|
||||||
@@ -6458,6 +6533,8 @@ gtk_entry_handle_dragged (GtkTextHandle *handle,
|
|||||||
|
|
||||||
gtk_entry_update_handles (entry, mode);
|
gtk_entry_update_handles (entry, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gtk_entry_show_magnifier (entry, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -6466,6 +6543,7 @@ gtk_entry_handle_drag_finished (GtkTextHandle *handle,
|
|||||||
GtkEntry *entry)
|
GtkEntry *entry)
|
||||||
{
|
{
|
||||||
gtk_entry_selection_bubble_popup_set (entry);
|
gtk_entry_selection_bubble_popup_set (entry);
|
||||||
|
gtk_widget_hide (entry->priv->magnifier_popover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -9361,7 +9439,7 @@ activate_bubble_cb (GtkWidget *item,
|
|||||||
{
|
{
|
||||||
const gchar *signal = g_object_get_data (G_OBJECT (item), "gtk-signal");
|
const gchar *signal = g_object_get_data (G_OBJECT (item), "gtk-signal");
|
||||||
g_signal_emit_by_name (entry, signal);
|
g_signal_emit_by_name (entry, signal);
|
||||||
_gtk_bubble_window_popdown (GTK_BUBBLE_WINDOW (entry->priv->selection_bubble));
|
gtk_widget_hide (entry->priv->selection_bubble);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -9372,6 +9450,7 @@ append_bubble_action (GtkEntry *entry,
|
|||||||
gboolean sensitive)
|
gboolean sensitive)
|
||||||
{
|
{
|
||||||
GtkToolItem *item = gtk_tool_button_new (NULL, label);
|
GtkToolItem *item = gtk_tool_button_new (NULL, label);
|
||||||
|
gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (item), TRUE);
|
||||||
g_object_set_data (G_OBJECT (item), I_("gtk-signal"), (char *)signal);
|
g_object_set_data (G_OBJECT (item), I_("gtk-signal"), (char *)signal);
|
||||||
g_signal_connect (item, "clicked", G_CALLBACK (activate_bubble_cb), entry);
|
g_signal_connect (item, "clicked", G_CALLBACK (activate_bubble_cb), entry);
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (item), sensitive);
|
gtk_widget_set_sensitive (GTK_WIDGET (item), sensitive);
|
||||||
@@ -9387,7 +9466,7 @@ bubble_targets_received (GtkClipboard *clipboard,
|
|||||||
GtkEntry *entry = user_data;
|
GtkEntry *entry = user_data;
|
||||||
GtkEntryPrivate *priv = entry->priv;
|
GtkEntryPrivate *priv = entry->priv;
|
||||||
cairo_rectangle_int_t rect;
|
cairo_rectangle_int_t rect;
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation, primary, secondary;
|
||||||
gint start_x, end_x;
|
gint start_x, end_x;
|
||||||
gboolean has_selection;
|
gboolean has_selection;
|
||||||
gboolean has_clipboard;
|
gboolean has_clipboard;
|
||||||
@@ -9405,7 +9484,13 @@ bubble_targets_received (GtkClipboard *clipboard,
|
|||||||
if (priv->selection_bubble)
|
if (priv->selection_bubble)
|
||||||
gtk_widget_destroy (priv->selection_bubble);
|
gtk_widget_destroy (priv->selection_bubble);
|
||||||
|
|
||||||
priv->selection_bubble = _gtk_bubble_window_new ();
|
priv->selection_bubble = gtk_popover_new (GTK_WIDGET (entry));
|
||||||
|
gtk_style_context_add_class (gtk_widget_get_style_context (priv->selection_bubble),
|
||||||
|
GTK_STYLE_CLASS_OSD);
|
||||||
|
gtk_popover_set_position (GTK_POPOVER (priv->selection_bubble),
|
||||||
|
GTK_POS_TOP);
|
||||||
|
gtk_popover_set_modal (GTK_POPOVER (priv->selection_bubble), FALSE);
|
||||||
|
|
||||||
toolbar = GTK_WIDGET (gtk_toolbar_new ());
|
toolbar = GTK_WIDGET (gtk_toolbar_new ());
|
||||||
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_TEXT);
|
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_TEXT);
|
||||||
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
|
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
|
||||||
@@ -9434,7 +9519,9 @@ bubble_targets_received (GtkClipboard *clipboard,
|
|||||||
start_x -= priv->scroll_offset;
|
start_x -= priv->scroll_offset;
|
||||||
start_x = CLAMP (start_x, 0, gdk_window_get_width (priv->text_area));
|
start_x = CLAMP (start_x, 0, gdk_window_get_width (priv->text_area));
|
||||||
|
|
||||||
rect.y = 0;
|
gtk_entry_get_text_area_size (entry, &rect.x, &rect.y, NULL, NULL);
|
||||||
|
get_icon_allocations (entry, &primary, &secondary);
|
||||||
|
rect.x += primary.width;
|
||||||
rect.height = gdk_window_get_height (priv->text_area);
|
rect.height = gdk_window_get_height (priv->text_area);
|
||||||
|
|
||||||
if (has_selection)
|
if (has_selection)
|
||||||
@@ -9442,17 +9529,17 @@ bubble_targets_received (GtkClipboard *clipboard,
|
|||||||
end_x = gtk_entry_get_selection_bound_location (entry) - priv->scroll_offset;
|
end_x = gtk_entry_get_selection_bound_location (entry) - priv->scroll_offset;
|
||||||
end_x = CLAMP (end_x, 0, gdk_window_get_width (priv->text_area));
|
end_x = CLAMP (end_x, 0, gdk_window_get_width (priv->text_area));
|
||||||
|
|
||||||
rect.x = MIN (start_x, end_x);
|
rect.x += MIN (start_x, end_x);
|
||||||
rect.width = MAX (start_x, end_x) - rect.x;
|
rect.width = MAX (start_x, end_x) - MIN (start_x, end_x);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rect.x = start_x;
|
rect.x += start_x;
|
||||||
rect.width = 0;
|
rect.width = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_gtk_bubble_window_popup (GTK_BUBBLE_WINDOW (priv->selection_bubble),
|
gtk_popover_set_pointing_to (GTK_POPOVER (priv->selection_bubble), &rect);
|
||||||
priv->text_area, &rect, GTK_POS_TOP);
|
gtk_widget_show (priv->selection_bubble);
|
||||||
|
|
||||||
priv->selection_bubble_timeout_id = 0;
|
priv->selection_bubble_timeout_id = 0;
|
||||||
}
|
}
|
||||||
@@ -9477,7 +9564,7 @@ gtk_entry_selection_bubble_popup_unset (GtkEntry *entry)
|
|||||||
priv = entry->priv;
|
priv = entry->priv;
|
||||||
|
|
||||||
if (priv->selection_bubble)
|
if (priv->selection_bubble)
|
||||||
_gtk_bubble_window_popdown (GTK_BUBBLE_WINDOW (priv->selection_bubble));
|
gtk_widget_hide (priv->selection_bubble);
|
||||||
|
|
||||||
if (priv->selection_bubble_timeout_id)
|
if (priv->selection_bubble_timeout_id)
|
||||||
{
|
{
|
||||||
|
@@ -727,8 +727,7 @@ gtk_header_bar_compute_size_for_orientation (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->label_box != NULL &&
|
if (priv->label_box != NULL)
|
||||||
gtk_widget_get_visible (priv->label_box))
|
|
||||||
{
|
{
|
||||||
gtk_widget_get_preferred_width (priv->label_sizing_box,
|
gtk_widget_get_preferred_width (priv->label_sizing_box,
|
||||||
&child_size, &child_natural);
|
&child_size, &child_natural);
|
||||||
@@ -862,8 +861,7 @@ gtk_header_bar_compute_size_for_opposing_orientation (GtkWidget *widget,
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->label_box != NULL &&
|
if (priv->label_box != NULL)
|
||||||
gtk_widget_get_visible (priv->label_box))
|
|
||||||
{
|
{
|
||||||
gtk_widget_get_preferred_height (priv->label_sizing_box,
|
gtk_widget_get_preferred_height (priv->label_sizing_box,
|
||||||
&child_minimum, &child_natural);
|
&child_minimum, &child_natural);
|
||||||
@@ -990,14 +988,16 @@ gtk_header_bar_size_allocate (GtkWidget *widget,
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->custom_title)
|
if (priv->custom_title &&
|
||||||
|
gtk_widget_get_visible (priv->custom_title))
|
||||||
{
|
{
|
||||||
gtk_widget_get_preferred_width_for_height (priv->custom_title,
|
gtk_widget_get_preferred_width_for_height (priv->custom_title,
|
||||||
height,
|
height,
|
||||||
&title_minimum_size,
|
&title_minimum_size,
|
||||||
&title_natural_size);
|
&title_natural_size);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (priv->label_box != NULL)
|
||||||
{
|
{
|
||||||
gtk_widget_get_preferred_width_for_height (priv->label_box,
|
gtk_widget_get_preferred_width_for_height (priv->label_box,
|
||||||
height,
|
height,
|
||||||
@@ -1105,9 +1105,11 @@ gtk_header_bar_size_allocate (GtkWidget *widget,
|
|||||||
if (direction == GTK_TEXT_DIR_RTL)
|
if (direction == GTK_TEXT_DIR_RTL)
|
||||||
child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width;
|
child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width;
|
||||||
|
|
||||||
if (priv->custom_title)
|
if (priv->custom_title != NULL &&
|
||||||
|
gtk_widget_get_visible (priv->custom_title))
|
||||||
gtk_widget_size_allocate (priv->custom_title, &child_allocation);
|
gtk_widget_size_allocate (priv->custom_title, &child_allocation);
|
||||||
else
|
|
||||||
|
if (priv->label_box != NULL)
|
||||||
gtk_widget_size_allocate (priv->label_box, &child_allocation);
|
gtk_widget_size_allocate (priv->label_box, &child_allocation);
|
||||||
|
|
||||||
if (priv->titlebar_start_box)
|
if (priv->titlebar_start_box)
|
||||||
@@ -1295,7 +1297,6 @@ gtk_header_bar_set_custom_title (GtkHeaderBar *bar,
|
|||||||
|
|
||||||
gtk_widget_set_parent (priv->custom_title, GTK_WIDGET (bar));
|
gtk_widget_set_parent (priv->custom_title, GTK_WIDGET (bar));
|
||||||
gtk_widget_set_valign (priv->custom_title, GTK_ALIGN_CENTER);
|
gtk_widget_set_valign (priv->custom_title, GTK_ALIGN_CENTER);
|
||||||
gtk_widget_show (title_widget);
|
|
||||||
|
|
||||||
if (priv->label_box != NULL)
|
if (priv->label_box != NULL)
|
||||||
{
|
{
|
||||||
|
@@ -3285,7 +3285,9 @@ _gtk_icon_view_set_cursor_item (GtkIconView *icon_view,
|
|||||||
|
|
||||||
if (item_obj != NULL)
|
if (item_obj != NULL)
|
||||||
{
|
{
|
||||||
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||||
atk_focus_tracker_notify (item_obj);
|
atk_focus_tracker_notify (item_obj);
|
||||||
|
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||||
atk_object_notify_state_change (item_obj, ATK_STATE_FOCUSED, TRUE);
|
atk_object_notify_state_change (item_obj, ATK_STATE_FOCUSED, TRUE);
|
||||||
g_object_unref (item_obj);
|
g_object_unref (item_obj);
|
||||||
}
|
}
|
||||||
|
269
gtk/gtkmagnifier.c
Normal file
269
gtk/gtkmagnifier.c
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
/* GTK - The GIMP Toolkit
|
||||||
|
* Copyright © 2013 Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "gtk/gtk.h"
|
||||||
|
#include "gtkmagnifierprivate.h"
|
||||||
|
#include "gtkintl.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_INSPECTED = 1,
|
||||||
|
PROP_MAGNIFICATION
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _GtkMagnifierPrivate GtkMagnifierPrivate;
|
||||||
|
|
||||||
|
struct _GtkMagnifierPrivate
|
||||||
|
{
|
||||||
|
GtkWidget *inspected;
|
||||||
|
gdouble magnification;
|
||||||
|
gint x;
|
||||||
|
gint y;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (GtkMagnifier, _gtk_magnifier,
|
||||||
|
GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_magnifier_set_property (GObject *object,
|
||||||
|
guint param_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (param_id)
|
||||||
|
{
|
||||||
|
case PROP_INSPECTED:
|
||||||
|
_gtk_magnifier_set_inspected (GTK_MAGNIFIER (object),
|
||||||
|
g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
case PROP_MAGNIFICATION:
|
||||||
|
_gtk_magnifier_set_magnification (GTK_MAGNIFIER (object),
|
||||||
|
g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_magnifier_get_property (GObject *object,
|
||||||
|
guint param_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GtkMagnifier *magnifier;
|
||||||
|
GtkMagnifierPrivate *priv;
|
||||||
|
|
||||||
|
magnifier = GTK_MAGNIFIER (object);
|
||||||
|
priv = _gtk_magnifier_get_instance_private (magnifier);
|
||||||
|
|
||||||
|
switch (param_id)
|
||||||
|
{
|
||||||
|
case PROP_INSPECTED:
|
||||||
|
g_value_set_object (value, priv->inspected);
|
||||||
|
break;
|
||||||
|
case PROP_MAGNIFICATION:
|
||||||
|
g_value_set_double (value, priv->magnification);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_gtk_magnifier_draw (GtkWidget *widget,
|
||||||
|
cairo_t *cr)
|
||||||
|
{
|
||||||
|
GtkAllocation allocation, inspected_alloc;
|
||||||
|
GtkMagnifier *magnifier;
|
||||||
|
GtkMagnifierPrivate *priv;
|
||||||
|
gdouble x, y;
|
||||||
|
|
||||||
|
magnifier = GTK_MAGNIFIER (widget);
|
||||||
|
priv = _gtk_magnifier_get_instance_private (magnifier);
|
||||||
|
|
||||||
|
if (!gtk_widget_is_visible (priv->inspected))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
|
gtk_widget_get_allocation (priv->inspected, &inspected_alloc);
|
||||||
|
cairo_translate (cr, allocation.width / 2, allocation.height / 2);
|
||||||
|
|
||||||
|
x = CLAMP (priv->x, 0, inspected_alloc.width);
|
||||||
|
y = CLAMP (priv->y, 0, inspected_alloc.height);
|
||||||
|
|
||||||
|
cairo_save (cr);
|
||||||
|
cairo_scale (cr, priv->magnification, priv->magnification);
|
||||||
|
cairo_translate (cr, -x, -y);
|
||||||
|
gtk_widget_draw (priv->inspected, cr);
|
||||||
|
cairo_restore (cr);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_magnifier_class_init (GtkMagnifierClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->set_property = _gtk_magnifier_set_property;
|
||||||
|
object_class->get_property = _gtk_magnifier_get_property;
|
||||||
|
|
||||||
|
widget_class->draw = _gtk_magnifier_draw;
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_INSPECTED,
|
||||||
|
g_param_spec_object (P_("inspected"),
|
||||||
|
P_("Inspected"),
|
||||||
|
P_("Inspected widget"),
|
||||||
|
GTK_TYPE_WIDGET,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_MAGNIFICATION,
|
||||||
|
g_param_spec_double (P_("magnification"),
|
||||||
|
P_("magnification"),
|
||||||
|
P_("magnification"),
|
||||||
|
1, G_MAXDOUBLE, 1,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_magnifier_init (GtkMagnifier *magnifier)
|
||||||
|
{
|
||||||
|
GtkWidget *widget = GTK_WIDGET (magnifier);
|
||||||
|
GtkMagnifierPrivate *priv;
|
||||||
|
|
||||||
|
priv = _gtk_magnifier_get_instance_private (magnifier);
|
||||||
|
|
||||||
|
gtk_widget_set_events (widget,
|
||||||
|
gtk_widget_get_events (widget) |
|
||||||
|
GDK_EXPOSURE_MASK);
|
||||||
|
|
||||||
|
gtk_widget_set_has_window (widget, FALSE);
|
||||||
|
priv->magnification = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
_gtk_magnifier_new (GtkWidget *inspected)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GTK_IS_WIDGET (inspected), NULL);
|
||||||
|
|
||||||
|
return g_object_new (GTK_TYPE_MAGNIFIER,
|
||||||
|
"inspected", inspected,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
_gtk_magnifier_get_inspected (GtkMagnifier *magnifier)
|
||||||
|
{
|
||||||
|
GtkMagnifierPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_MAGNIFIER (magnifier), NULL);
|
||||||
|
|
||||||
|
priv = _gtk_magnifier_get_instance_private (magnifier);
|
||||||
|
|
||||||
|
return priv->inspected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_magnifier_set_inspected (GtkMagnifier *magnifier,
|
||||||
|
GtkWidget *inspected)
|
||||||
|
{
|
||||||
|
GtkMagnifierPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_MAGNIFIER (magnifier));
|
||||||
|
|
||||||
|
priv = _gtk_magnifier_get_instance_private (magnifier);
|
||||||
|
|
||||||
|
if (priv->inspected == inspected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->inspected = inspected;
|
||||||
|
g_object_notify (G_OBJECT (magnifier), "inspected");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_magnifier_set_coords (GtkMagnifier *magnifier,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y)
|
||||||
|
{
|
||||||
|
GtkMagnifierPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_MAGNIFIER (magnifier));
|
||||||
|
|
||||||
|
priv = _gtk_magnifier_get_instance_private (magnifier);
|
||||||
|
|
||||||
|
if (priv->x == x && priv->y == y)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->x = x;
|
||||||
|
priv->y = y;
|
||||||
|
|
||||||
|
if (gtk_widget_is_visible (GTK_WIDGET (magnifier)))
|
||||||
|
gtk_widget_queue_draw (GTK_WIDGET (magnifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_magnifier_get_coords (GtkMagnifier *magnifier,
|
||||||
|
gdouble *x,
|
||||||
|
gdouble *y)
|
||||||
|
{
|
||||||
|
GtkMagnifierPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_MAGNIFIER (magnifier));
|
||||||
|
|
||||||
|
priv = _gtk_magnifier_get_instance_private (magnifier);
|
||||||
|
|
||||||
|
if (x)
|
||||||
|
*x = priv->x;
|
||||||
|
|
||||||
|
if (y)
|
||||||
|
*y = priv->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_magnifier_set_magnification (GtkMagnifier *magnifier,
|
||||||
|
gdouble magnification)
|
||||||
|
{
|
||||||
|
GtkMagnifierPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_MAGNIFIER (magnifier));
|
||||||
|
|
||||||
|
priv = _gtk_magnifier_get_instance_private (magnifier);
|
||||||
|
|
||||||
|
if (priv->magnification == magnification)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->magnification = magnification;
|
||||||
|
g_object_notify (G_OBJECT (magnifier), "magnification");
|
||||||
|
|
||||||
|
if (gtk_widget_is_visible (GTK_WIDGET (magnifier)))
|
||||||
|
gtk_widget_queue_draw (GTK_WIDGET (magnifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
_gtk_magnifier_get_magnification (GtkMagnifier *magnifier)
|
||||||
|
{
|
||||||
|
GtkMagnifierPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_MAGNIFIER (magnifier), 1);
|
||||||
|
|
||||||
|
priv = _gtk_magnifier_get_instance_private (magnifier);
|
||||||
|
|
||||||
|
return priv->magnification;
|
||||||
|
}
|
64
gtk/gtkmagnifierprivate.h
Normal file
64
gtk/gtkmagnifierprivate.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/* GTK - The GIMP Toolkit
|
||||||
|
* Copyright © 2013 Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GTK_MAGNIFIER_H__
|
||||||
|
#define __GTK_MAGNIFIER_H__
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GTK_TYPE_MAGNIFIER (_gtk_magnifier_get_type ())
|
||||||
|
#define GTK_MAGNIFIER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_MAGNIFIER, GtkMagnifier))
|
||||||
|
#define GTK_MAGNIFIER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GTK_TYPE_MAGNIFIER, GtkMagnifierClass))
|
||||||
|
#define GTK_IS_MAGNIFIER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_MAGNIFIER))
|
||||||
|
#define GTK_IS_MAGNIFIER_CLASS(o) (G_TYPE_CHECK_CLASS_TYPE ((o), GTK_TYPE_MAGNIFIER))
|
||||||
|
#define GTK_MAGNIFIER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_MAGNIFIER, GtkMagnifierClass))
|
||||||
|
|
||||||
|
typedef struct _GtkMagnifier GtkMagnifier;
|
||||||
|
typedef struct _GtkMagnifierClass GtkMagnifierClass;
|
||||||
|
|
||||||
|
struct _GtkMagnifier
|
||||||
|
{
|
||||||
|
GtkWidget parent_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GtkMagnifierClass
|
||||||
|
{
|
||||||
|
GtkWidgetClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType _gtk_magnifier_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GtkWidget * _gtk_magnifier_new (GtkWidget *inspected);
|
||||||
|
|
||||||
|
GtkWidget * _gtk_magnifier_get_inspected (GtkMagnifier *magnifier);
|
||||||
|
void _gtk_magnifier_set_inspected (GtkMagnifier *magnifier,
|
||||||
|
GtkWidget *inspected);
|
||||||
|
|
||||||
|
void _gtk_magnifier_set_coords (GtkMagnifier *magnifier,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y);
|
||||||
|
void _gtk_magnifier_get_coords (GtkMagnifier *magnifier,
|
||||||
|
gdouble *x,
|
||||||
|
gdouble *y);
|
||||||
|
|
||||||
|
void _gtk_magnifier_set_magnification (GtkMagnifier *magnifier,
|
||||||
|
gdouble magnification);
|
||||||
|
gdouble _gtk_magnifier_get_magnification (GtkMagnifier *magnifier);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GTK_MAGNIFIER_H__ */
|
@@ -1568,6 +1568,12 @@ gtk_main_do_event (GdkEvent *event)
|
|||||||
event_widget = gtk_get_event_widget (event);
|
event_widget = gtk_get_event_widget (event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GTK_IS_WINDOW (event_widget))
|
||||||
|
{
|
||||||
|
if (_gtk_window_check_handle_wm_event (event))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
window_group = gtk_main_get_window_group (event_widget);
|
window_group = gtk_main_get_window_group (event_widget);
|
||||||
device = gdk_event_get_device (event);
|
device = gdk_event_get_device (event);
|
||||||
|
|
||||||
|
@@ -396,6 +396,19 @@ blow_cache_cb (gpointer user_data)
|
|||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
context_is_unscaled (cairo_t *cr)
|
||||||
|
{
|
||||||
|
cairo_matrix_t matrix;
|
||||||
|
gdouble x, y;
|
||||||
|
|
||||||
|
x = y = 1;
|
||||||
|
cairo_get_matrix (cr, &matrix);
|
||||||
|
cairo_matrix_transform_distance (&matrix, &x, &y);
|
||||||
|
|
||||||
|
return x == 1 && y == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_gtk_pixel_cache_draw (GtkPixelCache *cache,
|
_gtk_pixel_cache_draw (GtkPixelCache *cache,
|
||||||
@@ -420,7 +433,7 @@ _gtk_pixel_cache_draw (GtkPixelCache *cache,
|
|||||||
_gtk_pixel_cache_set_position (cache, view_rect, canvas_rect);
|
_gtk_pixel_cache_set_position (cache, view_rect, canvas_rect);
|
||||||
_gtk_pixel_cache_repaint (cache, draw, view_rect, canvas_rect, user_data);
|
_gtk_pixel_cache_repaint (cache, draw, view_rect, canvas_rect, user_data);
|
||||||
|
|
||||||
if (cache->surface &&
|
if (cache->surface && context_is_unscaled (cr) &&
|
||||||
/* Don't use backing surface if rendering elsewhere */
|
/* Don't use backing surface if rendering elsewhere */
|
||||||
cairo_surface_get_type (cache->surface) == cairo_surface_get_type (cairo_get_target (cr)))
|
cairo_surface_get_type (cache->surface) == cairo_surface_get_type (cairo_get_target (cr)))
|
||||||
{
|
{
|
||||||
|
1674
gtk/gtkpopover.c
Normal file
1674
gtk/gtkpopover.c
Normal file
File diff suppressed because it is too large
Load Diff
84
gtk/gtkpopover.h
Normal file
84
gtk/gtkpopover.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/* GTK - The GIMP Toolkit
|
||||||
|
* Copyright © 2013 Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GTK_POPOVER_H__
|
||||||
|
#define __GTK_POPOVER_H__
|
||||||
|
|
||||||
|
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||||
|
#error "Only <gtk/gtk.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gtk/gtkwindow.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GTK_TYPE_POPOVER (gtk_popover_get_type ())
|
||||||
|
#define GTK_POPOVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_POPOVER, GtkPopover))
|
||||||
|
#define GTK_POPOVER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GTK_TYPE_POPOVER, GtkPopoverClass))
|
||||||
|
#define GTK_IS_POPOVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_POPOVER))
|
||||||
|
#define GTK_IS_POPOVER_CLASS(o) (G_TYPE_CHECK_CLASS_TYPE ((o), GTK_TYPE_POPOVER))
|
||||||
|
#define GTK_POPOVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_POPOVER, GtkPopoverClass))
|
||||||
|
|
||||||
|
typedef struct _GtkPopover GtkPopover;
|
||||||
|
typedef struct _GtkPopoverClass GtkPopoverClass;
|
||||||
|
|
||||||
|
struct _GtkPopover
|
||||||
|
{
|
||||||
|
GtkBin parent_instance;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
gpointer priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GtkPopoverClass
|
||||||
|
{
|
||||||
|
GtkBinClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
GType gtk_popover_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
GtkWidget * gtk_popover_new (GtkWidget *relative_to);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
void gtk_popover_set_relative_to (GtkPopover *popover,
|
||||||
|
GtkWidget *relative_to);
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
GtkWidget * gtk_popover_get_relative_to (GtkPopover *popover);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
void gtk_popover_set_pointing_to (GtkPopover *popover,
|
||||||
|
cairo_rectangle_int_t *rect);
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
gboolean gtk_popover_get_pointing_to (GtkPopover *popover,
|
||||||
|
cairo_rectangle_int_t *rect);
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
void gtk_popover_set_position (GtkPopover *popover,
|
||||||
|
GtkPositionType position);
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
GtkPositionType gtk_popover_get_position (GtkPopover *popover);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
void gtk_popover_set_modal (GtkPopover *popover,
|
||||||
|
gboolean modal);
|
||||||
|
GDK_AVAILABLE_IN_3_12
|
||||||
|
gboolean gtk_popover_get_modal (GtkPopover *popover);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GTK_POPOVER_H__ */
|
@@ -20,6 +20,7 @@
|
|||||||
#include "gtktexthandleprivate.h"
|
#include "gtktexthandleprivate.h"
|
||||||
#include "gtkmarshalers.h"
|
#include "gtkmarshalers.h"
|
||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
|
#include "gtkwindowprivate.h"
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
@@ -35,13 +36,12 @@ enum {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_PARENT,
|
PROP_PARENT
|
||||||
PROP_RELATIVE_TO
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _HandleWindow
|
struct _HandleWindow
|
||||||
{
|
{
|
||||||
GdkWindow *window;
|
GtkWidget *widget;
|
||||||
GdkRectangle pointing_to;
|
GdkRectangle pointing_to;
|
||||||
gint dx;
|
gint dx;
|
||||||
gint dy;
|
gint dy;
|
||||||
@@ -55,13 +55,11 @@ struct _GtkTextHandlePrivate
|
|||||||
{
|
{
|
||||||
HandleWindow windows[2];
|
HandleWindow windows[2];
|
||||||
GtkWidget *parent;
|
GtkWidget *parent;
|
||||||
GdkWindow *relative_to;
|
GtkScrollable *parent_scrollable;
|
||||||
|
GtkAdjustment *vadj;
|
||||||
gulong draw_signal_id;
|
GtkAdjustment *hadj;
|
||||||
gulong event_signal_id;
|
guint hierarchy_changed_id;
|
||||||
gulong style_updated_id;
|
guint scrollable_notify_id;
|
||||||
gulong composited_changed_id;
|
|
||||||
guint realized : 1;
|
|
||||||
guint mode : 2;
|
guint mode : 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,6 +67,9 @@ G_DEFINE_TYPE_WITH_PRIVATE (GtkTextHandle, _gtk_text_handle, G_TYPE_OBJECT)
|
|||||||
|
|
||||||
static guint signals[LAST_SIGNAL] = { 0 };
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
static void _gtk_text_handle_update (GtkTextHandle *handle,
|
||||||
|
GtkTextHandlePosition pos);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_gtk_text_handle_get_size (GtkTextHandle *handle,
|
_gtk_text_handle_get_size (GtkTextHandle *handle,
|
||||||
gint *width,
|
gint *width,
|
||||||
@@ -104,10 +105,6 @@ _gtk_text_handle_draw (GtkTextHandle *handle,
|
|||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
|
|
||||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
|
||||||
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
|
||||||
cairo_paint (cr);
|
|
||||||
|
|
||||||
if (pos == GTK_TEXT_HANDLE_POSITION_SELECTION_END)
|
if (pos == GTK_TEXT_HANDLE_POSITION_SELECTION_END)
|
||||||
cairo_translate (cr, 0, priv->windows[pos].pointing_to.height);
|
cairo_translate (cr, 0, priv->windows[pos].pointing_to.height);
|
||||||
|
|
||||||
@@ -135,92 +132,18 @@ _gtk_text_handle_draw (GtkTextHandle *handle,
|
|||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gint
|
||||||
_gtk_text_handle_update_shape (GtkTextHandle *handle,
|
_text_handle_pos_from_widget (GtkTextHandle *handle,
|
||||||
GdkWindow *window,
|
GtkWidget *widget)
|
||||||
GtkTextHandlePosition pos)
|
|
||||||
{
|
{
|
||||||
GtkTextHandlePrivate *priv;
|
GtkTextHandlePrivate *priv = handle->priv;
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
cairo_surface_t *surface;
|
|
||||||
cairo_region_t *region;
|
|
||||||
cairo_t *cr;
|
|
||||||
|
|
||||||
priv = handle->priv;
|
if (widget == priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget)
|
||||||
|
return GTK_TEXT_HANDLE_POSITION_SELECTION_START;
|
||||||
surface =
|
else if (widget == priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget)
|
||||||
gdk_window_create_similar_surface (window,
|
return GTK_TEXT_HANDLE_POSITION_SELECTION_END;
|
||||||
CAIRO_CONTENT_COLOR_ALPHA,
|
|
||||||
gdk_window_get_width (window),
|
|
||||||
gdk_window_get_height (window));
|
|
||||||
|
|
||||||
cr = cairo_create (surface);
|
|
||||||
_gtk_text_handle_draw (handle, cr, pos);
|
|
||||||
cairo_destroy (cr);
|
|
||||||
|
|
||||||
region = gdk_cairo_region_create_from_surface (surface);
|
|
||||||
|
|
||||||
if (gtk_widget_is_composited (priv->parent))
|
|
||||||
gdk_window_shape_combine_region (window, NULL, 0, 0);
|
|
||||||
else
|
else
|
||||||
gdk_window_shape_combine_region (window, region, 0, 0);
|
return -1;
|
||||||
|
|
||||||
cairo_region_get_extents (region, &rect);
|
|
||||||
cairo_region_destroy (region);
|
|
||||||
|
|
||||||
/* Preserve x/width, but extend input shape
|
|
||||||
* vertically to all window height */
|
|
||||||
rect.y = 0;
|
|
||||||
rect.height = gdk_window_get_height (window);
|
|
||||||
region = cairo_region_create_rectangle (&rect);
|
|
||||||
|
|
||||||
gdk_window_input_shape_combine_region (window, region, 0, 0);
|
|
||||||
|
|
||||||
cairo_surface_destroy (surface);
|
|
||||||
cairo_region_destroy (region);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GdkWindow *
|
|
||||||
_gtk_text_handle_create_window (GtkTextHandle *handle,
|
|
||||||
GtkTextHandlePosition pos)
|
|
||||||
{
|
|
||||||
GtkTextHandlePrivate *priv;
|
|
||||||
GdkRGBA bg = { 0, 0, 0, 0 };
|
|
||||||
GdkWindowAttr attributes;
|
|
||||||
GdkWindow *window;
|
|
||||||
GdkVisual *visual;
|
|
||||||
gint mask;
|
|
||||||
|
|
||||||
priv = handle->priv;
|
|
||||||
|
|
||||||
attributes.x = 0;
|
|
||||||
attributes.y = 0;
|
|
||||||
_gtk_text_handle_get_size (handle, &attributes.width, &attributes.height);
|
|
||||||
attributes.window_type = GDK_WINDOW_TEMP;
|
|
||||||
attributes.wclass = GDK_INPUT_OUTPUT;
|
|
||||||
attributes.event_mask = (GDK_EXPOSURE_MASK |
|
|
||||||
GDK_BUTTON_PRESS_MASK |
|
|
||||||
GDK_BUTTON_RELEASE_MASK |
|
|
||||||
GDK_BUTTON1_MOTION_MASK);
|
|
||||||
|
|
||||||
mask = GDK_WA_X | GDK_WA_Y;
|
|
||||||
|
|
||||||
visual = gdk_screen_get_rgba_visual (gtk_widget_get_screen (priv->parent));
|
|
||||||
|
|
||||||
if (visual)
|
|
||||||
{
|
|
||||||
attributes.visual = visual;
|
|
||||||
mask |= GDK_WA_VISUAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
window = gdk_window_new (gtk_widget_get_root_window (priv->parent),
|
|
||||||
&attributes, mask);
|
|
||||||
gtk_widget_register_window (priv->parent, window);
|
|
||||||
gdk_window_set_background_rgba (window, &bg);
|
|
||||||
|
|
||||||
_gtk_text_handle_update_shape (handle, window, pos);
|
|
||||||
|
|
||||||
return window;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -228,27 +151,15 @@ gtk_text_handle_widget_draw (GtkWidget *widget,
|
|||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
GtkTextHandle *handle)
|
GtkTextHandle *handle)
|
||||||
{
|
{
|
||||||
GtkTextHandlePrivate *priv;
|
gint pos;
|
||||||
GtkTextHandlePosition pos;
|
|
||||||
HandleWindow *handle_window;
|
|
||||||
|
|
||||||
priv = handle->priv;
|
pos = _text_handle_pos_from_widget (handle, widget);
|
||||||
|
|
||||||
if (!priv->realized)
|
if (pos < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (gtk_cairo_should_draw_window (cr, priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window))
|
_gtk_text_handle_draw (handle, cr, pos);
|
||||||
pos = GTK_TEXT_HANDLE_POSITION_SELECTION_START;
|
return TRUE;
|
||||||
else if (gtk_cairo_should_draw_window (cr, priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].window))
|
|
||||||
pos = GTK_TEXT_HANDLE_POSITION_SELECTION_END;
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
handle_window = &priv->windows[pos];
|
|
||||||
if (gdk_window_is_visible (handle_window->window))
|
|
||||||
_gtk_text_handle_draw (handle, cr, pos);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -257,15 +168,12 @@ gtk_text_handle_widget_event (GtkWidget *widget,
|
|||||||
GtkTextHandle *handle)
|
GtkTextHandle *handle)
|
||||||
{
|
{
|
||||||
GtkTextHandlePrivate *priv;
|
GtkTextHandlePrivate *priv;
|
||||||
GtkTextHandlePosition pos;
|
gint pos;
|
||||||
|
|
||||||
priv = handle->priv;
|
priv = handle->priv;
|
||||||
|
pos = _text_handle_pos_from_widget (handle, widget);
|
||||||
|
|
||||||
if (event->any.window == priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window)
|
if (pos < 0)
|
||||||
pos = GTK_TEXT_HANDLE_POSITION_SELECTION_START;
|
|
||||||
else if (event->any.window == priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].window)
|
|
||||||
pos = GTK_TEXT_HANDLE_POSITION_SELECTION_END;
|
|
||||||
else
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (event->type == GDK_BUTTON_PRESS)
|
if (event->type == GDK_BUTTON_PRESS)
|
||||||
@@ -277,24 +185,24 @@ gtk_text_handle_widget_event (GtkWidget *widget,
|
|||||||
else if (event->type == GDK_BUTTON_RELEASE)
|
else if (event->type == GDK_BUTTON_RELEASE)
|
||||||
{
|
{
|
||||||
g_signal_emit (handle, signals[DRAG_FINISHED], 0, pos);
|
g_signal_emit (handle, signals[DRAG_FINISHED], 0, pos);
|
||||||
priv->windows[pos].dx = priv->windows[pos].dy = 0;
|
|
||||||
priv->windows[pos].dragged = FALSE;
|
priv->windows[pos].dragged = FALSE;
|
||||||
}
|
}
|
||||||
else if (event->type == GDK_MOTION_NOTIFY && priv->windows[pos].dragged)
|
else if (event->type == GDK_MOTION_NOTIFY &&
|
||||||
|
event->motion.state & GDK_BUTTON1_MASK &&
|
||||||
|
priv->windows[pos].dragged)
|
||||||
{
|
{
|
||||||
gint x, y, width, height;
|
gint x, y, width, height;
|
||||||
|
|
||||||
_gtk_text_handle_get_size (handle, &width, &height);
|
_gtk_text_handle_get_size (handle, &width, &height);
|
||||||
gdk_window_get_origin (priv->relative_to, &x, &y);
|
x = event->motion.x - priv->windows[pos].dx + (width / 2);
|
||||||
|
y = event->motion.y - priv->windows[pos].dy;
|
||||||
|
|
||||||
x = event->motion.x_root - priv->windows[pos].dx + (width / 2) - x;
|
if (pos != GTK_TEXT_HANDLE_POSITION_CURSOR)
|
||||||
y = event->motion.y_root - priv->windows[pos].dy - y;
|
|
||||||
|
|
||||||
if (pos == GTK_TEXT_HANDLE_POSITION_SELECTION_START)
|
|
||||||
y += height;
|
y += height;
|
||||||
|
|
||||||
y += priv->windows[pos].pointing_to.height / 2;
|
y += priv->windows[pos].pointing_to.height / 2;
|
||||||
|
|
||||||
|
gtk_widget_translate_coordinates (widget, priv->parent, x, y, &x, &y);
|
||||||
g_signal_emit (handle, signals[HANDLE_DRAGGED], 0, pos, x, y);
|
g_signal_emit (handle, signals[HANDLE_DRAGGED], 0, pos, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,8 +210,84 @@ gtk_text_handle_widget_event (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_gtk_text_handle_update_window_state (GtkTextHandle *handle,
|
gtk_text_handle_widget_style_updated (GtkWidget *widget,
|
||||||
GtkTextHandlePosition pos)
|
GtkTextHandle *handle)
|
||||||
|
{
|
||||||
|
_gtk_text_handle_update (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
||||||
|
_gtk_text_handle_update (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
_gtk_text_handle_ensure_widget (GtkTextHandle *handle,
|
||||||
|
GtkTextHandlePosition pos)
|
||||||
|
{
|
||||||
|
GtkTextHandlePrivate *priv;
|
||||||
|
|
||||||
|
priv = handle->priv;
|
||||||
|
|
||||||
|
if (!priv->windows[pos].widget)
|
||||||
|
{
|
||||||
|
GtkWidget *widget, *window;
|
||||||
|
|
||||||
|
widget = gtk_event_box_new ();
|
||||||
|
gtk_widget_set_events (widget,
|
||||||
|
GDK_BUTTON_PRESS_MASK |
|
||||||
|
GDK_BUTTON_RELEASE_MASK |
|
||||||
|
GDK_POINTER_MOTION_MASK);
|
||||||
|
|
||||||
|
g_signal_connect (widget, "draw",
|
||||||
|
G_CALLBACK (gtk_text_handle_widget_draw), handle);
|
||||||
|
g_signal_connect (widget, "event",
|
||||||
|
G_CALLBACK (gtk_text_handle_widget_event), handle);
|
||||||
|
g_signal_connect (widget, "style-updated",
|
||||||
|
G_CALLBACK (gtk_text_handle_widget_style_updated),
|
||||||
|
handle);
|
||||||
|
|
||||||
|
priv->windows[pos].widget = g_object_ref_sink (widget);
|
||||||
|
window = gtk_widget_get_ancestor (priv->parent, GTK_TYPE_WINDOW);
|
||||||
|
_gtk_window_add_popover (GTK_WINDOW (window), widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
return priv->windows[pos].widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_handle_update_child_visible (GtkTextHandle *handle,
|
||||||
|
GtkTextHandlePosition pos)
|
||||||
|
{
|
||||||
|
HandleWindow *handle_window;
|
||||||
|
GtkTextHandlePrivate *priv;
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
GtkAllocation allocation;
|
||||||
|
GtkWidget *parent;
|
||||||
|
|
||||||
|
priv = handle->priv;
|
||||||
|
handle_window = &priv->windows[pos];
|
||||||
|
|
||||||
|
if (!priv->parent_scrollable)
|
||||||
|
{
|
||||||
|
gtk_widget_set_child_visible (handle_window->widget, TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent = gtk_widget_get_parent (GTK_WIDGET (priv->parent_scrollable));
|
||||||
|
rect = handle_window->pointing_to;
|
||||||
|
|
||||||
|
gtk_widget_translate_coordinates (priv->parent, parent,
|
||||||
|
rect.x, rect.y, &rect.x, &rect.y);
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (GTK_WIDGET (parent), &allocation);
|
||||||
|
|
||||||
|
if (rect.x < 0 || rect.x + rect.width > allocation.width ||
|
||||||
|
rect.y < 0 || rect.y + rect.height > allocation.height)
|
||||||
|
gtk_widget_set_child_visible (handle_window->widget, FALSE);
|
||||||
|
else
|
||||||
|
gtk_widget_set_child_visible (handle_window->widget, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_text_handle_update (GtkTextHandle *handle,
|
||||||
|
GtkTextHandlePosition pos)
|
||||||
{
|
{
|
||||||
GtkTextHandlePrivate *priv;
|
GtkTextHandlePrivate *priv;
|
||||||
HandleWindow *handle_window;
|
HandleWindow *handle_window;
|
||||||
@@ -311,93 +295,209 @@ _gtk_text_handle_update_window_state (GtkTextHandle *handle,
|
|||||||
priv = handle->priv;
|
priv = handle->priv;
|
||||||
handle_window = &priv->windows[pos];
|
handle_window = &priv->windows[pos];
|
||||||
|
|
||||||
if (!handle_window->window)
|
if (!priv->parent || !gtk_widget_is_drawable (priv->parent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (handle_window->has_point &&
|
if (handle_window->has_point &&
|
||||||
handle_window->mode_visible && handle_window->user_visible)
|
handle_window->mode_visible && handle_window->user_visible)
|
||||||
{
|
{
|
||||||
gint x, y, width, height;
|
cairo_rectangle_int_t rect;
|
||||||
|
GtkPositionType handle_pos;
|
||||||
|
gint width, height;
|
||||||
|
GtkWidget *window;
|
||||||
|
|
||||||
x = handle_window->pointing_to.x;
|
_gtk_text_handle_ensure_widget (handle, pos);
|
||||||
y = handle_window->pointing_to.y;
|
|
||||||
_gtk_text_handle_get_size (handle, &width, &height);
|
_gtk_text_handle_get_size (handle, &width, &height);
|
||||||
|
rect.x = handle_window->pointing_to.x;
|
||||||
|
rect.y = handle_window->pointing_to.y;
|
||||||
|
rect.width = width;
|
||||||
|
rect.height = 0;
|
||||||
|
|
||||||
if (pos != GTK_TEXT_HANDLE_POSITION_CURSOR)
|
_handle_update_child_visible (handle, pos);
|
||||||
y -= height;
|
|
||||||
|
window = gtk_widget_get_parent (handle_window->widget);
|
||||||
|
gtk_widget_translate_coordinates (priv->parent, window,
|
||||||
|
rect.x, rect.y, &rect.x, &rect.y);
|
||||||
|
|
||||||
|
if (pos == GTK_TEXT_HANDLE_POSITION_CURSOR)
|
||||||
|
handle_pos = GTK_POS_BOTTOM;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle_pos = GTK_POS_TOP;
|
||||||
|
rect.y += handle_window->pointing_to.height;
|
||||||
|
}
|
||||||
|
|
||||||
height += handle_window->pointing_to.height;
|
height += handle_window->pointing_to.height;
|
||||||
x -= width / 2;
|
rect.x -= rect.width / 2;
|
||||||
|
|
||||||
gdk_window_move_resize (handle_window->window, x, y, width, height);
|
gtk_widget_set_size_request (handle_window->widget, width, height);
|
||||||
gdk_window_show (handle_window->window);
|
gtk_widget_show (handle_window->widget);
|
||||||
|
_gtk_window_set_popover_position (GTK_WINDOW (window),
|
||||||
|
handle_window->widget,
|
||||||
|
handle_pos, &rect);
|
||||||
}
|
}
|
||||||
else
|
else if (handle_window->widget)
|
||||||
gdk_window_hide (handle_window->window);
|
gtk_widget_hide (handle_window->widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_gtk_text_handle_update_window (GtkTextHandle *handle,
|
adjustment_changed_cb (GtkAdjustment *adjustment,
|
||||||
GtkTextHandlePosition pos,
|
GtkTextHandle *handle)
|
||||||
gboolean recreate)
|
{
|
||||||
|
_gtk_text_handle_update (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
||||||
|
_gtk_text_handle_update (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_text_handle_set_scrollable (GtkTextHandle *handle,
|
||||||
|
GtkScrollable *scrollable)
|
||||||
{
|
{
|
||||||
GtkTextHandlePrivate *priv;
|
GtkTextHandlePrivate *priv;
|
||||||
HandleWindow *handle_window;
|
|
||||||
|
|
||||||
priv = handle->priv;
|
priv = handle->priv;
|
||||||
handle_window = &priv->windows[pos];
|
|
||||||
|
|
||||||
if (!handle_window->window)
|
if (priv->parent_scrollable)
|
||||||
return;
|
|
||||||
|
|
||||||
if (recreate)
|
|
||||||
{
|
{
|
||||||
gtk_widget_unregister_window (priv->parent, handle_window->window);
|
if (priv->vadj)
|
||||||
gdk_window_destroy (handle_window->window);
|
{
|
||||||
handle_window->window = _gtk_text_handle_create_window (handle, pos);
|
g_signal_handlers_disconnect_by_data (priv->vadj, handle);
|
||||||
|
g_object_unref (priv->vadj);
|
||||||
|
priv->vadj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->hadj)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_data (priv->hadj, handle);
|
||||||
|
g_object_unref (priv->hadj);
|
||||||
|
priv->hadj = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_gtk_text_handle_update_window_state (handle, pos);
|
priv->parent_scrollable = scrollable;
|
||||||
|
|
||||||
|
if (scrollable)
|
||||||
|
{
|
||||||
|
priv->vadj = gtk_scrollable_get_vadjustment (scrollable);
|
||||||
|
priv->hadj = gtk_scrollable_get_hadjustment (scrollable);
|
||||||
|
|
||||||
|
if (priv->vadj)
|
||||||
|
{
|
||||||
|
g_object_ref (priv->vadj);
|
||||||
|
g_signal_connect (priv->vadj, "changed",
|
||||||
|
G_CALLBACK (adjustment_changed_cb), handle);
|
||||||
|
g_signal_connect (priv->vadj, "value-changed",
|
||||||
|
G_CALLBACK (adjustment_changed_cb), handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->hadj)
|
||||||
|
{
|
||||||
|
g_object_ref (priv->hadj);
|
||||||
|
g_signal_connect (priv->hadj, "changed",
|
||||||
|
G_CALLBACK (adjustment_changed_cb), handle);
|
||||||
|
g_signal_connect (priv->hadj, "value-changed",
|
||||||
|
G_CALLBACK (adjustment_changed_cb), handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_gtk_text_handle_update_windows (GtkTextHandle *handle)
|
_gtk_text_handle_scrollable_notify (GObject *object,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
GtkTextHandle *handle)
|
||||||
{
|
{
|
||||||
_gtk_text_handle_update_window (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_START, FALSE);
|
if (pspec->value_type == GTK_TYPE_ADJUSTMENT)
|
||||||
_gtk_text_handle_update_window (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_END, FALSE);
|
_gtk_text_handle_set_scrollable (handle, GTK_SCROLLABLE (object));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_gtk_text_handle_composited_changed (GtkTextHandle *handle)
|
_gtk_text_handle_update_scrollable (GtkTextHandle *handle,
|
||||||
{
|
GtkScrollable *scrollable)
|
||||||
_gtk_text_handle_update_window (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_START, TRUE);
|
|
||||||
_gtk_text_handle_update_window (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_END, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_text_handle_constructed (GObject *object)
|
|
||||||
{
|
{
|
||||||
GtkTextHandlePrivate *priv;
|
GtkTextHandlePrivate *priv;
|
||||||
|
|
||||||
priv = GTK_TEXT_HANDLE (object)->priv;
|
priv = handle->priv;
|
||||||
g_assert (priv->parent != NULL);
|
|
||||||
|
|
||||||
priv->draw_signal_id =
|
if (priv->parent_scrollable == scrollable)
|
||||||
g_signal_connect (priv->parent, "draw",
|
return;
|
||||||
G_CALLBACK (gtk_text_handle_widget_draw),
|
|
||||||
object);
|
if (priv->parent_scrollable && priv->scrollable_notify_id &&
|
||||||
priv->event_signal_id =
|
g_signal_handler_is_connected (priv->parent_scrollable,
|
||||||
g_signal_connect (priv->parent, "event",
|
priv->scrollable_notify_id))
|
||||||
G_CALLBACK (gtk_text_handle_widget_event),
|
g_signal_handler_disconnect (priv->parent_scrollable,
|
||||||
object);
|
priv->scrollable_notify_id);
|
||||||
priv->composited_changed_id =
|
|
||||||
g_signal_connect_swapped (priv->parent, "composited-changed",
|
_gtk_text_handle_set_scrollable (handle, scrollable);
|
||||||
G_CALLBACK (_gtk_text_handle_composited_changed),
|
|
||||||
object);
|
if (priv->parent_scrollable)
|
||||||
priv->style_updated_id =
|
priv->scrollable_notify_id =
|
||||||
g_signal_connect_swapped (priv->parent, "style-updated",
|
g_signal_connect (priv->parent_scrollable, "notify",
|
||||||
G_CALLBACK (_gtk_text_handle_update_windows),
|
G_CALLBACK (_gtk_text_handle_scrollable_notify),
|
||||||
object);
|
handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_text_handle_parent_hierarchy_changed (GtkWidget *widget,
|
||||||
|
GtkWindow *previous_toplevel,
|
||||||
|
GtkTextHandle *handle)
|
||||||
|
{
|
||||||
|
GtkWidget *toplevel, *scrollable;
|
||||||
|
GtkTextHandlePrivate *priv;
|
||||||
|
|
||||||
|
priv = handle->priv;
|
||||||
|
toplevel = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
|
||||||
|
|
||||||
|
if (previous_toplevel && !toplevel)
|
||||||
|
{
|
||||||
|
if (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget)
|
||||||
|
{
|
||||||
|
_gtk_window_remove_popover (GTK_WINDOW (previous_toplevel),
|
||||||
|
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget);
|
||||||
|
g_object_unref (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget);
|
||||||
|
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget)
|
||||||
|
{
|
||||||
|
_gtk_window_remove_popover (GTK_WINDOW (previous_toplevel),
|
||||||
|
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget);
|
||||||
|
g_object_unref (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget);
|
||||||
|
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollable = gtk_widget_get_ancestor (widget, GTK_TYPE_SCROLLABLE);
|
||||||
|
_gtk_text_handle_update_scrollable (handle, GTK_SCROLLABLE (scrollable));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_text_handle_set_parent (GtkTextHandle *handle,
|
||||||
|
GtkWidget *parent)
|
||||||
|
{
|
||||||
|
GtkTextHandlePrivate *priv;
|
||||||
|
GtkWidget *scrollable = NULL;
|
||||||
|
|
||||||
|
priv = handle->priv;
|
||||||
|
|
||||||
|
if (priv->parent == parent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (priv->parent && priv->hierarchy_changed_id &&
|
||||||
|
g_signal_handler_is_connected (priv->parent, priv->hierarchy_changed_id))
|
||||||
|
g_signal_handler_disconnect (priv->parent, priv->hierarchy_changed_id);
|
||||||
|
|
||||||
|
priv->parent = parent;
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
priv->hierarchy_changed_id =
|
||||||
|
g_signal_connect (parent, "hierarchy-changed",
|
||||||
|
G_CALLBACK (_gtk_text_handle_parent_hierarchy_changed),
|
||||||
|
handle);
|
||||||
|
|
||||||
|
scrollable = gtk_widget_get_ancestor (parent, GTK_TYPE_SCROLLABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
_gtk_text_handle_update_scrollable (handle, GTK_SCROLLABLE (scrollable));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -407,34 +507,14 @@ gtk_text_handle_finalize (GObject *object)
|
|||||||
|
|
||||||
priv = GTK_TEXT_HANDLE (object)->priv;
|
priv = GTK_TEXT_HANDLE (object)->priv;
|
||||||
|
|
||||||
if (priv->relative_to)
|
_gtk_text_handle_set_parent (GTK_TEXT_HANDLE (object), NULL);
|
||||||
g_object_unref (priv->relative_to);
|
|
||||||
|
|
||||||
if (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window)
|
/* We sank the references, unref here */
|
||||||
{
|
if (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget)
|
||||||
gtk_widget_unregister_window (priv->parent,
|
g_object_unref (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].widget);
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window);
|
|
||||||
gdk_window_destroy (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].window)
|
if (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget)
|
||||||
{
|
g_object_unref (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].widget);
|
||||||
gtk_widget_unregister_window (priv->parent,
|
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].window);
|
|
||||||
gdk_window_destroy (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].window);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_signal_handler_is_connected (priv->parent, priv->draw_signal_id))
|
|
||||||
g_signal_handler_disconnect (priv->parent, priv->draw_signal_id);
|
|
||||||
|
|
||||||
if (g_signal_handler_is_connected (priv->parent, priv->event_signal_id))
|
|
||||||
g_signal_handler_disconnect (priv->parent, priv->event_signal_id);
|
|
||||||
|
|
||||||
if (g_signal_handler_is_connected (priv->parent, priv->composited_changed_id))
|
|
||||||
g_signal_handler_disconnect (priv->parent, priv->composited_changed_id);
|
|
||||||
|
|
||||||
if (g_signal_handler_is_connected (priv->parent, priv->style_updated_id))
|
|
||||||
g_signal_handler_disconnect (priv->parent, priv->style_updated_id);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (_gtk_text_handle_parent_class)->finalize (object);
|
G_OBJECT_CLASS (_gtk_text_handle_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -445,20 +525,14 @@ gtk_text_handle_set_property (GObject *object,
|
|||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GtkTextHandlePrivate *priv;
|
|
||||||
GtkTextHandle *handle;
|
GtkTextHandle *handle;
|
||||||
|
|
||||||
handle = GTK_TEXT_HANDLE (object);
|
handle = GTK_TEXT_HANDLE (object);
|
||||||
priv = handle->priv;
|
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_PARENT:
|
case PROP_PARENT:
|
||||||
priv->parent = g_value_get_object (value);
|
_gtk_text_handle_set_parent (handle, g_value_get_object (value));
|
||||||
break;
|
|
||||||
case PROP_RELATIVE_TO:
|
|
||||||
_gtk_text_handle_set_relative_to (handle,
|
|
||||||
g_value_get_object (value));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@@ -480,9 +554,6 @@ gtk_text_handle_get_property (GObject *object,
|
|||||||
case PROP_PARENT:
|
case PROP_PARENT:
|
||||||
g_value_set_object (value, priv->parent);
|
g_value_set_object (value, priv->parent);
|
||||||
break;
|
break;
|
||||||
case PROP_RELATIVE_TO:
|
|
||||||
g_value_set_object (value, priv->relative_to);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
}
|
}
|
||||||
@@ -493,7 +564,6 @@ _gtk_text_handle_class_init (GtkTextHandleClass *klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->constructed = gtk_text_handle_constructed;
|
|
||||||
object_class->finalize = gtk_text_handle_finalize;
|
object_class->finalize = gtk_text_handle_finalize;
|
||||||
object_class->set_property = gtk_text_handle_set_property;
|
object_class->set_property = gtk_text_handle_set_property;
|
||||||
object_class->get_property = gtk_text_handle_get_property;
|
object_class->get_property = gtk_text_handle_get_property;
|
||||||
@@ -525,13 +595,6 @@ _gtk_text_handle_class_init (GtkTextHandleClass *klass)
|
|||||||
GTK_TYPE_WIDGET,
|
GTK_TYPE_WIDGET,
|
||||||
GTK_PARAM_READWRITE |
|
GTK_PARAM_READWRITE |
|
||||||
G_PARAM_CONSTRUCT_ONLY));
|
G_PARAM_CONSTRUCT_ONLY));
|
||||||
g_object_class_install_property (object_class,
|
|
||||||
PROP_RELATIVE_TO,
|
|
||||||
g_param_spec_object ("relative-to",
|
|
||||||
P_("Window"),
|
|
||||||
P_("Window the coordinates are based upon"),
|
|
||||||
GDK_TYPE_WINDOW,
|
|
||||||
GTK_PARAM_READWRITE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -548,48 +611,6 @@ _gtk_text_handle_new (GtkWidget *parent)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
_gtk_text_handle_set_relative_to (GtkTextHandle *handle,
|
|
||||||
GdkWindow *window)
|
|
||||||
{
|
|
||||||
GtkTextHandlePrivate *priv;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_TEXT_HANDLE (handle));
|
|
||||||
g_return_if_fail (!window || GDK_IS_WINDOW (window));
|
|
||||||
|
|
||||||
priv = handle->priv;
|
|
||||||
|
|
||||||
if (priv->relative_to)
|
|
||||||
{
|
|
||||||
gtk_widget_unregister_window (priv->parent,
|
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window);
|
|
||||||
gdk_window_destroy (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window);
|
|
||||||
gtk_widget_unregister_window (priv->parent,
|
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].window);
|
|
||||||
gdk_window_destroy (priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].window);
|
|
||||||
g_object_unref (priv->relative_to);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window)
|
|
||||||
{
|
|
||||||
priv->relative_to = g_object_ref (window);
|
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window =
|
|
||||||
_gtk_text_handle_create_window (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].window =
|
|
||||||
_gtk_text_handle_create_window (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_END);
|
|
||||||
priv->realized = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window = NULL;
|
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_END].window = NULL;
|
|
||||||
priv->relative_to = NULL;
|
|
||||||
priv->realized = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (handle), "relative-to");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_gtk_text_handle_set_mode (GtkTextHandle *handle,
|
_gtk_text_handle_set_mode (GtkTextHandle *handle,
|
||||||
GtkTextHandleMode mode)
|
GtkTextHandleMode mode)
|
||||||
@@ -622,15 +643,8 @@ _gtk_text_handle_set_mode (GtkTextHandle *handle,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_gtk_text_handle_update_shape (handle,
|
_gtk_text_handle_update (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_CURSOR].window,
|
_gtk_text_handle_update (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_END);
|
||||||
GTK_TEXT_HANDLE_POSITION_CURSOR);
|
|
||||||
_gtk_text_handle_update_shape (handle,
|
|
||||||
priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window,
|
|
||||||
GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
|
||||||
|
|
||||||
_gtk_text_handle_update_window_state (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
|
||||||
_gtk_text_handle_update_window_state (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_END);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkTextHandleMode
|
GtkTextHandleMode
|
||||||
@@ -651,7 +665,6 @@ _gtk_text_handle_set_position (GtkTextHandle *handle,
|
|||||||
{
|
{
|
||||||
GtkTextHandlePrivate *priv;
|
GtkTextHandlePrivate *priv;
|
||||||
HandleWindow *handle_window;
|
HandleWindow *handle_window;
|
||||||
gboolean size_changed;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_TEXT_HANDLE (handle));
|
g_return_if_fail (GTK_IS_TEXT_HANDLE (handle));
|
||||||
|
|
||||||
@@ -660,28 +673,16 @@ _gtk_text_handle_set_position (GtkTextHandle *handle,
|
|||||||
GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
||||||
handle_window = &priv->windows[pos];
|
handle_window = &priv->windows[pos];
|
||||||
|
|
||||||
if (!priv->realized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (priv->mode == GTK_TEXT_HANDLE_MODE_NONE ||
|
if (priv->mode == GTK_TEXT_HANDLE_MODE_NONE ||
|
||||||
(priv->mode == GTK_TEXT_HANDLE_MODE_CURSOR &&
|
(priv->mode == GTK_TEXT_HANDLE_MODE_CURSOR &&
|
||||||
pos != GTK_TEXT_HANDLE_POSITION_CURSOR))
|
pos != GTK_TEXT_HANDLE_POSITION_CURSOR))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
size_changed = (rect->width != handle_window->pointing_to.width ||
|
|
||||||
rect->height != handle_window->pointing_to.height);
|
|
||||||
|
|
||||||
handle_window->pointing_to = *rect;
|
handle_window->pointing_to = *rect;
|
||||||
handle_window->has_point = TRUE;
|
handle_window->has_point = TRUE;
|
||||||
gdk_window_get_root_coords (priv->relative_to,
|
|
||||||
rect->x, rect->y,
|
|
||||||
&handle_window->pointing_to.x,
|
|
||||||
&handle_window->pointing_to.y);
|
|
||||||
|
|
||||||
_gtk_text_handle_update_window_state (handle, pos);
|
if (gtk_widget_is_visible (priv->parent))
|
||||||
|
_gtk_text_handle_update (handle, pos);
|
||||||
if (size_changed)
|
|
||||||
_gtk_text_handle_update_shape (handle, handle_window->window, pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -690,7 +691,6 @@ _gtk_text_handle_set_visible (GtkTextHandle *handle,
|
|||||||
gboolean visible)
|
gboolean visible)
|
||||||
{
|
{
|
||||||
GtkTextHandlePrivate *priv;
|
GtkTextHandlePrivate *priv;
|
||||||
GdkWindow *window;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_TEXT_HANDLE (handle));
|
g_return_if_fail (GTK_IS_TEXT_HANDLE (handle));
|
||||||
|
|
||||||
@@ -698,19 +698,10 @@ _gtk_text_handle_set_visible (GtkTextHandle *handle,
|
|||||||
pos = CLAMP (pos, GTK_TEXT_HANDLE_POSITION_CURSOR,
|
pos = CLAMP (pos, GTK_TEXT_HANDLE_POSITION_CURSOR,
|
||||||
GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
GTK_TEXT_HANDLE_POSITION_SELECTION_START);
|
||||||
|
|
||||||
if (!priv->realized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
window = priv->windows[pos].window;
|
|
||||||
|
|
||||||
if (!window)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!gdk_window_is_visible (window))
|
|
||||||
_gtk_text_handle_update_shape (handle, window, pos);
|
|
||||||
|
|
||||||
priv->windows[pos].user_visible = visible;
|
priv->windows[pos].user_visible = visible;
|
||||||
_gtk_text_handle_update_window_state (handle, pos);
|
|
||||||
|
if (gtk_widget_is_visible (priv->parent))
|
||||||
|
_gtk_text_handle_update (handle, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@@ -51,9 +51,10 @@
|
|||||||
#include "gtktexthandleprivate.h"
|
#include "gtktexthandleprivate.h"
|
||||||
#include "gtkstylecontextprivate.h"
|
#include "gtkstylecontextprivate.h"
|
||||||
#include "gtkcssstylepropertyprivate.h"
|
#include "gtkcssstylepropertyprivate.h"
|
||||||
#include "gtkbubblewindowprivate.h"
|
#include "gtkpopover.h"
|
||||||
#include "gtktoolbar.h"
|
#include "gtktoolbar.h"
|
||||||
#include "gtkpixelcacheprivate.h"
|
#include "gtkpixelcacheprivate.h"
|
||||||
|
#include "gtkmagnifierprivate.h"
|
||||||
|
|
||||||
#include "a11y/gtktextviewaccessibleprivate.h"
|
#include "a11y/gtktextviewaccessibleprivate.h"
|
||||||
|
|
||||||
@@ -140,6 +141,9 @@ struct _GtkTextViewPrivate
|
|||||||
GtkWidget *selection_bubble;
|
GtkWidget *selection_bubble;
|
||||||
guint selection_bubble_timeout_id;
|
guint selection_bubble_timeout_id;
|
||||||
|
|
||||||
|
GtkWidget *magnifier_popover;
|
||||||
|
GtkWidget *magnifier;
|
||||||
|
|
||||||
GtkTextWindow *text_window;
|
GtkTextWindow *text_window;
|
||||||
GtkTextWindow *left_window;
|
GtkTextWindow *left_window;
|
||||||
GtkTextWindow *right_window;
|
GtkTextWindow *right_window;
|
||||||
@@ -1542,6 +1546,18 @@ gtk_text_view_init (GtkTextView *text_view)
|
|||||||
G_CALLBACK (gtk_text_view_handle_dragged), text_view);
|
G_CALLBACK (gtk_text_view_handle_dragged), text_view);
|
||||||
g_signal_connect (priv->text_handle, "drag-finished",
|
g_signal_connect (priv->text_handle, "drag-finished",
|
||||||
G_CALLBACK (gtk_text_view_handle_drag_finished), text_view);
|
G_CALLBACK (gtk_text_view_handle_drag_finished), text_view);
|
||||||
|
|
||||||
|
priv->magnifier = _gtk_magnifier_new (widget);
|
||||||
|
gtk_widget_set_size_request (priv->magnifier, 100, 60);
|
||||||
|
_gtk_magnifier_set_magnification (GTK_MAGNIFIER (priv->magnifier), 2.0);
|
||||||
|
priv->magnifier_popover = gtk_popover_new (widget);
|
||||||
|
gtk_style_context_add_class (gtk_widget_get_style_context (priv->magnifier_popover),
|
||||||
|
GTK_STYLE_CLASS_OSD);
|
||||||
|
gtk_popover_set_modal (GTK_POPOVER (priv->magnifier_popover), FALSE);
|
||||||
|
gtk_container_add (GTK_CONTAINER (priv->magnifier_popover),
|
||||||
|
priv->magnifier);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (priv->magnifier_popover), 4);
|
||||||
|
gtk_widget_show (priv->magnifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3215,6 +3231,7 @@ gtk_text_view_finalize (GObject *object)
|
|||||||
if (priv->selection_bubble)
|
if (priv->selection_bubble)
|
||||||
gtk_widget_destroy (priv->selection_bubble);
|
gtk_widget_destroy (priv->selection_bubble);
|
||||||
|
|
||||||
|
gtk_widget_destroy (priv->magnifier_popover);
|
||||||
g_object_unref (priv->text_handle);
|
g_object_unref (priv->text_handle);
|
||||||
g_object_unref (priv->im_context);
|
g_object_unref (priv->im_context);
|
||||||
|
|
||||||
@@ -4237,8 +4254,6 @@ gtk_text_view_realize (GtkWidget *widget)
|
|||||||
|
|
||||||
/* Ensure updating the spot location. */
|
/* Ensure updating the spot location. */
|
||||||
gtk_text_view_update_im_spot_location (text_view);
|
gtk_text_view_update_im_spot_location (text_view);
|
||||||
|
|
||||||
_gtk_text_handle_set_relative_to (priv->text_handle, priv->text_window->window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4279,8 +4294,6 @@ gtk_text_view_unrealize (GtkWidget *widget)
|
|||||||
if (priv->bottom_window)
|
if (priv->bottom_window)
|
||||||
text_window_unrealize (priv->bottom_window);
|
text_window_unrealize (priv->bottom_window);
|
||||||
|
|
||||||
_gtk_text_handle_set_relative_to (priv->text_handle, NULL);
|
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_text_view_parent_class)->unrealize (widget);
|
GTK_WIDGET_CLASS (gtk_text_view_parent_class)->unrealize (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4588,6 +4601,30 @@ gtk_text_view_set_handle_position (GtkTextView *text_view,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_text_view_show_magnifier (GtkTextView *text_view,
|
||||||
|
gint x,
|
||||||
|
gint y)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
GtkTextViewPrivate *priv;
|
||||||
|
GtkAllocation allocation;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (GTK_WIDGET (text_view), &allocation);
|
||||||
|
|
||||||
|
priv = text_view->priv;
|
||||||
|
x = CLAMP (x, 0, allocation.width);
|
||||||
|
y = CLAMP (y, 0, allocation.height);
|
||||||
|
rect.x = x;
|
||||||
|
rect.y = y;
|
||||||
|
rect.width = rect.height = 1;
|
||||||
|
|
||||||
|
_gtk_magnifier_set_coords (GTK_MAGNIFIER (priv->magnifier), x, y);
|
||||||
|
gtk_popover_set_pointing_to (GTK_POPOVER (priv->magnifier_popover),
|
||||||
|
&rect);
|
||||||
|
gtk_widget_show (priv->magnifier_popover);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_text_view_handle_dragged (GtkTextHandle *handle,
|
gtk_text_view_handle_dragged (GtkTextHandle *handle,
|
||||||
GtkTextHandlePosition pos,
|
GtkTextHandlePosition pos,
|
||||||
@@ -4672,6 +4709,8 @@ gtk_text_view_handle_dragged (GtkTextHandle *handle,
|
|||||||
gtk_text_view_scroll_mark_onscreen (text_view,
|
gtk_text_view_scroll_mark_onscreen (text_view,
|
||||||
gtk_text_buffer_get_selection_bound (buffer));
|
gtk_text_buffer_get_selection_bound (buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gtk_text_view_show_magnifier (text_view, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4680,6 +4719,7 @@ gtk_text_view_handle_drag_finished (GtkTextHandle *handle,
|
|||||||
GtkTextView *text_view)
|
GtkTextView *text_view)
|
||||||
{
|
{
|
||||||
gtk_text_view_selection_bubble_popup_set (text_view);
|
gtk_text_view_selection_bubble_popup_set (text_view);
|
||||||
|
gtk_widget_hide (text_view->priv->magnifier_popover);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -6948,7 +6988,10 @@ selection_motion_event_handler (GtkTextView *text_view,
|
|||||||
g_source_set_name_by_id (text_view->priv->scroll_timeout, "[gtk+] selection_scan_timeout");
|
g_source_set_name_by_id (text_view->priv->scroll_timeout, "[gtk+] selection_scan_timeout");
|
||||||
|
|
||||||
if (test_touchscreen || input_source == GDK_SOURCE_TOUCHSCREEN)
|
if (test_touchscreen || input_source == GDK_SOURCE_TOUCHSCREEN)
|
||||||
gtk_text_view_update_handles (text_view, GTK_TEXT_HANDLE_MODE_SELECTION);
|
{
|
||||||
|
gtk_text_view_update_handles (text_view, GTK_TEXT_HANDLE_MODE_SELECTION);
|
||||||
|
gtk_text_view_show_magnifier (text_view, event->x, event->y);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -7068,6 +7111,8 @@ gtk_text_view_end_selection_drag (GtkTextView *text_view)
|
|||||||
priv->grab_device);
|
priv->grab_device);
|
||||||
priv->grab_device = NULL;
|
priv->grab_device = NULL;
|
||||||
|
|
||||||
|
gtk_widget_hide (priv->magnifier_popover);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8857,7 +8902,7 @@ activate_bubble_cb (GtkWidget *item,
|
|||||||
{
|
{
|
||||||
const gchar *signal = g_object_get_data (G_OBJECT (item), "gtk-signal");
|
const gchar *signal = g_object_get_data (G_OBJECT (item), "gtk-signal");
|
||||||
g_signal_emit_by_name (text_view, signal);
|
g_signal_emit_by_name (text_view, signal);
|
||||||
_gtk_bubble_window_popdown (GTK_BUBBLE_WINDOW (text_view->priv->selection_bubble));
|
gtk_widget_hide (text_view->priv->selection_bubble);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -8868,6 +8913,7 @@ append_bubble_action (GtkTextView *text_view,
|
|||||||
gboolean sensitive)
|
gboolean sensitive)
|
||||||
{
|
{
|
||||||
GtkToolItem *item = gtk_tool_button_new (NULL, label);
|
GtkToolItem *item = gtk_tool_button_new (NULL, label);
|
||||||
|
gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (item), TRUE);
|
||||||
g_object_set_data (G_OBJECT (item), I_("gtk-signal"), (char *)signal);
|
g_object_set_data (G_OBJECT (item), I_("gtk-signal"), (char *)signal);
|
||||||
g_signal_connect (item, "clicked", G_CALLBACK (activate_bubble_cb), text_view);
|
g_signal_connect (item, "clicked", G_CALLBACK (activate_bubble_cb), text_view);
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (item), sensitive);
|
gtk_widget_set_sensitive (GTK_WIDGET (item), sensitive);
|
||||||
@@ -8888,7 +8934,6 @@ bubble_targets_received (GtkClipboard *clipboard,
|
|||||||
gboolean can_insert;
|
gboolean can_insert;
|
||||||
GtkTextIter iter;
|
GtkTextIter iter;
|
||||||
GtkTextIter sel_start, sel_end;
|
GtkTextIter sel_start, sel_end;
|
||||||
GdkWindow *window;
|
|
||||||
GtkWidget *toolbar;
|
GtkWidget *toolbar;
|
||||||
|
|
||||||
has_selection = gtk_text_buffer_get_selection_bounds (get_buffer (text_view),
|
has_selection = gtk_text_buffer_get_selection_bounds (get_buffer (text_view),
|
||||||
@@ -8902,8 +8947,13 @@ bubble_targets_received (GtkClipboard *clipboard,
|
|||||||
if (priv->selection_bubble)
|
if (priv->selection_bubble)
|
||||||
gtk_widget_destroy (priv->selection_bubble);
|
gtk_widget_destroy (priv->selection_bubble);
|
||||||
|
|
||||||
window = gtk_widget_get_window (GTK_WIDGET (text_view));
|
priv->selection_bubble = gtk_popover_new (GTK_WIDGET (text_view));
|
||||||
priv->selection_bubble = _gtk_bubble_window_new ();
|
gtk_style_context_add_class (gtk_widget_get_style_context (priv->selection_bubble),
|
||||||
|
GTK_STYLE_CLASS_OSD);
|
||||||
|
gtk_popover_set_position (GTK_POPOVER (priv->selection_bubble),
|
||||||
|
GTK_POS_TOP);
|
||||||
|
gtk_popover_set_modal (GTK_POPOVER (priv->selection_bubble), FALSE);
|
||||||
|
|
||||||
toolbar = GTK_WIDGET (gtk_toolbar_new ());
|
toolbar = GTK_WIDGET (gtk_toolbar_new ());
|
||||||
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_TEXT);
|
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_TEXT);
|
||||||
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
|
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
|
||||||
@@ -8930,8 +8980,9 @@ bubble_targets_received (GtkClipboard *clipboard,
|
|||||||
gtk_text_view_get_selection_rect (text_view, &rect);
|
gtk_text_view_get_selection_rect (text_view, &rect);
|
||||||
rect.x -= priv->xoffset;
|
rect.x -= priv->xoffset;
|
||||||
rect.y -= priv->yoffset;
|
rect.y -= priv->yoffset;
|
||||||
_gtk_bubble_window_popup (GTK_BUBBLE_WINDOW (priv->selection_bubble),
|
|
||||||
window, &rect, GTK_POS_TOP);
|
gtk_popover_set_pointing_to (GTK_POPOVER (priv->selection_bubble), &rect);
|
||||||
|
gtk_widget_show (priv->selection_bubble);
|
||||||
|
|
||||||
priv->selection_bubble_timeout_id = 0;
|
priv->selection_bubble_timeout_id = 0;
|
||||||
}
|
}
|
||||||
@@ -8957,7 +9008,7 @@ gtk_text_view_selection_bubble_popup_unset (GtkTextView *text_view)
|
|||||||
priv = text_view->priv;
|
priv = text_view->priv;
|
||||||
|
|
||||||
if (priv->selection_bubble)
|
if (priv->selection_bubble)
|
||||||
_gtk_bubble_window_popdown (GTK_BUBBLE_WINDOW (priv->selection_bubble));
|
gtk_widget_hide (priv->selection_bubble);
|
||||||
|
|
||||||
if (priv->selection_bubble_timeout_id)
|
if (priv->selection_bubble_timeout_id)
|
||||||
{
|
{
|
||||||
@@ -9221,7 +9272,7 @@ text_window_scroll (GtkTextWindow *win,
|
|||||||
if (dx != 0 || dy != 0)
|
if (dx != 0 || dy != 0)
|
||||||
{
|
{
|
||||||
if (priv->selection_bubble)
|
if (priv->selection_bubble)
|
||||||
_gtk_bubble_window_popdown (GTK_BUBBLE_WINDOW (priv->selection_bubble));
|
gtk_widget_hide (priv->selection_bubble);
|
||||||
view->priv->in_scroll = TRUE;
|
view->priv->in_scroll = TRUE;
|
||||||
gdk_window_scroll (win->bin_window, dx, dy);
|
gdk_window_scroll (win->bin_window, dx, dy);
|
||||||
view->priv->in_scroll = FALSE;
|
view->priv->in_scroll = FALSE;
|
||||||
|
449
gtk/gtkwindow.c
449
gtk/gtkwindow.c
@@ -123,6 +123,16 @@
|
|||||||
#define MNEMONICS_DELAY 300 /* ms */
|
#define MNEMONICS_DELAY 300 /* ms */
|
||||||
|
|
||||||
typedef struct _GtkDeviceGrabInfo GtkDeviceGrabInfo;
|
typedef struct _GtkDeviceGrabInfo GtkDeviceGrabInfo;
|
||||||
|
typedef struct _GtkWindowPopover GtkWindowPopover;
|
||||||
|
|
||||||
|
struct _GtkWindowPopover
|
||||||
|
{
|
||||||
|
GtkWidget *widget;
|
||||||
|
GdkWindow *window;
|
||||||
|
GtkPositionType pos;
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
gulong unmap_id;
|
||||||
|
};
|
||||||
|
|
||||||
struct _GtkWindowPrivate
|
struct _GtkWindowPrivate
|
||||||
{
|
{
|
||||||
@@ -137,6 +147,8 @@ struct _GtkWindowPrivate
|
|||||||
GdkScreen *screen;
|
GdkScreen *screen;
|
||||||
GtkApplication *application;
|
GtkApplication *application;
|
||||||
|
|
||||||
|
GList *popovers;
|
||||||
|
|
||||||
GdkModifierType mnemonic_modifier;
|
GdkModifierType mnemonic_modifier;
|
||||||
GdkWindowTypeHint gdk_type_hint;
|
GdkWindowTypeHint gdk_type_hint;
|
||||||
|
|
||||||
@@ -1318,6 +1330,24 @@ gtk_window_close (GtkWindow *window)
|
|||||||
gdk_threads_add_idle (send_delete_event, window);
|
gdk_threads_add_idle (send_delete_event, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
popover_destroy (GtkWindowPopover *popover)
|
||||||
|
{
|
||||||
|
if (popover->unmap_id)
|
||||||
|
{
|
||||||
|
g_signal_handler_disconnect (popover->widget, popover->unmap_id);
|
||||||
|
popover->unmap_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (popover->widget && gtk_widget_get_parent (popover->widget))
|
||||||
|
gtk_widget_unparent (popover->widget);
|
||||||
|
|
||||||
|
if (popover->window)
|
||||||
|
gdk_window_destroy (popover->window);
|
||||||
|
|
||||||
|
g_free (popover);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_window_init (GtkWindow *window)
|
gtk_window_init (GtkWindow *window)
|
||||||
{
|
{
|
||||||
@@ -2630,6 +2660,16 @@ static void
|
|||||||
gtk_window_dispose (GObject *object)
|
gtk_window_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
GtkWindow *window = GTK_WINDOW (object);
|
GtkWindow *window = GTK_WINDOW (object);
|
||||||
|
GtkWindowPrivate *priv = window->priv;
|
||||||
|
|
||||||
|
while (priv->popovers)
|
||||||
|
{
|
||||||
|
GtkWindowPopover *popover;
|
||||||
|
|
||||||
|
popover = priv->popovers->data;
|
||||||
|
priv->popovers = g_list_remove_link (priv->popovers, priv->popovers);
|
||||||
|
popover_destroy (popover);
|
||||||
|
}
|
||||||
|
|
||||||
gtk_window_set_focus (window, NULL);
|
gtk_window_set_focus (window, NULL);
|
||||||
gtk_window_set_default (window, NULL);
|
gtk_window_set_default (window, NULL);
|
||||||
@@ -5391,6 +5431,41 @@ gtk_window_hide (GtkWidget *widget)
|
|||||||
gtk_grab_remove (widget);
|
gtk_grab_remove (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
popover_unmap (GtkWidget *widget,
|
||||||
|
GtkWindowPopover *popover)
|
||||||
|
{
|
||||||
|
if (popover->window)
|
||||||
|
{
|
||||||
|
if (gtk_widget_is_visible (popover->widget))
|
||||||
|
gtk_widget_unmap (popover->widget);
|
||||||
|
gdk_window_hide (popover->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (popover->unmap_id)
|
||||||
|
{
|
||||||
|
g_signal_handler_disconnect (widget, popover->unmap_id);
|
||||||
|
popover->unmap_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
popover_map (GtkWidget *widget,
|
||||||
|
GtkWindowPopover *popover)
|
||||||
|
{
|
||||||
|
if (popover->window)
|
||||||
|
{
|
||||||
|
gdk_window_show (popover->window);
|
||||||
|
|
||||||
|
if (gtk_widget_get_visible (popover->widget))
|
||||||
|
{
|
||||||
|
gtk_widget_map (popover->widget);
|
||||||
|
popover->unmap_id = g_signal_connect (popover->widget, "unmap",
|
||||||
|
G_CALLBACK (popover_unmap), popover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_window_map (GtkWidget *widget)
|
gtk_window_map (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
@@ -5398,6 +5473,7 @@ gtk_window_map (GtkWidget *widget)
|
|||||||
GtkWindow *window = GTK_WINDOW (widget);
|
GtkWindow *window = GTK_WINDOW (widget);
|
||||||
GtkWindowPrivate *priv = window->priv;
|
GtkWindowPrivate *priv = window->priv;
|
||||||
GdkWindow *gdk_window;
|
GdkWindow *gdk_window;
|
||||||
|
GList *link;
|
||||||
|
|
||||||
if (!gtk_widget_is_toplevel (widget))
|
if (!gtk_widget_is_toplevel (widget))
|
||||||
{
|
{
|
||||||
@@ -5504,6 +5580,15 @@ gtk_window_map (GtkWidget *widget)
|
|||||||
|
|
||||||
if (priv->application)
|
if (priv->application)
|
||||||
gtk_application_handle_window_map (priv->application, window);
|
gtk_application_handle_window_map (priv->application, window);
|
||||||
|
|
||||||
|
link = priv->popovers;
|
||||||
|
|
||||||
|
while (link)
|
||||||
|
{
|
||||||
|
GtkWindowPopover *popover = link->data;
|
||||||
|
link = link->next;
|
||||||
|
popover_map (popover->widget, popover);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -5533,6 +5618,7 @@ gtk_window_unmap (GtkWidget *widget)
|
|||||||
GtkWindowGeometryInfo *info;
|
GtkWindowGeometryInfo *info;
|
||||||
GdkWindow *gdk_window;
|
GdkWindow *gdk_window;
|
||||||
GdkWindowState state;
|
GdkWindowState state;
|
||||||
|
GList *link;
|
||||||
|
|
||||||
if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
|
if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
|
||||||
{
|
{
|
||||||
@@ -5540,6 +5626,15 @@ gtk_window_unmap (GtkWidget *widget)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
link = priv->popovers;
|
||||||
|
|
||||||
|
while (link)
|
||||||
|
{
|
||||||
|
GtkWindowPopover *popover = link->data;
|
||||||
|
link = link->next;
|
||||||
|
popover_unmap (popover->widget, popover);
|
||||||
|
}
|
||||||
|
|
||||||
gdk_window = gtk_widget_get_window (widget);
|
gdk_window = gtk_widget_get_window (widget);
|
||||||
|
|
||||||
gtk_widget_set_mapped (widget, FALSE);
|
gtk_widget_set_mapped (widget, FALSE);
|
||||||
@@ -5669,6 +5764,118 @@ gtk_window_get_remembered_size (GtkWindow *window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
popover_get_rect (GtkWindowPopover *popover,
|
||||||
|
GtkWindow *window,
|
||||||
|
cairo_rectangle_int_t *rect)
|
||||||
|
{
|
||||||
|
GtkAllocation win_alloc;
|
||||||
|
GtkRequisition req;
|
||||||
|
|
||||||
|
gtk_widget_get_preferred_size (popover->widget, NULL, &req);
|
||||||
|
gtk_widget_get_allocation (GTK_WIDGET (window), &win_alloc);
|
||||||
|
rect->width = req.width;
|
||||||
|
rect->height = req.height;
|
||||||
|
|
||||||
|
if (popover->pos == GTK_POS_LEFT || popover->pos == GTK_POS_RIGHT)
|
||||||
|
{
|
||||||
|
if (req.height < win_alloc.height &&
|
||||||
|
gtk_widget_get_vexpand (popover->widget))
|
||||||
|
{
|
||||||
|
rect->y = 0;
|
||||||
|
rect->height = win_alloc.height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rect->y = CLAMP (popover->rect.y + (popover->rect.height / 2) -
|
||||||
|
(req.height / 2), 0, win_alloc.height - req.height);
|
||||||
|
|
||||||
|
if ((popover->pos == GTK_POS_LEFT) ==
|
||||||
|
(gtk_widget_get_direction (popover->widget) == GTK_TEXT_DIR_LTR))
|
||||||
|
{
|
||||||
|
rect->x = popover->rect.x - req.width;
|
||||||
|
|
||||||
|
if (rect->x > 0 && gtk_widget_get_hexpand (popover->widget))
|
||||||
|
{
|
||||||
|
rect->x = 0;
|
||||||
|
rect->width = popover->rect.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rect->x = popover->rect.x + popover->rect.width;
|
||||||
|
|
||||||
|
if (rect->x + rect->width < win_alloc.width &&
|
||||||
|
gtk_widget_get_hexpand (popover->widget))
|
||||||
|
rect->width = win_alloc.width - rect->x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (popover->pos == GTK_POS_TOP || popover->pos == GTK_POS_BOTTOM)
|
||||||
|
{
|
||||||
|
if (req.width < win_alloc.width &&
|
||||||
|
gtk_widget_get_hexpand (popover->widget))
|
||||||
|
{
|
||||||
|
rect->x = 0;
|
||||||
|
rect->width = win_alloc.width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rect->x = CLAMP (popover->rect.x + (popover->rect.width / 2) -
|
||||||
|
(req.width / 2), 0, win_alloc.width - req.width);
|
||||||
|
|
||||||
|
if (popover->pos == GTK_POS_TOP)
|
||||||
|
{
|
||||||
|
rect->y = popover->rect.y - req.height;
|
||||||
|
|
||||||
|
if (rect->y > 0 && gtk_widget_get_vexpand (popover->widget))
|
||||||
|
{
|
||||||
|
rect->y = 0;
|
||||||
|
rect->height = popover->rect.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rect->y = popover->rect.y + popover->rect.height;
|
||||||
|
|
||||||
|
if (rect->y + rect->height < win_alloc.height &&
|
||||||
|
gtk_widget_get_vexpand (popover->widget))
|
||||||
|
rect->height = win_alloc.height - rect->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
popover_realize (GtkWidget *widget,
|
||||||
|
GtkWindowPopover *popover,
|
||||||
|
GtkWindow *window)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
GdkWindow *parent_window;
|
||||||
|
GdkWindowAttr attributes;
|
||||||
|
gint attributes_mask;
|
||||||
|
|
||||||
|
if (popover->window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
popover_get_rect (popover, window, &rect);
|
||||||
|
|
||||||
|
attributes.window_type = GDK_WINDOW_CHILD;
|
||||||
|
attributes.wclass = GDK_INPUT_OUTPUT;
|
||||||
|
attributes.x = rect.x;
|
||||||
|
attributes.y = rect.y;
|
||||||
|
attributes.width = rect.width;
|
||||||
|
attributes.height = rect.height;
|
||||||
|
attributes.visual = gtk_widget_get_visual (widget);
|
||||||
|
attributes.event_mask = gtk_widget_get_events (popover->widget) |
|
||||||
|
GDK_EXPOSURE_MASK;
|
||||||
|
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
|
||||||
|
|
||||||
|
parent_window = gtk_widget_get_window (GTK_WIDGET (window));
|
||||||
|
popover->window =
|
||||||
|
gdk_window_new (parent_window, &attributes, attributes_mask);
|
||||||
|
gtk_widget_register_window (GTK_WIDGET (window), popover->window);
|
||||||
|
|
||||||
|
gtk_widget_set_parent_window (popover->widget, popover->window);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_window_realize (GtkWidget *widget)
|
gtk_window_realize (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
@@ -5681,6 +5888,7 @@ gtk_window_realize (GtkWidget *widget)
|
|||||||
GtkWindowPrivate *priv;
|
GtkWindowPrivate *priv;
|
||||||
gint i;
|
gint i;
|
||||||
int old_scale;
|
int old_scale;
|
||||||
|
GList *link;
|
||||||
|
|
||||||
window = GTK_WINDOW (widget);
|
window = GTK_WINDOW (widget);
|
||||||
priv = window->priv;
|
priv = window->priv;
|
||||||
@@ -5919,18 +6127,37 @@ gtk_window_realize (GtkWidget *widget)
|
|||||||
if (priv->has_resize_grip)
|
if (priv->has_resize_grip)
|
||||||
resize_grip_create_window (window);
|
resize_grip_create_window (window);
|
||||||
|
|
||||||
|
link = priv->popovers;
|
||||||
|
|
||||||
|
while (link)
|
||||||
|
{
|
||||||
|
GtkWindowPopover *popover = link->data;
|
||||||
|
link = link->next;
|
||||||
|
popover_realize (popover->widget, popover, window);
|
||||||
|
}
|
||||||
|
|
||||||
old_scale = priv->scale;
|
old_scale = priv->scale;
|
||||||
priv->scale = gtk_widget_get_scale_factor (widget);
|
priv->scale = gtk_widget_get_scale_factor (widget);
|
||||||
if (old_scale != priv->scale)
|
if (old_scale != priv->scale)
|
||||||
_gtk_widget_scale_changed (widget);
|
_gtk_widget_scale_changed (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
popover_unrealize (GtkWidget *widget,
|
||||||
|
GtkWindowPopover *popover)
|
||||||
|
{
|
||||||
|
gtk_widget_unrealize (popover->widget);
|
||||||
|
gdk_window_destroy (popover->window);
|
||||||
|
popover->window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_window_unrealize (GtkWidget *widget)
|
gtk_window_unrealize (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
GtkWindow *window = GTK_WINDOW (widget);
|
GtkWindow *window = GTK_WINDOW (widget);
|
||||||
GtkWindowPrivate *priv = window->priv;
|
GtkWindowPrivate *priv = window->priv;
|
||||||
GtkWindowGeometryInfo *info;
|
GtkWindowGeometryInfo *info;
|
||||||
|
GList *link;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
/* On unrealize, we reset the size of the window such
|
/* On unrealize, we reset the size of the window such
|
||||||
@@ -5975,6 +6202,15 @@ gtk_window_unrealize (GtkWidget *widget)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
link = priv->popovers;
|
||||||
|
|
||||||
|
while (link)
|
||||||
|
{
|
||||||
|
GtkWindowPopover *popover = link->data;
|
||||||
|
link = link->next;
|
||||||
|
popover_unrealize (popover->widget, popover);
|
||||||
|
}
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
|
GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6690,19 +6926,56 @@ _gtk_window_set_allocation (GtkWindow *window,
|
|||||||
*allocation_out = child_allocation;
|
*allocation_out = child_allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
popover_size_allocate (GtkWidget *widget,
|
||||||
|
GtkWindowPopover *popover,
|
||||||
|
GtkWindow *window)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
if (!popover->window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
popover_get_rect (popover, window, &rect);
|
||||||
|
gdk_window_move_resize (popover->window, rect.x, rect.y,
|
||||||
|
rect.width, rect.height);
|
||||||
|
rect.x = rect.y = 0;
|
||||||
|
gtk_widget_size_allocate (widget, &rect);
|
||||||
|
|
||||||
|
if (gtk_widget_is_drawable (GTK_WIDGET (window)) &&
|
||||||
|
gtk_widget_is_visible (widget))
|
||||||
|
{
|
||||||
|
if (!gdk_window_is_visible (popover->window))
|
||||||
|
gdk_window_show (popover->window);
|
||||||
|
}
|
||||||
|
else if (gdk_window_is_visible (popover->window))
|
||||||
|
gdk_window_hide (popover->window);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_window_size_allocate (GtkWidget *widget,
|
gtk_window_size_allocate (GtkWidget *widget,
|
||||||
GtkAllocation *allocation)
|
GtkAllocation *allocation)
|
||||||
{
|
{
|
||||||
GtkWindow *window = GTK_WINDOW (widget);
|
GtkWindow *window = GTK_WINDOW (widget);
|
||||||
|
GtkWindowPrivate *priv = window->priv;
|
||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
GtkAllocation child_allocation;
|
GtkAllocation child_allocation;
|
||||||
|
GList *link;
|
||||||
|
|
||||||
_gtk_window_set_allocation (window, allocation, &child_allocation);
|
_gtk_window_set_allocation (window, allocation, &child_allocation);
|
||||||
|
|
||||||
child = gtk_bin_get_child (GTK_BIN (window));
|
child = gtk_bin_get_child (GTK_BIN (window));
|
||||||
if (child && gtk_widget_get_visible (child))
|
if (child && gtk_widget_get_visible (child))
|
||||||
gtk_widget_size_allocate (child, &child_allocation);
|
gtk_widget_size_allocate (child, &child_allocation);
|
||||||
|
|
||||||
|
link = priv->popovers;
|
||||||
|
|
||||||
|
while (link)
|
||||||
|
{
|
||||||
|
GtkWindowPopover *popover = link->data;
|
||||||
|
link = link->next;
|
||||||
|
popover_size_allocate (popover->widget, popover, window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
@@ -7472,6 +7745,27 @@ gtk_window_button_press_event (GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_gtk_window_check_handle_wm_event (GdkEvent *event)
|
||||||
|
{
|
||||||
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
widget = gtk_get_event_widget (event);
|
||||||
|
|
||||||
|
if (!GTK_IS_WINDOW (widget))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (event->type == GDK_BUTTON_PRESS ||
|
||||||
|
event->type == GDK_2BUTTON_PRESS)
|
||||||
|
return gtk_window_button_press_event (widget, &event->button);
|
||||||
|
else if (event->type == GDK_BUTTON_RELEASE)
|
||||||
|
return gtk_window_button_release_event (widget, &event->button);
|
||||||
|
else if (event->type == GDK_MOTION_NOTIFY)
|
||||||
|
return gtk_window_motion_notify_event (widget, &event->motion);
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_window_real_activate_default (GtkWindow *window)
|
gtk_window_real_activate_default (GtkWindow *window)
|
||||||
{
|
{
|
||||||
@@ -7607,13 +7901,34 @@ gtk_window_focus_out_event (GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GtkWindowPopover *
|
||||||
|
_gtk_window_has_popover (GtkWindow *window,
|
||||||
|
GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GtkWindowPrivate *priv = window->priv;
|
||||||
|
GList *link;
|
||||||
|
|
||||||
|
for (link = priv->popovers; link; link = link->next)
|
||||||
|
{
|
||||||
|
GtkWindowPopover *popover = link->data;
|
||||||
|
|
||||||
|
if (popover->widget == widget)
|
||||||
|
return popover;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_window_remove (GtkContainer *container,
|
gtk_window_remove (GtkContainer *container,
|
||||||
GtkWidget *widget)
|
GtkWidget *widget)
|
||||||
{
|
{
|
||||||
GtkWindow *window = GTK_WINDOW (container);
|
GtkWindow *window = GTK_WINDOW (container);
|
||||||
|
|
||||||
if (widget == window->priv->title_box)
|
if (widget == window->priv->title_box)
|
||||||
unset_titlebar (window);
|
unset_titlebar (window);
|
||||||
|
else if (_gtk_window_has_popover (window, widget))
|
||||||
|
_gtk_window_remove_popover (window, widget);
|
||||||
else
|
else
|
||||||
GTK_CONTAINER_CLASS (gtk_window_parent_class)->remove (container, widget);
|
GTK_CONTAINER_CLASS (gtk_window_parent_class)->remove (container, widget);
|
||||||
}
|
}
|
||||||
@@ -9388,11 +9703,13 @@ gtk_window_draw (GtkWidget *widget,
|
|||||||
cairo_t *cr)
|
cairo_t *cr)
|
||||||
{
|
{
|
||||||
GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
|
GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
|
||||||
|
GtkWindowPopover *popover;
|
||||||
GtkStyleContext *context;
|
GtkStyleContext *context;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
GtkBorder window_border;
|
GtkBorder window_border;
|
||||||
gint title_height;
|
gint title_height;
|
||||||
|
GList *link;
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (widget);
|
context = gtk_widget_get_style_context (widget);
|
||||||
|
|
||||||
@@ -9476,6 +9793,19 @@ gtk_window_draw (GtkWidget *widget,
|
|||||||
gtk_style_context_restore (context);
|
gtk_style_context_restore (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
link = priv->popovers;
|
||||||
|
|
||||||
|
while (link)
|
||||||
|
{
|
||||||
|
popover = link->data;
|
||||||
|
link = link->next;
|
||||||
|
|
||||||
|
if (popover->window && gtk_widget_is_visible (popover->widget) &&
|
||||||
|
gtk_cairo_should_draw_window (cr, popover->window))
|
||||||
|
gtk_container_propagate_draw (GTK_CONTAINER (widget),
|
||||||
|
popover->widget, cr);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11690,3 +12020,122 @@ _gtk_window_get_shadow_width (GtkWindow *window,
|
|||||||
{
|
{
|
||||||
get_shadow_width (GTK_WIDGET (window), border);
|
get_shadow_width (GTK_WIDGET (window), border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_window_add_popover (GtkWindow *window,
|
||||||
|
GtkWidget *popover)
|
||||||
|
{
|
||||||
|
GtkWindowPrivate *priv;
|
||||||
|
GtkWindowPopover *data;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_WINDOW (window));
|
||||||
|
g_return_if_fail (GTK_IS_WIDGET (popover));
|
||||||
|
g_return_if_fail (gtk_widget_get_parent (popover) == NULL);
|
||||||
|
|
||||||
|
priv = window->priv;
|
||||||
|
|
||||||
|
if (_gtk_window_has_popover (window, popover))
|
||||||
|
return;
|
||||||
|
|
||||||
|
data = g_new0 (GtkWindowPopover, 1);
|
||||||
|
data->widget = popover;
|
||||||
|
priv->popovers = g_list_prepend (priv->popovers, data);
|
||||||
|
|
||||||
|
if (gtk_widget_get_realized (GTK_WIDGET (window)))
|
||||||
|
popover_realize (popover, data, window);
|
||||||
|
|
||||||
|
gtk_widget_set_parent (popover, GTK_WIDGET (window));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_window_remove_popover (GtkWindow *window,
|
||||||
|
GtkWidget *popover)
|
||||||
|
{
|
||||||
|
GtkWindowPrivate *priv;
|
||||||
|
GtkWindowPopover *data;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_WINDOW (window));
|
||||||
|
g_return_if_fail (GTK_IS_WIDGET (popover));
|
||||||
|
|
||||||
|
priv = window->priv;
|
||||||
|
|
||||||
|
data = _gtk_window_has_popover (window, popover);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->popovers = g_list_remove (priv->popovers, data);
|
||||||
|
popover_destroy (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_window_set_popover_position (GtkWindow *window,
|
||||||
|
GtkWidget *popover,
|
||||||
|
GtkPositionType pos,
|
||||||
|
const cairo_rectangle_int_t *rect)
|
||||||
|
{
|
||||||
|
GtkWindowPopover *data;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_WINDOW (window));
|
||||||
|
g_return_if_fail (GTK_IS_WIDGET (popover));
|
||||||
|
|
||||||
|
data = _gtk_window_has_popover (window, popover);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
g_warning ("Widget %s(%p) is not a popover of window %s",
|
||||||
|
gtk_widget_get_name (popover), popover,
|
||||||
|
gtk_widget_get_name (GTK_WIDGET (window)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (data->pos == pos &&
|
||||||
|
memcmp (&data->rect, rect, sizeof (cairo_rectangle_int_t)) == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->rect = *rect;
|
||||||
|
data->pos = pos;
|
||||||
|
|
||||||
|
if (gtk_widget_is_visible (popover))
|
||||||
|
{
|
||||||
|
if (!data->window)
|
||||||
|
{
|
||||||
|
popover_realize (popover, data, window);
|
||||||
|
popover_map (popover, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gdk_window_raise (data->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_queue_resize (popover);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_window_get_popover_position (GtkWindow *window,
|
||||||
|
GtkWidget *popover,
|
||||||
|
GtkPositionType *pos,
|
||||||
|
cairo_rectangle_int_t *rect)
|
||||||
|
{
|
||||||
|
GtkWindowPopover *data;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_WINDOW (window));
|
||||||
|
g_return_if_fail (GTK_IS_WIDGET (popover));
|
||||||
|
|
||||||
|
data = _gtk_window_has_popover (window, popover);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
g_warning ("Widget %s(%p) is not a popover of window %s",
|
||||||
|
gtk_widget_get_name (popover), popover,
|
||||||
|
gtk_widget_get_name (GTK_WIDGET (window)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos)
|
||||||
|
*pos = data->pos;
|
||||||
|
|
||||||
|
if (rect)
|
||||||
|
*rect = data->rect;
|
||||||
|
}
|
||||||
|
@@ -75,6 +75,8 @@ void _gtk_window_keys_foreach (GtkWindow *window,
|
|||||||
GtkWindowKeysForeachFunc func,
|
GtkWindowKeysForeachFunc func,
|
||||||
gpointer func_data);
|
gpointer func_data);
|
||||||
|
|
||||||
|
gboolean _gtk_window_check_handle_wm_event (GdkEvent *event);
|
||||||
|
|
||||||
/* --- internal (GtkAcceleratable) --- */
|
/* --- internal (GtkAcceleratable) --- */
|
||||||
gboolean _gtk_window_query_nonaccels (GtkWindow *window,
|
gboolean _gtk_window_query_nonaccels (GtkWindow *window,
|
||||||
guint accel_key,
|
guint accel_key,
|
||||||
@@ -91,6 +93,20 @@ void _gtk_window_get_shadow_width (GtkWindow *window,
|
|||||||
|
|
||||||
void _gtk_window_toggle_maximized (GtkWindow *window);
|
void _gtk_window_toggle_maximized (GtkWindow *window);
|
||||||
|
|
||||||
|
/* Popovers */
|
||||||
|
void _gtk_window_add_popover (GtkWindow *window,
|
||||||
|
GtkWidget *popover);
|
||||||
|
void _gtk_window_remove_popover (GtkWindow *window,
|
||||||
|
GtkWidget *popover);
|
||||||
|
void _gtk_window_set_popover_position (GtkWindow *window,
|
||||||
|
GtkWidget *popover,
|
||||||
|
GtkPositionType pos,
|
||||||
|
const cairo_rectangle_int_t *rect);
|
||||||
|
void _gtk_window_get_popover_position (GtkWindow *window,
|
||||||
|
GtkWidget *popover,
|
||||||
|
GtkPositionType *pos,
|
||||||
|
cairo_rectangle_int_t *rect);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GTK_WINDOW_PRIVATE_H__ */
|
#endif /* __GTK_WINDOW_PRIVATE_H__ */
|
||||||
|
Reference in New Issue
Block a user