[gnome-builder/wip/gtk4-port] libide/terminal: minimal port of libde-terminal to GTK 4



commit 05599026c7cc5ef5359cc639d1992bdb4122491f
Author: Christian Hergert <chergert redhat com>
Date:   Fri Apr 1 01:54:24 2022 -0700

    libide/terminal: minimal port of libde-terminal to GTK 4
    
    This disables a lot of things we don't have access to yet in VTE.

 src/libide/terminal/ide-terminal-page-actions.c   |  22 ++-
 src/libide/terminal/ide-terminal-page-private.h   |   9 +-
 src/libide/terminal/ide-terminal-page.c           | 211 +++++++---------------
 src/libide/terminal/ide-terminal-search-private.h |  10 +-
 src/libide/terminal/ide-terminal-search.c         |  26 ++-
 src/libide/terminal/ide-terminal-search.h         |  18 +-
 src/libide/terminal/ide-terminal-search.ui        | 115 +++---------
 src/libide/terminal/ide-terminal.c                |  34 ++++
 src/libide/terminal/ide-terminal.h                |  13 +-
 9 files changed, 182 insertions(+), 276 deletions(-)
---
diff --git a/src/libide/terminal/ide-terminal-page-actions.c b/src/libide/terminal/ide-terminal-page-actions.c
index ad54c6713..b231bf3b9 100644
--- a/src/libide/terminal/ide-terminal-page-actions.c
+++ b/src/libide/terminal/ide-terminal-page-actions.c
@@ -165,8 +165,8 @@ save_as_cb (GObject      *object,
     }
   else
     {
-      g_clear_object (&view->save_as_file_top);
-      view->save_as_file_top = file;
+      g_clear_object (&view->save_as_file);
+      view->save_as_file = file;
     }
 }
 
@@ -175,8 +175,8 @@ get_last_focused_terminal_file (IdeTerminalPage *view)
 {
   GFile *file = NULL;
 
-  if (G_IS_FILE (view->save_as_file_top))
-    file = view->save_as_file_top;
+  if (G_IS_FILE (view->save_as_file))
+    file = view->save_as_file;
 
   return file;
 }
@@ -184,13 +184,14 @@ get_last_focused_terminal_file (IdeTerminalPage *view)
 static VteTerminal *
 get_last_focused_terminal (IdeTerminalPage *view)
 {
-  return VTE_TERMINAL (view->terminal_top);
+  return VTE_TERMINAL (view->terminal);
 }
 
 static gchar *
 gb_terminal_get_selected_text (IdeTerminalPage  *view,
-                               VteTerminal    **terminal_p)
+                               VteTerminal     **terminal_p)
 {
+#if 0
   VteTerminal *terminal;
   gchar *buf = NULL;
 
@@ -205,6 +206,9 @@ gb_terminal_get_selected_text (IdeTerminalPage  *view,
     }
 
   return buf;
+#else
+  return g_strdup ("");
+#endif
 }
 
 static void
@@ -235,7 +239,7 @@ save_as_response (GtkWidget *widget,
       break;
     }
 
-  gtk_widget_destroy (widget);
+  gtk_window_destroy (GTK_WINDOW (chooser));
 }
 
 static void
@@ -256,7 +260,7 @@ ide_terminal_page_actions_save_as (GSimpleAction *action,
    */
   view->selection_buffer = gb_terminal_get_selected_text (view, NULL);
 
-  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
+  toplevel = GTK_WIDGET (gtk_widget_get_native (GTK_WIDGET (view)));
   dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
                          "action", GTK_FILE_CHOOSER_ACTION_SAVE,
                          "do-overwrite-confirmation", TRUE,
@@ -280,7 +284,7 @@ ide_terminal_page_actions_save_as (GSimpleAction *action,
 
   suggested = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
   gtk_style_context_add_class (gtk_widget_get_style_context (suggested),
-                               GTK_STYLE_CLASS_SUGGESTED_ACTION);
+                               "suggested-action");
 
   g_signal_connect (dialog, "response", G_CALLBACK (save_as_response), g_object_ref (view));
 
diff --git a/src/libide/terminal/ide-terminal-page-private.h b/src/libide/terminal/ide-terminal-page-private.h
index 404921835..fd2d5d6a6 100644
--- a/src/libide/terminal/ide-terminal-page-private.h
+++ b/src/libide/terminal/ide-terminal-page-private.h
@@ -31,14 +31,14 @@ struct _IdeTerminalPage
   IdePage              parent_instance;
 
   IdeTerminalLauncher *launcher;
-  GFile               *save_as_file_top;
+  GFile               *save_as_file;
   gchar               *selection_buffer;
   VtePty              *pty;
 
   /* Template widgets */
-  GtkOverlay          *terminal_overlay_top;
-  GtkRevealer         *search_revealer_top;
-  IdeTerminal         *terminal_top;
+  GtkOverlay          *terminal_overlay;
+  GtkRevealer         *search_revealer;
+  IdeTerminal         *terminal;
   IdeTerminalSearch   *tsearch;
 
   gint64               last_respawn;
@@ -47,7 +47,6 @@ struct _IdeTerminalPage
   guint                manage_spawn : 1;
   guint                respawn_on_exit : 1;
   guint                close_on_exit : 1;
-  guint                needs_attention : 1;
   guint                exited : 1;
   guint                destroyed : 1;
 };
diff --git a/src/libide/terminal/ide-terminal-page.c b/src/libide/terminal/ide-terminal-page.c
index 27d913c32..78890c55d 100644
--- a/src/libide/terminal/ide-terminal-page.c
+++ b/src/libide/terminal/ide-terminal-page.c
@@ -86,9 +86,7 @@ destroy_widget_in_idle (GtkWidget *widget)
   g_assert (IDE_IS_TERMINAL_PAGE (self));
 
   if (!self->destroyed)
-    gtk_widget_destroy (widget);
-
-  g_assert (self->destroyed);
+    panel_widget_close (PANEL_WIDGET (self));
 
   IDE_RETURN (G_SOURCE_REMOVE);
 }
@@ -138,12 +136,12 @@ ide_terminal_page_spawn_cb (GObject      *object,
   if (!self->respawn_on_exit)
     {
       if (self->close_on_exit && !maybe_flapping)
-        gdk_threads_add_idle_full (G_PRIORITY_LOW + 1000,
-                                   (GSourceFunc) destroy_widget_in_idle,
-                                   g_object_ref (self),
-                                   g_object_unref);
+        g_idle_add_full (G_PRIORITY_LOW + 1000,
+                         (GSourceFunc) destroy_widget_in_idle,
+                         g_object_ref (self),
+                         g_object_unref);
       else
-        vte_terminal_set_input_enabled (VTE_TERMINAL (self->terminal_top), FALSE);
+        vte_terminal_set_input_enabled (VTE_TERMINAL (self->terminal), FALSE);
       IDE_EXIT;
     }
 
@@ -155,9 +153,9 @@ ide_terminal_page_spawn_cb (GObject      *object,
     }
 
   g_clear_object (&self->pty);
-  vte_terminal_reset (VTE_TERMINAL (self->terminal_top), TRUE, TRUE);
+  vte_terminal_reset (VTE_TERMINAL (self->terminal), TRUE, TRUE);
   self->pty = vte_pty_new_sync (VTE_PTY_DEFAULT, NULL, NULL);
-  vte_terminal_set_pty (VTE_TERMINAL (self->terminal_top), self->pty);
+  vte_terminal_set_pty (VTE_TERMINAL (self->terminal), self->pty);
 
   /* Spawn our terminal and wait for it to exit */
   self->last_respawn = now;
@@ -195,7 +193,7 @@ ide_terminal_page_do_spawn_in_idle (IdeTerminalPage *self)
         }
     }
 
-  vte_terminal_set_pty (VTE_TERMINAL (self->terminal_top), self->pty);
+  vte_terminal_set_pty (VTE_TERMINAL (self->terminal), self->pty);
 
   if (!self->manage_spawn)
     IDE_RETURN (G_SOURCE_REMOVE);
@@ -234,59 +232,6 @@ ide_terminal_page_realize (GtkWidget *widget)
                    g_object_unref);
 }
 
-static void
-ide_terminal_page_get_preferred_width (GtkWidget *widget,
-                                       gint      *min_width,
-                                       gint      *nat_width)
-{
-  /*
-   * Since we are placing the terminal in a GtkStack, we need
-   * to fake the size a bit. Otherwise, GtkStack tries to keep the
-   * widget at its natural size (which prevents us from getting
-   * appropriate size requests.
-   */
-  GTK_WIDGET_CLASS (ide_terminal_page_parent_class)->get_preferred_width (widget, min_width, nat_width);
-  *nat_width = *min_width;
-}
-
-static void
-ide_terminal_page_get_preferred_height (GtkWidget *widget,
-                                        gint      *min_height,
-                                        gint      *nat_height)
-{
-  /*
-   * Since we are placing the terminal in a GtkStack, we need
-   * to fake the size a bit. Otherwise, GtkStack tries to keep the
-   * widget at its natural size (which prevents us from getting
-   * appropriate size requests.
-   */
-  GTK_WIDGET_CLASS (ide_terminal_page_parent_class)->get_preferred_height (widget, min_height, nat_height);
-  *nat_height = *min_height;
-}
-
-static void
-ide_terminal_page_set_needs_attention (IdeTerminalPage *self,
-                                       gboolean         needs_attention)
-{
-  GtkWidget *parent;
-
-  g_assert (IDE_IS_TERMINAL_PAGE (self));
-
-  parent = gtk_widget_get_parent (GTK_WIDGET (self));
-
-  if (GTK_IS_STACK (parent) &&
-      !gtk_widget_in_destruction (GTK_WIDGET (self)) &&
-      !gtk_widget_in_destruction (parent))
-    {
-      if (!gtk_widget_in_destruction (GTK_WIDGET (self->terminal_top)))
-        self->needs_attention = !!needs_attention;
-
-      gtk_container_child_set (GTK_CONTAINER (parent), GTK_WIDGET (self),
-                               "needs-attention", needs_attention,
-                               NULL);
-    }
-}
-
 static void
 notification_received_cb (VteTerminal     *terminal,
                           const gchar     *summary,
@@ -300,22 +245,18 @@ notification_received_cb (VteTerminal     *terminal,
     return;
 
   if (!gtk_widget_has_focus (GTK_WIDGET (terminal)))
-    ide_terminal_page_set_needs_attention (self, TRUE);
+    panel_widget_set_needs_attention (PANEL_WIDGET (self), TRUE);
 }
 
-static gboolean
-focus_in_event_cb (VteTerminal     *terminal,
-                   GdkEvent        *event,
-                   IdeTerminalPage *self)
+static void
+focus_in_event_cb (GtkEventControllerFocus *focus,
+                   IdeTerminalPage         *self)
 {
-  g_assert (VTE_IS_TERMINAL (terminal));
+  g_assert (GTK_IS_EVENT_CONTROLLER_FOCUS (focus));
   g_assert (IDE_IS_TERMINAL_PAGE (self));
 
-  self->needs_attention = FALSE;
-  ide_terminal_page_set_needs_attention (self, FALSE);
-  gtk_revealer_set_reveal_child (self->search_revealer_top, FALSE);
-
-  return GDK_EVENT_PROPAGATE;
+  panel_widget_set_needs_attention (PANEL_WIDGET (self), FALSE);
+  gtk_revealer_set_reveal_child (self->search_revealer, FALSE);
 }
 
 static void
@@ -330,7 +271,7 @@ window_title_changed_cb (VteTerminal     *terminal,
   if (self->destroyed)
     return;
 
-  title = vte_terminal_get_window_title (VTE_TERMINAL (self->terminal_top));
+  title = vte_terminal_get_window_title (VTE_TERMINAL (self->terminal));
 
   if (title == NULL || title[0] == '\0')
     title = _("Untitled terminal");
@@ -338,31 +279,6 @@ window_title_changed_cb (VteTerminal     *terminal,
   ide_page_set_title (IDE_PAGE (self), title);
 }
 
-static void
-style_context_changed (GtkStyleContext *style_context,
-                       IdeTerminalPage *self)
-{
-  GtkStateFlags state;
-  GdkRGBA fg;
-  GdkRGBA bg;
-
-  g_assert (GTK_IS_STYLE_CONTEXT (style_context));
-  g_assert (IDE_IS_TERMINAL_PAGE (self));
-
-  state = gtk_style_context_get_state (style_context);
-
-  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-  gtk_style_context_get_color (style_context, state, &fg);
-  gtk_style_context_get_background_color (style_context, state, &bg);
-  G_GNUC_END_IGNORE_DEPRECATIONS;
-
-  if (bg.alpha == 0.0)
-    gdk_rgba_parse (&bg, "#f6f7f8");
-
-  ide_page_set_primary_color_fg (IDE_PAGE (self), &fg);
-  ide_page_set_primary_color_bg (IDE_PAGE (self), &bg);
-}
-
 static IdePage *
 ide_terminal_page_create_split (IdePage *page)
 {
@@ -380,31 +296,54 @@ ide_terminal_page_create_split (IdePage *page)
                        NULL);
 }
 
-static void
+static gboolean
 ide_terminal_page_grab_focus (GtkWidget *widget)
 {
   IdeTerminalPage *self = (IdeTerminalPage *)widget;
 
   g_assert (IDE_IS_TERMINAL_PAGE (self));
 
-  gtk_widget_grab_focus (GTK_WIDGET (self->terminal_top));
+  return gtk_widget_grab_focus (GTK_WIDGET (self->terminal));
+}
+
+static void
+on_colors_changed_cb (IdeTerminal     *terminal,
+                      IdeTerminalPage *self)
+{
+  GdkRGBA bg, fg;
+
+  ide_terminal_get_colors (terminal, &bg, &fg);
+  ide_page_set_primary_color_fg (IDE_PAGE (self), &fg);
+  ide_page_set_primary_color_bg (IDE_PAGE (self), &bg);
 }
 
 static void
 ide_terminal_page_connect_terminal (IdeTerminalPage *self,
                                     VteTerminal     *terminal)
 {
+  GtkEventController *controller;
+
   g_assert (IDE_IS_TERMINAL_PAGE (self));
-  g_assert (VTE_IS_TERMINAL (terminal));
+  g_assert (IDE_IS_TERMINAL (terminal));
 
   if (self->destroyed)
     return;
 
   g_signal_connect_object (terminal,
-                           "focus-in-event",
+                           "colors-changed",
+                           G_CALLBACK (on_colors_changed_cb),
+                           self,
+                           0);
+  on_colors_changed_cb (IDE_TERMINAL (terminal), self);
+
+  controller = gtk_event_controller_focus_new ();
+  g_signal_connect_object (controller,
+                           "enter",
                            G_CALLBACK (focus_in_event_cb),
                            self,
                            0);
+  gtk_widget_add_controller (GTK_WIDGET (terminal), controller);
+
 
   g_signal_connect_object (terminal,
                            "window-title-changed",
@@ -456,8 +395,8 @@ ide_terminal_page_get_file_or_directory (IdePage *page)
   if (self->destroyed)
     return NULL;
 
-  if (!(uri = vte_terminal_get_current_file_uri (VTE_TERMINAL (self->terminal_top))))
-    uri = vte_terminal_get_current_directory_uri (VTE_TERMINAL (self->terminal_top));
+  if (!(uri = vte_terminal_get_current_file_uri (VTE_TERMINAL (self->terminal))))
+    uri = vte_terminal_get_current_directory_uri (VTE_TERMINAL (self->terminal));
 
   if (uri != NULL)
     return g_file_new_for_uri (uri);
@@ -466,26 +405,18 @@ ide_terminal_page_get_file_or_directory (IdePage *page)
 }
 
 static void
-ide_terminal_page_destroy (GtkWidget *widget)
+ide_terminal_page_dispose (GObject *object)
 {
-  IdeTerminalPage *self = (IdeTerminalPage *)widget;
+  IdeTerminalPage *self = IDE_TERMINAL_PAGE (object);
 
   self->destroyed = TRUE;
 
-  GTK_WIDGET_CLASS (ide_terminal_page_parent_class)->destroy (widget);
-}
-
-static void
-ide_terminal_page_finalize (GObject *object)
-{
-  IdeTerminalPage *self = IDE_TERMINAL_PAGE (object);
-
   g_clear_object (&self->launcher);
-  g_clear_object (&self->save_as_file_top);
+  g_clear_object (&self->save_as_file);
   g_clear_pointer (&self->selection_buffer, g_free);
   g_clear_object (&self->pty);
 
-  G_OBJECT_CLASS (ide_terminal_page_parent_class)->finalize (object);
+  G_OBJECT_CLASS (ide_terminal_page_parent_class)->dispose (object);
 }
 
 static void
@@ -565,22 +496,19 @@ ide_terminal_page_class_init (IdeTerminalPageClass *klass)
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
   IdePageClass *page_class = IDE_PAGE_CLASS (klass);
 
-  object_class->finalize = ide_terminal_page_finalize;
+  object_class->dispose = ide_terminal_page_dispose;
   object_class->get_property = ide_terminal_page_get_property;
   object_class->set_property = ide_terminal_page_set_property;
 
   widget_class->realize = ide_terminal_page_realize;
-  widget_class->get_preferred_width = ide_terminal_page_get_preferred_width;
-  widget_class->get_preferred_height = ide_terminal_page_get_preferred_height;
   widget_class->grab_focus = ide_terminal_page_grab_focus;
-  widget_class->destroy = ide_terminal_page_destroy;
 
   page_class->create_split = ide_terminal_page_create_split;
   page_class->get_file_or_directory = ide_terminal_page_get_file_or_directory;
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/libide-terminal/ui/ide-terminal-page.ui");
-  gtk_widget_class_bind_template_child (widget_class, IdeTerminalPage, terminal_top);
-  gtk_widget_class_bind_template_child (widget_class, IdeTerminalPage, terminal_overlay_top);
+  gtk_widget_class_bind_template_child (widget_class, IdeTerminalPage, terminal);
+  gtk_widget_class_bind_template_child (widget_class, IdeTerminalPage, terminal_overlay);
 
   properties [PROP_CLOSE_ON_EXIT] =
     g_param_spec_boolean ("close-on-exit",
@@ -635,8 +563,6 @@ ide_terminal_page_class_init (IdeTerminalPageClass *klass)
 static void
 ide_terminal_page_init (IdeTerminalPage *self)
 {
-  GtkStyleContext *style_context;
-
   self->close_on_exit = TRUE;
   self->respawn_on_exit = TRUE;
   self->manage_spawn = TRUE;
@@ -644,11 +570,11 @@ ide_terminal_page_init (IdeTerminalPage *self)
   self->tsearch = g_object_new (IDE_TYPE_TERMINAL_SEARCH,
                                 "visible", TRUE,
                                 NULL);
-  self->search_revealer_top = ide_terminal_search_get_revealer (self->tsearch);
+  self->search_revealer = ide_terminal_search_get_revealer (self->tsearch);
 
   gtk_widget_init_template (GTK_WIDGET (self));
 
-  g_signal_connect_object (self->terminal_top,
+  g_signal_connect_object (self->terminal,
                            "text-inserted",
                            G_CALLBACK (ide_terminal_page_on_text_inserted_cb),
                            self,
@@ -658,25 +584,14 @@ ide_terminal_page_init (IdeTerminalPage *self)
   ide_page_set_can_split (IDE_PAGE (self), TRUE);
   ide_page_set_menu_id (IDE_PAGE (self), "ide-terminal-page-document-menu");
 
-  gtk_overlay_add_overlay (self->terminal_overlay_top, GTK_WIDGET (self->tsearch));
+  gtk_overlay_add_overlay (self->terminal_overlay, GTK_WIDGET (self->tsearch));
 
-  ide_terminal_page_connect_terminal (self, VTE_TERMINAL (self->terminal_top));
+  ide_terminal_page_connect_terminal (self, VTE_TERMINAL (self->terminal));
 
-  ide_terminal_search_set_terminal (self->tsearch, VTE_TERMINAL (self->terminal_top));
+  ide_terminal_search_set_terminal (self->tsearch, VTE_TERMINAL (self->terminal));
 
   ide_terminal_page_actions_init (self);
 
-  style_context = gtk_widget_get_style_context (GTK_WIDGET (self->terminal_top));
-  gtk_style_context_add_class (style_context, "terminal");
-  g_signal_connect_object (style_context,
-                           "changed",
-                           G_CALLBACK (style_context_changed),
-                           self,
-                           0);
-  style_context_changed (style_context, self);
-
-  gtk_widget_set_can_focus (GTK_WIDGET (self->terminal_top), TRUE);
-
   ide_widget_set_context_handler (self, ide_terminal_page_context_set);
 }
 
@@ -692,8 +607,8 @@ ide_terminal_page_set_pty (IdeTerminalPage *self,
 
   if (g_set_object (&self->pty, pty))
     {
-      vte_terminal_reset (VTE_TERMINAL (self->terminal_top), TRUE, TRUE);
-      vte_terminal_set_pty (VTE_TERMINAL (self->terminal_top), pty);
+      vte_terminal_reset (VTE_TERMINAL (self->terminal), TRUE, TRUE);
+      vte_terminal_set_pty (VTE_TERMINAL (self->terminal), pty);
     }
 }
 
@@ -704,8 +619,8 @@ ide_terminal_page_feed (IdeTerminalPage *self,
   g_return_if_fail (IDE_IS_TERMINAL_PAGE (self));
   g_return_if_fail (self->destroyed == FALSE);
 
-  if (self->terminal_top != NULL)
-    vte_terminal_feed (VTE_TERMINAL (self->terminal_top), message, -1);
+  if (self->terminal != NULL)
+    vte_terminal_feed (VTE_TERMINAL (self->terminal), message, -1);
 }
 
 void
@@ -742,5 +657,5 @@ ide_terminal_page_get_current_directory_uri (IdeTerminalPage *self)
   g_return_val_if_fail (IDE_IS_TERMINAL_PAGE (self), NULL);
   g_return_val_if_fail (self->destroyed == FALSE, NULL);
 
-  return vte_terminal_get_current_directory_uri (VTE_TERMINAL (self->terminal_top));
+  return vte_terminal_get_current_directory_uri (VTE_TERMINAL (self->terminal));
 }
diff --git a/src/libide/terminal/ide-terminal-search-private.h 
b/src/libide/terminal/ide-terminal-search-private.h
index 2ace9737d..a61e68398 100644
--- a/src/libide/terminal/ide-terminal-search-private.h
+++ b/src/libide/terminal/ide-terminal-search-private.h
@@ -20,20 +20,21 @@
 
 #pragma once
 
-#include <gtk/gtk.h>
-#include <libide-gui.h>
+#include "ide-terminal-search.h"
+
+#include <libide-gtk.h>
 
 G_BEGIN_DECLS
 
 struct _IdeTerminalSearch
 {
-  GtkBin               parent_instance;
+  AdwBin               parent_instance;
 
   VteTerminal         *terminal;
 
   GtkRevealer         *search_revealer;
 
-  IdeTaggedEntry      *search_entry;
+  IdeSearchEntry      *search_entry;
 
   GtkButton           *search_prev_button;
   GtkButton           *search_next_button;
@@ -52,7 +53,6 @@ struct _IdeTerminalSearch
   gchar               *regex_pattern;
   VteRegex            *regex;
 
-  GtkClipboard        *clipboard;
   gchar               *selected_text;
   gchar               *selection_buffer;
 };
diff --git a/src/libide/terminal/ide-terminal-search.c b/src/libide/terminal/ide-terminal-search.c
index a7e1c5627..b4c0a3ba4 100644
--- a/src/libide/terminal/ide-terminal-search.c
+++ b/src/libide/terminal/ide-terminal-search.c
@@ -24,16 +24,19 @@
 #include "config.h"
 
 #include <fcntl.h>
-#include <glib/gi18n.h>
 #include <pcre2.h>
 #include <stdlib.h>
-#include <vte/vte.h>
 #include <unistd.h>
 
+#include <glib/gi18n.h>
+#include <vte/vte.h>
+
+#include <libide-gtk.h>
+
 #include "ide-terminal-search.h"
 #include "ide-terminal-search-private.h"
 
-G_DEFINE_FINAL_TYPE (IdeTerminalSearch, ide_terminal_search, GTK_TYPE_BIN)
+G_DEFINE_FINAL_TYPE (IdeTerminalSearch, ide_terminal_search, ADW_TYPE_BIN)
 
 enum {
   PROP_0,
@@ -101,7 +104,7 @@ update_regex (IdeTerminalSearch *self)
 
   g_assert (IDE_IS_TERMINAL_SEARCH (self));
 
-  search_text = gtk_entry_get_text (GTK_ENTRY (self->search_entry));
+  search_text = gtk_editable_get_text (GTK_EDITABLE (self->search_entry));
   caseless = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->match_case_checkbutton));
 
   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->regex_checkbutton)))
@@ -150,7 +153,7 @@ update_regex (IdeTerminalSearch *self)
 }
 
 static void
-search_text_changed_cb (IdeTaggedEntry  *search_entry,
+search_text_changed_cb (IdeSearchEntry    *search_entry,
                         IdeTerminalSearch *self)
 {
   update_regex (self);
@@ -232,12 +235,19 @@ search_revealer_cb (GtkRevealer       *search_revealer,
 
   if (gtk_revealer_get_child_revealed (search_revealer))
     {
+#if 0
       if (vte_terminal_get_has_selection (self->terminal))
         {
           vte_terminal_copy_primary (self->terminal);
-          self->selected_text = gtk_clipboard_wait_for_text (self->clipboard);
-          gtk_entry_set_text (GTK_ENTRY (self->search_entry), self->selected_text);
+
+          g_clear_pointer (&self->selected_text, g_free);
+
+          /* TODO: Wait for async text read */
+
+          gtk_editable_set_text (GTK_EDITABLE (self->search_entry), self->selected_text);
         }
+#endif
+
       gtk_widget_grab_focus (GTK_WIDGET (self->search_entry));
     }
   else
@@ -341,8 +351,6 @@ ide_terminal_search_init (IdeTerminalSearch *self)
   self->regex_caseless = FALSE;
   self->regex_pattern = 0;
 
-  self->clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
-
   gtk_widget_init_template (GTK_WIDGET (self));
 
   g_signal_connect (self->search_prev_button, "clicked", G_CALLBACK (search_button_clicked_cb), self);
diff --git a/src/libide/terminal/ide-terminal-search.h b/src/libide/terminal/ide-terminal-search.h
index 1081b0d05..bacee6b00 100644
--- a/src/libide/terminal/ide-terminal-search.h
+++ b/src/libide/terminal/ide-terminal-search.h
@@ -4,7 +4,7 @@
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version ALL the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -15,7 +15,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
- * SPDX-License-Identifier: GPL-3.0-or-later
+ * SPDX-License-Identifier: GPL-ALLor-later
  */
 
 #pragma once
@@ -24,24 +24,26 @@
 # error "Only <libide-terminal.h> can be included directly."
 #endif
 
+#include <adwaita.h>
 #include <vte/vte.h>
+
 #include <libide-core.h>
 
 G_BEGIN_DECLS
 
 #define IDE_TYPE_TERMINAL_SEARCH (ide_terminal_search_get_type())
 
-IDE_AVAILABLE_IN_3_32
-G_DECLARE_FINAL_TYPE (IdeTerminalSearch, ide_terminal_search, IDE, TERMINAL_SEARCH, GtkBin)
+IDE_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (IdeTerminalSearch, ide_terminal_search, IDE, TERMINAL_SEARCH, AdwBin)
 
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
 VteRegex    *ide_terminal_search_get_regex       (IdeTerminalSearch *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
 gboolean     ide_terminal_search_get_wrap_around (IdeTerminalSearch *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
 void         ide_terminal_search_set_terminal    (IdeTerminalSearch *self,
                                                   VteTerminal       *terminal);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
 GtkRevealer *ide_terminal_search_get_revealer    (IdeTerminalSearch *self);
 
 G_END_DECLS
diff --git a/src/libide/terminal/ide-terminal-search.ui b/src/libide/terminal/ide-terminal-search.ui
index e349e8927..a4efbd42c 100644
--- a/src/libide/terminal/ide-terminal-search.ui
+++ b/src/libide/terminal/ide-terminal-search.ui
@@ -5,118 +5,80 @@
     <property name="valign">start</property>
     <child>
       <object class="GtkRevealer" id="search_revealer">
-        <property name="visible">true</property>
         <child>
           <object class="GtkFrame">
-            <property name="visible">true</property>
             <property name="margin-end">12</property>
             <style>
               <class name="search-frame"/>
             </style>
             <child>
               <object class="GtkBox">
-                <property name="visible">true</property>
                 <property name="orientation">vertical</property>
                 <property name="spacing">7</property>
                 <child>
                   <object class="GtkGrid">
-                    <property name="visible">true</property>
-                    <property name="can_focus">false</property>
                     <property name="row_spacing">8</property>
                     <property name="column_spacing">8</property>
                     <child>
-                      <object class="IdeTaggedEntry" id="search_entry">
-                        <property name="visible">true</property>
-                        <property name="can_focus">true</property>
+                      <object class="IdeSearchEntry" id="search_entry">
                         <property name="width-chars">20</property>
                         <property name="max-width-chars">30</property>
-                        <property name="primary_icon_name">edit-find-symbolic</property>
-                        <property name="primary_icon_activatable">false</property>
-                        <property name="primary_icon_sensitive">false</property>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">0</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkBox">
                         <property name="homogeneous">true</property>
-                        <property name="visible">true</property>
-                        <property name="can_focus">false</property>
                         <property name="valign">center</property>
                         <style>
                           <class name="linked"/>
                         </style>
                         <child>
                           <object class="GtkButton" id="search_prev_button">
-                            <property name="visible">true</property>
-                            <property name="can_focus">false</property>
-                            <property name="receives_default">true</property>
                             <child>
                               <object class="GtkImage">
-                                <property name="visible">true</property>
-                                <property name="can_focus">false</property>
                                 <property name="icon_name">go-up-symbolic</property>
                                 <property name="icon_size">1</property>
                               </object>
                             </child>
                           </object>
-                          <packing>
-                            <property name="expand">false</property>
-                            <property name="fill">true</property>
-                            <property name="position">0</property>
-                          </packing>
                         </child>
                         <child>
                           <object class="GtkButton" id="search_next_button">
-                            <property name="visible">true</property>
-                            <property name="can_focus">false</property>
-                            <property name="receives_default">true</property>
                             <child>
                               <object class="GtkImage">
-                                <property name="visible">true</property>
-                                <property name="can_focus">false</property>
                                 <property name="icon_name">go-down-symbolic</property>
                                 <property name="icon_size">1</property>
                               </object>
                             </child>
                           </object>
-                          <packing>
-                            <property name="expand">false</property>
-                            <property name="fill">true</property>
-                            <property name="position">1</property>
-                          </packing>
                         </child>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">0</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkToggleButton" id="reveal_button">
                         <property name="action-target">true</property>
                         <property name="tooltip-text" translatable="yes">Show or hide search options such as 
case sensitivity</property>
-                        <property name="visible">true</property>
-                        <property name="can_focus">true</property>
-                        <property name="receives_default">true</property>
                         <child>
                           <object class="GtkImage">
-                            <property name="visible">true</property>
-                            <property name="can_focus">false</property>
                             <property name="icon_name">emblem-system-symbolic</property>
                           </object>
                         </child>
+                        <layout>
+                          <property name="column">2</property>
+                          <property name="row">0</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="top_attach">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkButton" id="close_button">
-                        <property name="visible">true</property>
                         <property name="halign">center</property>
                         <property name="valign">center</property>
                         <property name="focus_on_click">false</property>
@@ -125,76 +87,57 @@
                         </style>
                         <child>
                           <object class="GtkImage">
-                            <property name="visible">true</property>
                             <property name="icon_name">window-close-symbolic</property>
                           </object>
                         </child>
+                        <layout>
+                          <property name="column">3</property>
+                          <property name="row">0</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left_attach">3</property>
-                        <property name="top_attach">0</property>
-                      </packing>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">false</property>
-                    <property name="fill">true</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkGrid" id="search_options">
                     <property name="visible">false</property>
-                    <property name="can_focus">false</property>
                     <property name="column_spacing">8</property>
                     <child>
                       <object class="GtkCheckButton" id="regex_checkbutton">
                         <property name="label" translatable="yes">Regex</property>
-                        <property name="visible">true</property>
-                        <property name="can_focus">false</property>
-                        <property name="receives_default">false</property>
                         <property name="xalign">0</property>
                         <property name="draw_indicator">true</property>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">0</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkCheckButton" id="match_case_checkbutton">
                         <property name="label" translatable="yes">Case sensitive</property>
-                        <property name="visible">true</property>
-                        <property name="can_focus">false</property>
-                        <property name="receives_default">false</property>
                         <property name="xalign">0</property>
                         <property name="draw_indicator">true</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">0</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkCheckButton" id="entire_word_checkbutton">
                         <property name="label" translatable="yes">Match whole word</property>
-                        <property name="visible">true</property>
-                        <property name="can_focus">false</property>
-                        <property name="receives_default">false</property>
                         <property name="xalign">0</property>
                         <property name="draw_indicator">true</property>
+                        <layout>
+                          <property name="column">2</property>
+                          <property name="row">0</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="top_attach">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkCheckButton" id="wrap_around_checkbutton">
                         <property name="label" translatable="yes">Wrap around</property>
-                        <property name="visible">true</property>
-                        <property name="can_focus">false</property>
-                        <property name="receives_default">false</property>
                         <property name="xalign">0</property>
                         <property name="draw_indicator">true</property>
                       </object>
diff --git a/src/libide/terminal/ide-terminal.c b/src/libide/terminal/ide-terminal.c
index a3b8f9a6e..5e827d90f 100644
--- a/src/libide/terminal/ide-terminal.c
+++ b/src/libide/terminal/ide-terminal.c
@@ -36,6 +36,8 @@ typedef struct
   GtkWidget *popup_menu;
   GSettings *settings;
   gchar     *url;
+  GdkRGBA    bg;
+  GdkRGBA    fg;
 } IdeTerminalPrivate;
 
 typedef struct
@@ -58,6 +60,7 @@ enum {
   POPULATE_POPUP,
   SELECT_ALL,
   SEARCH_REVEAL,
+  COLORS_CHANGED,
   N_SIGNALS
 };
 
@@ -92,10 +95,28 @@ static const GdkRGBA solarized_palette[] = {
   { 0.992156, 0.964705, 0.890196, 1 },
 };
 
+void
+ide_terminal_get_colors (IdeTerminal *self,
+                         GdkRGBA     *bg,
+                         GdkRGBA     *fg)
+{
+  IdeTerminalPrivate *priv = ide_terminal_get_instance_private (self);
+
+  g_return_if_fail (IDE_IS_TERMINAL (self));
+
+  if (bg)
+    *bg = priv->bg;
+
+  if (fg)
+    *fg = priv->fg;
+}
+
 static void
 ide_terminal_css_changed (GtkWidget         *widget,
                           GtkCssStyleChange *change)
 {
+  IdeTerminal *self = (IdeTerminal *)widget;
+  IdeTerminalPrivate *priv = ide_terminal_get_instance_private (self);
   GtkStyleContext *style_context;
   GdkRGBA fg;
   GdkRGBA bg;
@@ -113,6 +134,11 @@ ide_terminal_css_changed (GtkWidget         *widget,
   vte_terminal_set_colors (VTE_TERMINAL (widget),
                            &fg, &bg,
                            solarized_palette, G_N_ELEMENTS (solarized_palette));
+
+  priv->fg = fg;
+  priv->bg = bg;
+
+  g_signal_emit (self, signals [COLORS_CHANGED], 0);
 }
 
 #if 0
@@ -494,6 +520,14 @@ ide_terminal_class_init (IdeTerminalClass *klass)
   filename_regex = g_regex_new (FILENAME_PLUS_LOCATION, 0, 0, NULL);
   g_assert (filename_regex != NULL);
 
+  signals [COLORS_CHANGED] =
+    g_signal_new ("colors-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
   signals [COPY_LINK_ADDRESS] =
     g_signal_new ("copy-link-address",
                   G_TYPE_FROM_CLASS (klass),
diff --git a/src/libide/terminal/ide-terminal.h b/src/libide/terminal/ide-terminal.h
index c4687e6c2..c797d6c92 100644
--- a/src/libide/terminal/ide-terminal.h
+++ b/src/libide/terminal/ide-terminal.h
@@ -31,7 +31,7 @@ G_BEGIN_DECLS
 
 #define IDE_TYPE_TERMINAL (ide_terminal_get_type())
 
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
 G_DECLARE_DERIVABLE_TYPE (IdeTerminal, ide_terminal, IDE, TERMINAL, VteTerminal)
 
 struct _IdeTerminalClass
@@ -45,12 +45,13 @@ struct _IdeTerminalClass
   void     (*search_reveal)       (IdeTerminal *self);
   gboolean (*open_link)           (IdeTerminal *self);
   gboolean (*copy_link_address)   (IdeTerminal *self);
-
-  /*< private >*/
-  gpointer padding[16];
 };
 
-IDE_AVAILABLE_IN_3_32
-GtkWidget *ide_terminal_new (void);
+IDE_AVAILABLE_IN_ALL
+GtkWidget *ide_terminal_new        (void);
+IDE_AVAILABLE_IN_ALL
+void       ide_terminal_get_colors (IdeTerminal *self,
+                                    GdkRGBA     *bg,
+                                    GdkRGBA     *fg);
 
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]