[gnome-builder/wip/gtk4-port] libide/sourceview: take over context menu control for text view
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/gtk4-port] libide/sourceview: take over context menu control for text view
- Date: Fri, 29 Apr 2022 21:15:38 +0000 (UTC)
commit f64ec91d76c1a06ee861866942c03961c5ef9db9
Author: Christian Hergert <chergert redhat com>
Date: Fri Apr 29 14:15:33 2022 -0700
libide/sourceview: take over context menu control for text view
Rather than rely on GtkTextView to display menu items we can't control
positioning of, just take over control of the menu display and placement
with all of the items merge-able by plugins.
We still need some work to update actions but that can happen in followup
commits. We also need to add soem missing items like emoji. It may also
make sense to add some "junction" widgets for copy/paste/etc as those take
a lot of vertical space with very rare usage.
src/libide/sourceview/{archive => gtk}/menus.ui | 2 -
src/libide/sourceview/ide-source-view-private.h | 1 +
src/libide/sourceview/ide-source-view.c | 82 +++++++++++++++++++++-
.../sourceview/libide-sourceview.gresource.xml | 1 +
4 files changed, 83 insertions(+), 3 deletions(-)
---
diff --git a/src/libide/sourceview/archive/menus.ui b/src/libide/sourceview/gtk/menus.ui
similarity index 98%
rename from src/libide/sourceview/archive/menus.ui
rename to src/libide/sourceview/gtk/menus.ui
index cccd3fc68..ace729427 100644
--- a/src/libide/sourceview/archive/menus.ui
+++ b/src/libide/sourceview/gtk/menus.ui
@@ -51,8 +51,6 @@
<attribute name="accel">Delete</attribute>
</item>
</section>
- <section id="ide-source-view-popup-menu-spellcheck-section">
- </section>
<section id="ide-source-view-popup-menu-highlighting-section">
<submenu id="ide-source-view-popup-menu-highlighting-submenu">
<attribute name="label" translatable="yes">_Highlighting</attribute>
diff --git a/src/libide/sourceview/ide-source-view-private.h b/src/libide/sourceview/ide-source-view-private.h
index 19c847351..f88ea6974 100644
--- a/src/libide/sourceview/ide-source-view-private.h
+++ b/src/libide/sourceview/ide-source-view-private.h
@@ -53,6 +53,7 @@ struct _IdeSourceView
* addins to extend it.
*/
IdeJoinedMenu *joined_menu;
+ GtkPopover *popup_menu;
/* Various addins for different ways of extending the
* GtkSourceView. These are managed in ide-source-view-addins.c
diff --git a/src/libide/sourceview/ide-source-view.c b/src/libide/sourceview/ide-source-view.c
index 1a31a5357..4b4c06851 100644
--- a/src/libide/sourceview/ide-source-view.c
+++ b/src/libide/sourceview/ide-source-view.c
@@ -374,6 +374,82 @@ ide_source_view_root (GtkWidget *widget)
IDE_EXIT;
}
+static void
+ide_source_view_menu_popup_action (GtkWidget *widget,
+ const char *action_name,
+ GVariant *param)
+{
+ IdeSourceView *self = (IdeSourceView *)widget;
+ GtkTextView *text_view = (GtkTextView *)widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+ GdkRectangle iter_location;
+ GdkRectangle visible_rect;
+ gboolean is_visible;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+ g_assert (ide_str_equal0 (action_name, "menu.popup"));
+ g_assert (param == NULL);
+
+ if (self->popup_menu == NULL)
+ {
+ GMenuModel *model;
+
+ model = G_MENU_MODEL (self->joined_menu);
+ self->popup_menu = GTK_POPOVER (gtk_popover_menu_new_from_model (model));
+ gtk_widget_set_parent (GTK_WIDGET (self->popup_menu), widget);
+ gtk_popover_set_position (self->popup_menu, GTK_POS_BOTTOM);
+ gtk_popover_set_has_arrow (self->popup_menu, FALSE);
+ gtk_widget_set_halign (GTK_WIDGET (self->popup_menu), GTK_ALIGN_START);
+ }
+
+ buffer = gtk_text_view_get_buffer (text_view);
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter,
+ gtk_text_buffer_get_insert (buffer));
+ gtk_text_view_get_iter_location (text_view, &iter, &iter_location);
+ gtk_text_view_get_visible_rect (text_view, &visible_rect);
+
+ is_visible = (iter_location.x + iter_location.width > visible_rect.x &&
+ iter_location.x < visible_rect.x + visible_rect.width &&
+ iter_location.y + iter_location.height > visible_rect.y &&
+ iter_location.y < visible_rect.y + visible_rect.height);
+
+ if (is_visible)
+ {
+ gtk_text_view_buffer_to_window_coords (text_view,
+ GTK_TEXT_WINDOW_WIDGET,
+ iter_location.x,
+ iter_location.y,
+ &iter_location.x,
+ &iter_location.y);
+
+ gtk_popover_set_pointing_to (self->popup_menu, &iter_location);
+ }
+
+ gtk_popover_popup (self->popup_menu);
+
+ IDE_EXIT;
+}
+
+static void
+ide_source_view_size_allocate (GtkWidget *widget,
+ int width,
+ int height,
+ int baseline)
+{
+ IdeSourceView *self = (IdeSourceView *)widget;
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+ g_assert (GTK_IS_WIDGET (widget));
+
+ GTK_WIDGET_CLASS (ide_source_view_parent_class)->size_allocate (widget, width, height, baseline);
+
+ if (self->popup_menu != NULL)
+ gtk_popover_present (self->popup_menu);
+}
+
static void
ide_source_view_dispose (GObject *object)
{
@@ -386,6 +462,7 @@ ide_source_view_dispose (GObject *object)
g_clear_object (&self->joined_menu);
g_clear_object (&self->css_provider);
g_clear_pointer (&self->font_desc, pango_font_description_free);
+ g_clear_pointer ((GtkWidget **)&self->popup_menu, gtk_widget_unparent);
g_assert (self->completion_providers == NULL);
@@ -476,6 +553,7 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
object_class->set_property = ide_source_view_set_property;
widget_class->root = ide_source_view_root;
+ widget_class->size_allocate = ide_source_view_size_allocate;
properties [PROP_LINE_HEIGHT] =
g_param_spec_double ("line-height",
@@ -507,6 +585,8 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
g_object_class_install_properties (object_class, N_PROPS, properties);
+ gtk_widget_class_install_action (widget_class, "menu.popup", NULL, ide_source_view_menu_popup_action);
+
/**
* IdeSourceView::populate-menu:
* @self: an #IdeSourceView
@@ -539,7 +619,7 @@ ide_source_view_init (IdeSourceView *self)
NULL);
/* Setup our extra menu so that consumers can use
- * ide_source_view_append_men() or similar to update menus.
+ * ide_source_view_append_menu() or similar to update menus.
*/
self->joined_menu = ide_joined_menu_new ();
gtk_text_view_set_extra_menu (GTK_TEXT_VIEW (self),
diff --git a/src/libide/sourceview/libide-sourceview.gresource.xml
b/src/libide/sourceview/libide-sourceview.gresource.xml
index 203de6496..33fffdf8b 100644
--- a/src/libide/sourceview/libide-sourceview.gresource.xml
+++ b/src/libide/sourceview/libide-sourceview.gresource.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/libide-sourceview">
+ <file preprocess="xml-stripblanks">gtk/menus.ui</file>
</gresource>
</gresources>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]