Merge the GTK4 branch as it is now usable
--- a/demo/data/demo.ui Sat Aug 13 22:03:08 2022 -0500
+++ b/demo/data/demo.ui Sun Aug 28 22:44:59 2022 -0500
@@ -20,549 +20,302 @@
<requires lib="Talkatu" version="0.0"/>
- <requires lib="gtk+" version="3.18"/>
+ <requires lib="gtk" version="4.0"/> <!-- interface-license-type gplv2 -->
<!-- interface-name Talkatu -->
<!-- interface-description GTK widgets for chat applications -->
<!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
+ <object class="TalkatuAutoScroller" id="auto_scroller"/> <template class="TalkatuDemoWindow" parent="GtkApplicationWindow">
- <property name="can-focus">False</property>
- <property name="border-width">12</property>
+ <property name="child"> <object class="GtkPaned">
- <property name="visible">True</property>
- <property name="can-focus">True</property>
+ <property name="shrink-end-child">0</property> + <property name="shrink-start-child">0</property> <property name="orientation">vertical</property>
- <property name="wide-handle">True</property>
+ <property name="wide-handle">1</property> - <object class="TalkatuScrolledWindow">
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="shadow-type">in</property>
+ <object class="GtkScrolledWindow"> + <property name="vadjustment">auto_scroller</property> <object class="TalkatuHistory" id="history">
<property name="name">history</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="hexpand-set">True</property>
- <property name="vexpand-set">True</property>
- <property name="resize">True</property>
- <property name="shrink">False</property>
- <property name="visible">True</property>
- <property name="can-focus">False</property>
<property name="orientation">vertical</property>
- <object class="GtkToolbar">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkBox"> + <class name="toolbar"/> + <property name="can-focus">0</property> - <object class="GtkRadioToolButton" id="toggle_plain">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkToggleButton" id="toggle_plain"> + <property name="can-focus">0</property> <property name="tooltip-text" translatable="yes">Use a TalkatuBuffer</property>
<property name="label" translatable="yes">Plain</property>
- <property name="use-underline">True</property>
+ <property name="use-underline">1</property> <property name="icon-name">text-x-generic</property>
- <property name="active">True</property>
+ <property name="active">1</property> <signal name="toggled" handler="talkatu_demo_window_buffer_changed_cb" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkRadioToolButton" id="toggle_whole">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkToggleButton" id="toggle_whole"> + <property name="can-focus">0</property> <property name="tooltip-text" translatable="yes">Use a TalkatuWholeBuffer</property>
<property name="label" translatable="yes">Whole</property>
- <property name="use-underline">True</property>
+ <property name="use-underline">1</property> <property name="icon-name">ascii</property>
<property name="group">toggle_plain</property>
<signal name="toggled" handler="talkatu_demo_window_buffer_changed_cb" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkRadioToolButton" id="toggle_html">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkToggleButton" id="toggle_html"> + <property name="can-focus">0</property> <property name="tooltip-text" translatable="yes">Use a TalkatuHTMLBuffer</property>
<property name="label" translatable="yes">HTML</property>
- <property name="use-underline">True</property>
+ <property name="use-underline">1</property> <property name="icon-name">text-html</property>
<property name="group">toggle_plain</property>
<signal name="toggled" handler="talkatu_demo_window_buffer_changed_cb" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkRadioToolButton" id="toggle_markdown">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkToggleButton" id="toggle_markdown"> + <property name="can-focus">0</property> <property name="tooltip-text" translatable="yes">Use a TalkatuMarkdownBuffer</property>
<property name="label" translatable="yes">Markdown</property>
- <property name="use-underline">True</property>
+ <property name="use-underline">1</property> <property name="icon-name">text-x-generic-template</property>
<property name="group">toggle_plain</property>
<signal name="toggled" handler="talkatu_demo_window_buffer_changed_cb" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkSeparatorToolItem">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkSeparator"> + <property name="orientation">vertical</property> + <property name="can-focus">0</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToolButton">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkButton"> + <property name="can-focus">0</property> <property name="tooltip-text" translatable="yes">Insert HTML from a file</property>
<property name="label" translatable="yes">Insert HTML</property>
- <property name="use-underline">True</property>
+ <property name="use-underline">1</property> <property name="icon-name">text-html</property>
<signal name="clicked" handler="talkatu_demo_window_insert_html_cb" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToolButton">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkButton"> + <property name="can-focus">0</property> <property name="tooltip-text" translatable="yes">Insert Markdown from a file</property>
<property name="label" translatable="yes">Insert Markdown</property>
- <property name="use-underline">True</property>
+ <property name="use-underline">1</property> <property name="icon-name">text-x-generic</property>
<signal name="clicked" handler="talkatu_demo_window_insert_markdown_cb" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkSeparatorToolItem">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkSeparator"> + <property name="orientation">vertical</property> + <property name="can-focus">0</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToggleToolButton" id="author_button">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes">Author</property>
- <property name="use-underline">True</property>
+ <object class="GtkMenuButton" id="author_button"> + <property name="can-focus">0</property> <property name="icon-name">system-users</property>
- <signal name="toggled" handler="talkatu_demo_window_author_toggled_cb" object="author_popover" swapped="no"/>
+ <property name="label" translatable="yes">Author</property> + <property name="menu-model">author_menu</property> + <property name="use-underline">1</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToggleToolButton" id="author_name_color_button">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes">Color</property>
- <property name="use-underline">True</property>
+ <object class="GtkMenuButton" id="author_name_color_button"> + <property name="can-focus">0</property> <property name="icon-name">color-select-symbolic</property>
- <signal name="toggled" handler="talkatu_demo_window_author_name_color_toggled_cb" object="author_name_color_popover" swapped="no"/>
+ <property name="label" translatable="yes">Color</property> + <property name="menu-model">author_name_color_menu</property> + <property name="use-underline">1</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
+ <object class="GtkSeparator"> + <property name="orientation">vertical</property> + <property name="can-focus">0</property> - <object class="GtkSeparatorToolItem">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToggleToolButton" id="toggle_toolbar">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkToggleButton" id="toggle_toolbar"> + <property name="can-focus">0</property> <property name="tooltip-text" translatable="yes">Toggle toolbar visibility</property>
<property name="label" translatable="yes">Toolbar</property>
- <property name="use-underline">True</property>
+ <property name="use-underline">1</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToggleToolButton" id="toggle_send_button">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkToggleButton" id="toggle_send_button"> + <property name="can-focus">0</property> <property name="tooltip-text" translatable="yes">Toggle send button visibility</property>
<property name="label" translatable="yes">Send Button</property>
- <property name="use-underline">True</property>
+ <property name="use-underline">1</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToggleToolButton" id="toggle_edited">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkToggleButton" id="toggle_edited"> + <property name="can-focus">0</property> <property name="tooltip-text" translatable="yes">Toggle whether the message is edited</property>
<property name="label" translatable="yes">Edited</property>
- <property name="use-underline">True</property>
+ <property name="use-underline">1</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
<object class="TalkatuEditor" id="editor">
+ <property name="vexpand">1</property> <property name="orientation">vertical</property>
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="hexpand-set">True</property>
<property name="vexpand-set">True</property>
<child internal-child="toolbar">
<object class="TalkatuToolbar">
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="hexpand-set">True</property>
<property name="vexpand-set">True</property>
- <property name="fill">False</property>
<child internal-child="input">
<object class="TalkatuInput">
- <property name="hexpand-set">True</property>
- <property name="vexpand-set">True</property>
<property name="buffer">buffer_plain</property>
+ <property name="author">Alice</property> + <property name="send-binding">1</property> <signal name="open-url" handler="talkatu_demo_window_view_open_url_cb" object="TalkatuDemoWindow" swapped="no"/>
<signal name="send-message" handler="talkatu_demo_window_view_send_message_cb" object="TalkatuDemoWindow" swapped="no"/>
- <property name="fill">False</property>
<child internal-child="send_button">
<object class="GtkButton">
- <property name="can-focus">False</property>
- <property name="receives-default">False</property>
+ <property name="visible">0</property> + <property name="can-focus">0</property>
- <property name="fill">False</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
<object class="TalkatuTypingLabel" id="typing">
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- <property name="resize">True</property>
- <property name="shrink">False</property>
- <object class="GtkPopover" id="author_name_color_popover">
- <property name="can-focus">False</property>
- <property name="relative-to">author_name_color_button</property>
- <signal name="closed" handler="talkatu_demo_window_author_name_color_popover_closed_cb" object="author_name_color_button" swapped="no"/>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="border-width">6</property>
- <property name="orientation">vertical</property>
- <object class="GtkRadioButton" id="author_name_color_item">
- <property name="label" translatable="yes">Not set</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="active">True</property>
- <property name="draw-indicator">True</property>
- <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">Red</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_name_color_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">Green</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_name_color_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">Blue</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_name_color_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">Yellow</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_name_color_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">4</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">Purple</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_name_color_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">5</property>
- <object class="GtkPopover" id="author_popover">
- <property name="can-focus">False</property>
- <property name="relative-to">author_button</property>
- <signal name="closed" handler="talkatu_demo_window_author_popover_closed_cb" object="author_button" swapped="no"/>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="border-width">6</property>
- <property name="orientation">vertical</property>
- <object class="GtkRadioButton" id="author_item">
- <property name="label" translatable="yes">Alice</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="active">True</property>
- <property name="draw-indicator">True</property>
- <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">Bob</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">Carol</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">David</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">Eve</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">4</property>
- <object class="GtkRadioButton">
- <property name="label" translatable="yes">Mallory</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="draw-indicator">True</property>
- <property name="group">author_item</property>
- <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">5</property>
- <object class="TalkatuTagTable" id="table_history"/>
- <object class="TalkatuTagTable" id="table_html"/>
+ <menu id="author_menu"> + <attribute name="label" translatable="yes">Alice</attribute> + <attribute name="action">win.author-name</attribute> + <attribute name="target" translatable="yes">Alice</attribute> + <attribute name="label" translatable="yes">Bob</attribute> + <attribute name="action">win.author-name</attribute> + <attribute name="target" translatable="yes">Bob</attribute> + <attribute name="label" translatable="yes">Carol</attribute> + <attribute name="action">win.author-name</attribute> + <attribute name="target" translatable="yes">Carol</attribute> + <attribute name="label" translatable="yes">David</attribute> + <attribute name="action">win.author-name</attribute> + <attribute name="target" translatable="yes">David</attribute> + <attribute name="label" translatable="yes">Eve</attribute> + <attribute name="action">win.author-name</attribute> + <attribute name="target" translatable="yes">Eve</attribute> + <attribute name="label" translatable="yes">Mallory</attribute> + <attribute name="action">win.author-name</attribute> + <attribute name="target" translatable="yes">Mallory</attribute> + <menu id="author_name_color_menu"> + <attribute name="label" translatable="yes">Not set</attribute> + <attribute name="action">win.author-name-color</attribute> + <attribute name="target"></attribute> + <attribute name="label" translatable="yes">Red</attribute> + <attribute name="action">win.author-name-color</attribute> + <attribute name="target">red</attribute> + <attribute name="label" translatable="yes">Green</attribute> + <attribute name="action">win.author-name-color</attribute> + <attribute name="target">green</attribute> + <attribute name="label" translatable="yes">Blue</attribute> + <attribute name="action">win.author-name-color</attribute> + <attribute name="target">blue</attribute> + <attribute name="label" translatable="yes">Yellow</attribute> + <attribute name="action">win.author-name-color</attribute> + <attribute name="target">yellow</attribute> + <attribute name="label" translatable="yes">Purple</attribute> + <attribute name="action">win.author-name-color</attribute> + <attribute name="target">purple</attribute> <object class="TalkatuHtmlBuffer" id="buffer_html">
- <property name="tag-table">table_html</property>
<signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
- <object class="TalkatuTagTable" id="table_markdown"/>
<object class="TalkatuMarkdownBuffer" id="buffer_markdown">
- <property name="tag-table">table_markdown</property>
<signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
- <object class="TalkatuTagTable" id="table_plain"/>
<object class="TalkatuBuffer" id="buffer_plain">
- <property name="tag-table">table_plain</property>
<signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
<object class="TalkatuWholeBuffer" id="buffer_whole">
- <property name="tag-table">table_plain</property>
<property name="style">whole</property>
<signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
--- a/demo/meson.build Sat Aug 13 22:03:08 2022 -0500
+++ b/demo/meson.build Sun Aug 28 22:44:59 2022 -0500
@@ -24,7 +24,7 @@
c_args : ['-DG_LOG_USE_STRUCTURED', '-DG_LOG_DOMAIN="Talkatu-Demo"'],
- dependencies: [GLIB, GTK3, talkatu_dep],
+ dependencies: [GLIB, GTK4, talkatu_dep], include_directories : top_srcdir,
install: get_option('install-demo'),
--- a/demo/talkatudemowindow.c Sat Aug 13 22:03:08 2022 -0500
+++ b/demo/talkatudemowindow.c Sun Aug 28 22:44:59 2022 -0500
@@ -28,14 +28,14 @@
- GtkRadioToolButton *toggle_plain;
- GtkRadioToolButton *toggle_whole;
- GtkRadioToolButton *toggle_html;
- GtkRadioToolButton *toggle_markdown;
+ GtkToggleButton *toggle_plain; + GtkToggleButton *toggle_whole; + GtkToggleButton *toggle_html; + GtkToggleButton *toggle_markdown; - GtkToggleToolButton *toggle_toolbar;
- GtkToggleToolButton *toggle_send_button;
- GtkToggleToolButton *toggle_edited;
+ GtkToggleButton *toggle_toolbar; + GtkToggleButton *toggle_send_button; + GtkToggleButton *toggle_edited; GtkTextBuffer *buffer_plain;
GtkTextBuffer *buffer_whole;
@@ -43,8 +43,6 @@
GtkTextBuffer *buffer_markdown;
GtkWidget *author_button;
- GtkWidget *author_popover;
- GtkWidget *author_item;
G_DEFINE_TYPE(TalkatuDemoWindow, talkatu_demo_window, GTK_TYPE_APPLICATION_WINDOW);
@@ -56,11 +54,11 @@
TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
if(response == GTK_RESPONSE_ACCEPT) {
- gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dialog)); - if(g_file_get_contents(filename, &contents, &len, NULL)) {
+ if(g_file_load_contents(file, NULL, &contents, &len, NULL, NULL)) { GtkTextMark *mark = NULL;
@@ -71,7 +69,7 @@
gtk_native_dialog_destroy(dialog);
@@ -111,11 +109,11 @@
TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
if(response == GTK_RESPONSE_ACCEPT) {
- gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dialog)); - if(g_file_get_contents(filename, &contents, &len, NULL)) {
+ if(g_file_load_contents(file, NULL, &contents, &len, NULL, NULL)) { GtkTextMark *mark = NULL;
@@ -126,7 +124,7 @@
gtk_native_dialog_destroy(dialog);
@@ -164,16 +162,16 @@
TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
GtkWidget *view = talkatu_editor_get_input(TALKATU_EDITOR(window->editor));
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(window->toggle_plain))) {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->toggle_plain))) { g_message("switching to plain buffer");
gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), window->buffer_plain);
- } else if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(window->toggle_whole))) {
+ } else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->toggle_whole))) { g_message("switching to whole buffer");
gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), window->buffer_whole);
- } else if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(window->toggle_html))) {
+ } else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->toggle_html))) { g_message("switching to html buffer");
gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), window->buffer_html);
- } else if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(window->toggle_markdown))) {
+ } else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->toggle_markdown))) { g_message("switching to markdown buffer");
gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), window->buffer_markdown);
@@ -199,21 +197,10 @@
-talkatu_demo_window_view_open_url_cb(TalkatuView *view, const gchar *url, gpointer data) {
- gboolean success = FALSE;
- success = gtk_show_uri_on_window(
- GTK_WINDOW(data), url, GDK_CURRENT_TIME, &error);
- "failed to open uri '%s': %s",
- (error) ? error->message : NULL
+talkatu_demo_window_view_open_url_cb(G_GNUC_UNUSED TalkatuView *view, + const gchar *url, gpointer data) + gtk_show_uri(GTK_WINDOW(data), url, GDK_CURRENT_TIME); @@ -236,69 +223,47 @@
-talkatu_demo_window_author_toggled_cb(GtkToolButton *button, gpointer data) {
- GtkPopover *popover = GTK_POPOVER(data);
- gtk_popover_popup(popover);
-talkatu_demo_window_author_popover_closed_cb(GtkPopover *popover, gpointer data) {
- GtkToggleToolButton *button = GTK_TOGGLE_TOOL_BUTTON(data);
+talkatu_demo_window_author_changed(GSimpleAction *action, GVariant *parameter, + TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data); + const gchar *author = NULL; + TalkatuEditor *editor = NULL; + GtkWidget *input = NULL; - gtk_toggle_tool_button_set_active(button, FALSE);
-talkatu_demo_window_author_changed(GtkRadioButton *item, gpointer data) {
- TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
+ author = g_variant_get_string(parameter, NULL); + g_message("Changing author to %s", author); - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item))) {
- TalkatuEditor *editor = TALKATU_EDITOR(window->editor);
- GtkWidget *input = talkatu_editor_get_input(editor);
+ editor = TALKATU_EDITOR(window->editor); + input = talkatu_editor_get_input(editor); + talkatu_message_set_author(TALKATU_MESSAGE(input), author); - talkatu_message_set_author(TALKATU_MESSAGE(input),
- gtk_button_get_label(GTK_BUTTON(item)));
+ g_action_change_state(G_ACTION(action), parameter); -talkatu_demo_window_author_name_color_toggled_cb(GtkToolButton *button,
- GtkPopover *popover = GTK_POPOVER(data);
- gtk_popover_popup(popover);
-talkatu_demo_window_author_name_color_popover_closed_cb(GtkPopover *popover,
- GtkToggleToolButton *button = GTK_TOGGLE_TOOL_BUTTON(data);
- gtk_toggle_tool_button_set_active(button, FALSE);
-talkatu_demo_window_author_name_color_changed(GtkRadioButton *item,
+talkatu_demo_window_author_name_color_changed(GSimpleAction *action, TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
+ const gchar *color_str = NULL; + TalkatuEditor *editor = NULL; + GtkWidget *input = NULL; - if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item))) {
- TalkatuEditor *editor = TALKATU_EDITOR(window->editor);
- GtkWidget *input = talkatu_editor_get_input(editor);
- const gchar *label = gtk_button_get_label(GTK_BUTTON(item));
+ color_str = g_variant_get_string(parameter, NULL); + g_message("Changing author name colour to %s", color_str); - if(gdk_rgba_parse(&color, label)) {
- talkatu_message_set_author_name_color(TALKATU_MESSAGE(input),
- talkatu_message_set_author_name_color(TALKATU_MESSAGE(input), NULL);
+ editor = TALKATU_EDITOR(window->editor); + input = talkatu_editor_get_input(editor); + if(gdk_rgba_parse(&color, color_str)) { + talkatu_message_set_author_name_color(TALKATU_MESSAGE(input), &color); + talkatu_message_set_author_name_color(TALKATU_MESSAGE(input), NULL); + g_action_change_state(G_ACTION(action), parameter); /******************************************************************************
@@ -306,12 +271,16 @@
*****************************************************************************/
talkatu_demo_window_init(TalkatuDemoWindow *window) {
- gtk_widget_init_template(GTK_WIDGET(window));
+ const GActionEntry entries[] = { + { "author-name", talkatu_demo_window_author_changed, "s", "'Alice'" }, + { "author-name-color", talkatu_demo_window_author_name_color_changed, - /* activate the first menu item to make sure its label gets stored
- talkatu_demo_window_author_changed(GTK_RADIO_BUTTON(window->author_item), window);
+ g_action_map_add_action_entries(G_ACTION_MAP(window), entries, + G_N_ELEMENTS(entries), window); + gtk_widget_init_template(GTK_WIDGET(window)); window->editor, "show-toolbar",
@@ -356,8 +325,6 @@
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_markdown);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, author_button);
- gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, author_popover);
- gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, author_item);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_toolbar);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_send_button);
@@ -371,13 +338,9 @@
gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_insert_html_cb);
gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_insert_markdown_cb);
- gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_toggled_cb);
- gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_popover_closed_cb);
- gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_changed);
- gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_name_color_toggled_cb);
- gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_name_color_popover_closed_cb);
- gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_name_color_changed);
+ gtk_widget_class_add_binding_action(widget_class, + GDK_KEY_w, GDK_CONTROL_MASK, /******************************************************************************
--- a/meson.build Sat Aug 13 22:03:08 2022 -0500
+++ b/meson.build Sun Aug 28 22:44:59 2022 -0500
@@ -37,8 +37,7 @@
GLIB = dependency('glib-2.0', version : '>=2.52.0')
GOBJECT = dependency('gobject-2.0')
-GTK3 = dependency('gtk+-3.0', version : '>=3.24.0')
-GSPELL = dependency('gspell-1', version : '>=1.2')
+GTK4 = dependency('gtk4', version : '>=4.0.0') GUMBO = dependency('gumbo', version : '>=0.10')
--- a/po/POTFILES Sat Aug 13 22:03:08 2022 -0500
+++ b/po/POTFILES Sun Aug 28 22:44:59 2022 -0500
@@ -5,13 +5,18 @@
talkatu/data/attachmentpreview.ui
talkatu/data/historyrow.ui
talkatu/data/linkdialog.ui
-talkatu/data/messageactions.ui
+talkatu/data/scrolledwindow.ui +talkatu/data/typinglabel.ui talkatu/talkatuactiongroup.c
talkatu/talkatuattachment.c
talkatu/talkatuattachmentdialog.c
talkatu/talkatuattachmentpreview.c
+talkatu/talkatuautoscroller.c @@ -24,15 +29,11 @@
talkatu/talkatulinkdialog.c
talkatu/talkatumarkdownbuffer.c
-talkatu/talkatumenutoolbutton.c
-talkatu/talkatumessageactions.c
-talkatu/talkatuscrolledwindow.c
talkatu/talkatusimpleattachment.c
talkatu/talkatutagtable.c
-talkatu/talkatutooldrawer.c
talkatu/talkatutypinglabel.c
talkatu/talkatuwholebuffer.c
--- a/talkatu/data/attachmentdialog.ui Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/data/attachmentdialog.ui Sun Aug 28 22:44:59 2022 -0500
@@ -19,102 +19,34 @@
- <requires lib="gtk+" version="3.18"/>
+ <requires lib="gtk" version="4.0"/> <!-- interface-license-type gplv2 -->
<!-- interface-name Talkatu -->
<!-- interface-description GTK widgets for chat applications -->
<!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
<template class="TalkatuAttachmentDialog" parent="GtkDialog">
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="modal">True</property>
- <property name="type_hint">dialog</property>
- <child internal-child="vbox">
+ <property name="modal">1</property> + <child internal-child="content_area"> - <property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox">
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
- <object class="GtkButton" id="cancel">
- <property name="label" translatable="yes">Cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkButton" id="upload">
- <property name="label" translatable="yes">Upload</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">True</property>
- <accelerator key="Return" signal="clicked"/>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
<object class="GtkImage" id="preview">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="pixel_size">256</property>
<property name="icon_name">text-x-generic-template</property>
- <property name="icon_size">6</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
<object class="GtkLabel" id="filename">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes"><filename></property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
<object class="GtkEntry" id="comment">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
+ <property name="activates_default">1</property> + <property name="focusable">1</property> <property name="placeholder_text" translatable="yes">Comment (optional)</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
@@ -122,5 +54,18 @@
<action-widget response="-6">cancel</action-widget>
<action-widget response="-3">upload</action-widget>
+ <object class="GtkButton" id="cancel"> + <property name="label" translatable="yes">Cancel</property> + <property name="focusable">1</property> + <object class="GtkButton" id="upload"> + <property name="label" translatable="yes">Upload</property> + <property name="focusable">1</property> + <property name="receives_default">1</property> --- a/talkatu/data/attachmentpreview.ui Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/data/attachmentpreview.ui Sun Aug 28 22:44:59 2022 -0500
@@ -19,112 +19,62 @@
- <requires lib="gtk+" version="3.18"/>
+ <requires lib="gtk" version="4.0"/> <!-- interface-license-type gplv2 -->
<!-- interface-name Talkatu -->
<!-- interface-description GTK widgets for chat applications -->
<!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
- <template class="TalkatuAttachmentPreview" parent="GtkInfoBar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox">
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <property name="layout_style">end</property>
- <object class="GtkButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="talkatu_attachment_preview_download_cb" object="TalkatuAttachmentPreview" swapped="no"/>
+ <template class="TalkatuAttachmentPreview" parent="GtkWidget"> + <object class="GtkInfoBar"> + <property name="hexpand">1</property> + <signal name="response" handler="talkatu_attachment_preview_download_cb" object="TalkatuAttachmentPreview" swapped="no"/> + <object class="GtkButton" id="download_button"> <object class="GtkImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="icon_name">document-save-symbolic</property>
- <property name="icon_size">5</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- <property name="non_homogeneous">True</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- <child internal-child="content_area">
- <object class="GtkBox">
- <property name="can_focus">False</property>
- <property name="spacing">16</property>
- <object class="GtkImage" id="preview">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">text-x-generic</property>
- <property name="icon_size">6</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <action-widget response="0">download_button</action-widget> - <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
+ <property name="can_focus">0</property> + <property name="spacing">16</property> - <object class="GtkLabel" id="filename">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">unknown</property>
- <property name="xalign">0</property>
+ <object class="GtkImage" id="preview"> + <property name="can_focus">0</property> + <property name="icon_name">text-x-generic</property> + <property name="icon_size">large</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkLabel" id="filesize">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
+ <object class="GtkBox"> + <property name="hexpand">1</property> + <property name="can_focus">0</property> + <property name="orientation">vertical</property> + <object class="GtkLabel" id="filename"> + <property name="can_focus">0</property> + <property name="label" translatable="yes">unknown</property> + <property name="xalign">0</property> + <object class="GtkLabel" id="filesize"> + <property name="can_focus">0</property> + <property name="xalign">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
--- a/talkatu/data/editor.ui Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/data/editor.ui Sun Aug 28 22:44:59 2022 -0500
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.1
Talkatu - GTK widgets for chat applications
-Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
+Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com> This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,82 +15,49 @@
You should have received a copy of the GNU General Public License
along with this library; if not, see <https://www.gnu.org/licenses/>.
<requires lib="Talkatu" version="0.0"/>
- <requires lib="gtk+" version="3.20"/>
- <object class="TalkatuTagTable" id="table"/>
- <object class="TalkatuBuffer" id="buffer">
- <property name="tag_table">table</property>
+ <requires lib="gtk" version="4.0"/> <!-- interface-license-type gplv2 -->
- <!-- interface-name Talkatu -->
- <!-- interface-description GTK widgets for chat applications -->
- <!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
+ <!-- interface-name Pidgin --> + <!-- interface-description Internet Messenger --> + <!-- interface-copyright Pidgin Developers <devel@pidgin.im> --> + <object class="TalkatuBuffer" id="buffer"/> <template class="TalkatuEditor" parent="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="orientation">vertical</property>
- <object class="TalkatuToolbar" id="toolbar">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <object class="TalkatuToolbar" id="toolbar"/> - <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="vexpand">1</property> <property name="spacing">4</property>
<object class="GtkScrolledWindow">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="hexpand">1</property> + <property name="focusable">1</property> <property name="hscrollbar_policy">never</property>
- <property name="shadow_type">in</property>
<object class="TalkatuInput" id="input">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="can_focus">1</property> <property name="wrap_mode">word</property>
<property name="buffer">buffer</property>
<signal name="notify::buffer" handler="talkatu_editor_view_buffer_changed_handler" object="TalkatuEditor" swapped="no"/>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
<object class="GtkButton" id="send_button">
+ <property name="visible">0</property> <property name="label" translatable="yes">Send</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="no_show_all">True</property>
+ <property name="focusable">1</property> + <property name="receives_default">1</property> <signal name="clicked" handler="talkatu_editor_send_button_clicked_cb" object="TalkatuEditor" swapped="no"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/data/history.ui Sun Aug 28 22:44:59 2022 -0500
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?> +Talkatu - GTK widgets for chat applications +Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com> +This library 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 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 General Public License for more details. +You should have received a copy of the GNU General Public License +along with this library; if not, see <https://www.gnu.org/licenses/>. + <requires lib="gtk" version="4.0"/> + <!-- interface-license-type gplv2 --> + <!-- interface-name Talkatu --> + <!-- interface-description GTK widgets for chat applications --> + <!-- interface-copyright Gary Kramlich <grim@reaperworld.com> --> + <template class="TalkatuHistory" parent="GtkWidget"> + <property name="height-request">120</property> + <object class="GtkListBox" id="list_box"/> --- a/talkatu/data/historyrow.ui Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/data/historyrow.ui Sun Aug 28 22:44:59 2022 -0500
@@ -19,112 +19,67 @@
- <requires lib="gtk+" version="3.18"/>
+ <requires lib="gtk" version="4.0"/> <!-- interface-license-type gplv2 -->
<!-- interface-name Talkatu -->
<!-- interface-description GTK widgets for chat applications -->
<!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
<template class="TalkatuHistoryRow" parent="GtkListBoxRow">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <property name="can-focus">0</property> + <property name="child"> - <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <property name="can-focus">0</property> - <object class="GtkEventBox" id="avatar_event">
- <property name="can-focus">False</property>
- <object class="GtkImage" id="avatar_image">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="icon-name">image-missing</property>
+ <object class="GtkImage" id="avatar_image"> + <property name="can-focus">0</property> + <property name="icon-name">image-missing</property> + <property name="visible">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <property name="hexpand">1</property> + <property name="can-focus">0</property> <property name="orientation">vertical</property>
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <property name="can-focus">0</property> <property name="spacing">8</property>
<object class="GtkLabel" id="author">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <property name="can-focus">0</property> <property name="label" translatable="yes">Author</property>
- <property name="use-markup">True</property>
+ <property name="use-markup">1</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
<object class="GtkLabel" id="timestamp">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <property name="can-focus">0</property> <property name="label" translatable="yes">12:34PM</property>
- <property name="use-markup">True</property>
+ <property name="use-markup">1</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
<object class="GtkLabel" id="edited">
- <property name="can-focus">False</property>
+ <property name="visible">0</property> + <property name="can-focus">0</property> <property name="label" translatable="yes">(edited)</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
<object class="GtkLabel" id="content">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="wrap">True</property>
+ <property name="can-focus">0</property> + <property name="wrap">1</property> <property name="wrap-mode">word-char</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/data/input.ui Sun Aug 28 22:44:59 2022 -0500
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?> +Talkatu - GTK widgets for chat applications +Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com> +This library 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 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 General Public License for more details. +You should have received a copy of the GNU General Public License +along with this library; if not, see <https://www.gnu.org/licenses/>. + <requires lib="gtk" version="4.0"/> + <!-- interface-license-type gplv2 --> + <!-- interface-name Pidgin --> + <!-- interface-description Internet Messenger --> + <!-- interface-copyright Pidgin Developers <devel@pidgin.im> --> + <attribute name="label" translatable="yes">_Send Message</attribute> + <attribute name="action">message.send</attribute> + <template class="TalkatuInput" parent="TalkatuView"> + <property name="extra-menu">model</property> + <signal name="notify::buffer" handler="talkatu_input_buffer_set_cb"/> + <object class="GtkEventControllerKey"> + <signal name="key-pressed" handler="talkatu_input_key_pressed_cb" object="TalkatuInput" swapped="no"/> --- a/talkatu/data/linkdialog.ui Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/data/linkdialog.ui Sun Aug 28 22:44:59 2022 -0500
@@ -19,180 +19,74 @@
- <requires lib="gtk+" version="3.10"/>
+ <requires lib="gtk" version="4.0"/> <!-- interface-license-type gplv2 -->
<!-- interface-name Talkatu -->
<!-- interface-description GTK widgets for chat applications -->
<!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
<template class="TalkatuLinkDialog" parent="GtkDialog">
- <property name="can_focus">False</property>
<property name="title" translatable="yes">Insert Link</property>
- <property name="resizable">False</property>
- <property name="type_hint">dialog</property>
- <child internal-child="vbox">
+ <property name="resizable">0</property> + <child internal-child="content_area"> - <property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox">
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
- <object class="GtkButton" id="cancel">
- <property name="label" translatable="yes">Cancel</property>
- <property name="name">cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkButton" id="insert">
- <property name="label" translatable="yes">Insert</property>
- <property name="name">insert</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">True</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes"><span font-size="large" font-weight="bold">Insert Link</span></property>
- <property name="use_markup">True</property>
+ <property name="label" translatable="yes"><span font-size="large" font-weight="bold">Insert Link</span></property> + <property name="use_markup">1</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
<object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Please enter the URL and optional display text you would like to insert.</property>
- <property name="wrap">True</property>
+ <property name="wrap">1</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="spacing">2</property>
<object class="GtkLabel" id="url_label">
<property name="name">url_label</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">URL:</property>
<property name="xalign">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
<object class="GtkEntry" id="url">
+ <property name="hexpand">1</property> <property name="name">url</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="focusable">1</property> <property name="input_purpose">url</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="spacing">2</property>
<object class="GtkLabel" id="display_label">
<property name="name">display_label</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Display Text:</property>
<property name="xalign">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
<object class="GtkEntry" id="display">
+ <property name="hexpand">1</property> <property name="name">display</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="focusable">1</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
@@ -200,6 +94,22 @@
<action-widget response="-6">cancel</action-widget>
<action-widget response="-3">insert</action-widget>
+ <object class="GtkButton" id="cancel"> + <property name="label" translatable="yes">Cancel</property> + <property name="name">cancel</property> + <property name="focusable">1</property> + <property name="receives_default">1</property> + <object class="GtkButton" id="insert"> + <property name="label" translatable="yes">Insert</property> + <property name="name">insert</property> + <property name="focusable">1</property> + <property name="receives_default">1</property> <object class="GtkSizeGroup">
--- a/talkatu/data/messageactions.ui Sat Aug 13 22:03:08 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.1
-Talkatu - GTK widgets for chat applications
-Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
-This library 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 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 General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this library; if not, see <https://www.gnu.org/licenses/>.
--->
- <requires lib="gtk+" version="3.20"/>
- <!-- interface-license-type gplv2 -->
- <!-- interface-name Talkatu -->
- <!-- interface-description GTK widgets for chat applications -->
- <!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
- <template class="TalkatuMessageActions" parent="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <object class="GtkEventBox" id="reactions">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">face-smile</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkEventBox" id="actions">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">open-menu-symbolic</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
--- a/talkatu/data/talkatu.gresource.xml Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/data/talkatu.gresource.xml Sun Aug 28 22:44:59 2022 -0500
@@ -4,9 +4,12 @@
<file compressed="true">attachmentdialog.ui</file>
<file compressed="true">attachmentpreview.ui</file>
<file compressed="true">editor.ui</file>
+ <file compressed="true">history.ui</file> <file compressed="true">historyrow.ui</file>
+ <file compressed="true">input.ui</file> <file compressed="true">linkdialog.ui</file>
- <file compressed="true">messageactions.ui</file>
<file compressed="true">toolbar.ui</file>
+ <file compressed="true">typinglabel.ui</file> + <file compressed="true">view.ui</file> --- a/talkatu/data/toolbar.ui Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/data/toolbar.ui Sun Aug 28 22:44:59 2022 -0500
@@ -19,189 +19,124 @@
- <requires lib="gtk+" version="3.20"/>
+ <requires lib="gtk" version="4.0"/> <!-- interface-license-type gplv2 -->
<!-- interface-name Talkatu -->
<!-- interface-description GTK widgets for chat applications -->
<!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
- <template class="TalkatuToolbar" parent="GtkToolbar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <template class="TalkatuToolbar" parent="GtkBox"> + <class name="toolbar"/> + <property name="can_focus">0</property> - <object class="GtkToggleToolButton" id="format_bold">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkToggleButton" id="format_bold"> + <property name="can_focus">0</property> <property name="action_name">talkatu.format-bold</property>
<property name="label" translatable="yes">Bold</property>
<property name="icon_name">format-text-bold</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToggleToolButton" id="format_italic">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkToggleButton" id="format_italic"> + <property name="can_focus">0</property> <property name="action_name">talkatu.format-italic</property>
<property name="label" translatable="yes">Italic</property>
<property name="icon_name">format-text-italic</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToggleToolButton" id="format_underline">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkToggleButton" id="format_underline"> + <property name="can_focus">0</property> <property name="action_name">talkatu.format-underline</property>
<property name="label" translatable="yes">Underline</property>
<property name="icon_name">format-text-underline</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToggleToolButton" id="format_strikethrough">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkToggleButton" id="format_strikethrough"> + <property name="can_focus">0</property> <property name="action_name">talkatu.format-strikethrough</property>
<property name="label" translatable="yes">Strikethrough</property>
<property name="icon_name">format-text-strikethrough</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkSeparatorToolItem">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkSeparator"> + <property name="orientation">vertical</property> + <property name="can_focus">0</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToolButton" id="format_larger">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkButton" id="format_larger"> + <property name="can_focus">0</property> <property name="action_name">talkatu.format-grow</property>
<property name="label" translatable="yes">Increase Font Size</property>
<property name="icon_name">zoom-in</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToolButton" id="format_smaller">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkButton" id="format_smaller"> + <property name="can_focus">0</property> <property name="action_name">talkatu.format-shrink</property>
<property name="label" translatable="yes">Decrease Font Size</property>
<property name="icon_name">zoom-out</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkSeparatorToolItem">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkSeparator"> + <property name="orientation">vertical</property> + <property name="can_focus">0</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToolButton" id="format_reset">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkButton" id="format_reset"> + <property name="can_focus">0</property> <property name="action_name">talkatu.format-reset</property>
<property name="label" translatable="yes">Clear Formatting</property>
<property name="icon_name">edit-clear</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkSeparatorToolItem">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkSeparator"> + <property name="orientation">vertical</property> + <property name="can_focus">0</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToggleToolButton" id="insert_link">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkToggleButton" id="insert_link"> + <property name="can_focus">0</property> <property name="action_name">talkatu.insert-link</property>
<property name="label" translatable="yes">Insert Link</property>
- <property name="use_underline">True</property>
+ <property name="use_underline">1</property> <property name="icon_name">insert-link</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToolButton" id="insert_file">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkButton" id="insert_file"> + <property name="can_focus">0</property> <property name="action_name">talkatu.attach-file</property>
<property name="label" translatable="yes">Attach File</property>
<property name="icon_name">insert-object</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToolButton" id="insert_code">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkButton" id="insert_code"> + <property name="can_focus">0</property> <property name="action_name">talkatu.insert-code</property>
<property name="label" translatable="yes">Insert Code</property>
- <property name="use_underline">True</property>
+ <property name="use_underline">1</property> <property name="icon_name">insert-text</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- <object class="GtkToolButton" id="insert_emoji">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="GtkButton" id="insert_emoji"> + <property name="can_focus">0</property> <property name="action_name">talkatu.insert-emoji</property>
<property name="label" translatable="yes">Insert Emoji</property>
- <property name="use_underline">True</property>
+ <property name="use_underline">1</property> <property name="icon_name">face-smile-big</property>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/data/typinglabel.ui Sun Aug 28 22:44:59 2022 -0500
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?> +Talkatu - GTK widgets for chat applications +Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com> +This library 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 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 General Public License for more details. +You should have received a copy of the GNU General Public License +along with this library; if not, see <https://www.gnu.org/licenses/>. + <requires lib="gtk" version="4.0"/> + <!-- interface-license-type gplv2 --> + <!-- interface-name Talkatu --> + <!-- interface-description GTK widgets for chat applications --> + <!-- interface-copyright Gary Kramlich <grim@reaperworld.com> --> + <template class="TalkatuTypingLabel" parent="GtkWidget"> + <object class="GtkLabel" id="label"> + <property name="xalign">0</property> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/data/view.ui Sun Aug 28 22:44:59 2022 -0500
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?> +Talkatu - GTK widgets for chat applications +Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com> +This library 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 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 General Public License for more details. +You should have received a copy of the GNU General Public License +along with this library; if not, see <https://www.gnu.org/licenses/>. + <requires lib="gtk" version="4.0"/> + <!-- interface-license-type gplv2 --> + <!-- interface-name Pidgin --> + <!-- interface-description Internet Messenger --> + <!-- interface-copyright Pidgin Developers <devel@pidgin.im> --> + <attribute name="label" translatable="yes">_Open Link</attribute> + <attribute name="action">link.open</attribute> + <attribute name="label" translatable="yes">_Copy Link</attribute> + <attribute name="action">link.copy</attribute> + <template class="TalkatuView" parent="GtkTextView"> + <property name="has-tooltip">1</property> + <property name="wrap-mode">3</property> + <signal name="notify::buffer" handler="talkatu_view_buffer_set_cb"/> + <object class="GtkPopoverMenu" id="menu"> + <property name="has-arrow">0</property> + <property name="menu-model">model</property> + <object class="GtkGestureClick"> + <property name="button">0</property> + <signal name="pressed" handler="talkatu_view_pressed_cb"/> + <object class="GtkEventControllerMotion"> + <signal name="motion" handler="talkatu_view_motion_cb"/> --- a/talkatu/meson.build Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/meson.build Sun Aug 28 22:44:59 2022 -0500
@@ -8,6 +8,7 @@
'talkatuattachmentdialog.h',
'talkatuattachmentpreview.h',
+ 'talkatuautoscroller.h', @@ -21,15 +22,11 @@
'talkatumarkdownbuffer.h',
- 'talkatumenutoolbutton.h',
- 'talkatumessageactions.h',
- 'talkatuscrolledwindow.h',
'talkatusimpleattachment.h',
@@ -40,6 +37,7 @@
'talkatuattachmentdialog.c',
'talkatuattachmentpreview.c',
+ 'talkatuautoscroller.c', @@ -53,15 +51,11 @@
'talkatumarkdownbuffer.c',
- 'talkatumenutoolbutton.c',
- 'talkatumessageactions.c',
- 'talkatuscrolledwindow.c',
'talkatusimpleattachment.c',
@@ -177,7 +171,7 @@
###############################################################################
###############################################################################
-talkatu = shared_library('talkatu',
+talkatu = library('talkatu', TALKATU_PUBLIC_BUILT_SOURCES,
@@ -189,7 +183,7 @@
c_args : ['-DTALKATU_COMPILATION', '-DG_LOG_USE_STRUCTURED', '-DG_LOG_DOMAIN="Talkatu"'],
include_directories : toplevel_inc,
- dependencies : [CMARK, GLIB, GOBJECT, GUMBO, GTK3, GSPELL],
+ dependencies : [CMARK, GLIB, GOBJECT, GUMBO, GTK4], version : TALKATU_LIBRARY_VERSION,
@@ -203,7 +197,7 @@
- requires : ['glib-2.0', 'gobject-2.0', 'gtk+-3.0'],
+ requires : ['glib-2.0', 'gobject-2.0', 'gtk4'], ###############################################################################
@@ -217,7 +211,7 @@
export_packages : ['talkatu'],
extra_args : ['--quiet', '--warn-all', '-DTALKATU_COMPILATION'],
header : 'talkatu/talkatu.h',
- includes : ['GModule-2.0', 'GObject-2.0', 'Gtk-3.0'],
+ includes : ['GModule-2.0', 'GObject-2.0', 'Gtk-4.0'], nsversion : '@0@.0'.format(TALKATU_MAJOR_VERSION),
@@ -233,7 +227,7 @@
include_directories : [toplevel_inc, talkatu_inc],
sources : TALKATU_PUBLIC_BUILT_HEADERS + TALKATU_GENERATED_TARGETS,
- dependencies : [GLIB, GOBJECT, GTK3]
+ dependencies : [GLIB, GOBJECT, GTK4] if meson.version().version_compare('>=0.54.0')
--- a/talkatu/talkatuactiongroup.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuactiongroup.c Sun Aug 28 22:44:59 2022 -0500
@@ -347,7 +347,7 @@
/* we call this separately for GTK_RESPONSE_CANCEL because
* GTK_RESPONSE_DELETE_EVENT already destroys the dialog.
- gtk_widget_destroy(GTK_WIDGET(dialog));
+ gtk_window_destroy(GTK_WINDOW(dialog)); } else if(response == GTK_RESPONSE_ACCEPT) {
TalkatuActionGroup *ag = TALKATU_ACTION_GROUP(data);
TalkatuActionGroupPrivate *priv = NULL;
@@ -369,29 +369,28 @@
talkatu_input_send_message(priv->input);
- gtk_widget_destroy(GTK_WIDGET(dialog));
+ gtk_window_destroy(GTK_WINDOW(dialog)); + g_object_unref(dialog); talkatu_action_attach_file_response_cb(GtkDialog *dialog, gint response,
- if(response == GTK_RESPONSE_CANCEL) {
- /* we call this separately for GTK_RESPONSE_CANCEL because
- * GTK_RESPONSE_DELETE_EVENT already destroys the dialog.
- gtk_widget_destroy(GTK_WIDGET(dialog));
- } else if(response == GTK_RESPONSE_ACCEPT) {
+ if(response == GTK_RESPONSE_ACCEPT) { TalkatuActionGroup *ag = TALKATU_ACTION_GROUP(data);
TalkatuActionGroupPrivate *priv = NULL;
TalkatuAttachment *attachment = NULL;
GtkWidget *attach_dialog = NULL;
gchar *filename = NULL, *content_type = NULL, *comment = NULL;
priv = talkatu_action_group_get_instance_private(ag);
- filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dialog)); + filename = g_file_get_path(file); content_type = g_content_type_guess(filename, NULL, 0, NULL);
attachment = talkatu_simple_attachment_new(G_GUINT64_CONSTANT(0),
@@ -400,8 +399,7 @@
talkatu_attachment_set_local_uri(attachment, filename);
- gtk_widget_destroy(GTK_WIDGET(dialog));
comment = talkatu_markup_get_html(priv->buffer, NULL);
attach_dialog = talkatu_attachment_dialog_new(attachment, comment);
@@ -410,8 +408,11 @@
g_signal_connect(G_OBJECT(attach_dialog), "response",
G_CALLBACK(talkatu_action_attach_file_attach_response_cb),
- gtk_widget_show_all(attach_dialog);
+ gtk_widget_show(attach_dialog); + gtk_native_dialog_destroy(GTK_NATIVE_DIALOG(dialog)); + g_object_unref(dialog); @@ -420,34 +421,32 @@
TalkatuActionGroup *ag = TALKATU_ACTION_GROUP(data);
TalkatuActionGroupPrivate *priv = NULL;
- GtkWidget *dialog = NULL;
+ GtkFileChooserNative *dialog = NULL; priv = talkatu_action_group_get_instance_private(ag);
g_return_if_fail(TALKATU_IS_INPUT(priv->input));
- dialog = gtk_file_chooser_dialog_new(_("Attach file..."),
+ dialog = gtk_file_chooser_native_new(_("Attach file..."), GTK_FILE_CHOOSER_ACTION_OPEN,
- _("Cancel"), GTK_RESPONSE_CANCEL,
- _("Open"), GTK_RESPONSE_ACCEPT,
g_signal_connect(G_OBJECT(dialog), "response",
G_CALLBACK(talkatu_action_attach_file_response_cb),
- gtk_widget_show_all(dialog);
+ gtk_native_dialog_show(GTK_NATIVE_DIALOG(dialog)); -talkatu_action_insert_link(GSimpleAction *action, GVariant *parameter,
+talkatu_action_insert_link_response_cb(GtkDialog *dialog, gint response, TalkatuActionGroup *ag = TALKATU_ACTION_GROUP(data);
TalkatuActionGroupPrivate *priv = NULL;
- GtkWidget *link_dialog = talkatu_link_dialog_new();
priv = talkatu_action_group_get_instance_private(ag);
- if(gtk_dialog_run(GTK_DIALOG(link_dialog)) == GTK_RESPONSE_ACCEPT) {
+ if(response == GTK_RESPONSE_ACCEPT) { GtkTextTagTable *table = gtk_text_buffer_get_tag_table(priv->buffer);
GtkTextTag *anchor, *anchor_data;
GtkTextMark *insert_mark = NULL;
@@ -460,8 +459,8 @@
/* grab our inputs from the dialog */
- url = talkatu_link_dialog_get_url(TALKATU_LINK_DIALOG(link_dialog));
- label = talkatu_link_dialog_get_display_text(TALKATU_LINK_DIALOG(link_dialog));
+ url = talkatu_link_dialog_get_url(TALKATU_LINK_DIALOG(dialog)); + label = talkatu_link_dialog_get_display_text(TALKATU_LINK_DIALOG(dialog)); /* find the anchor tag from the table */
anchor = gtk_text_tag_table_lookup(table, TALKATU_TAG_ANCHOR);
@@ -472,7 +471,8 @@
anchor_data = gtk_text_tag_new(NULL);
- g_object_set_data_full(G_OBJECT(anchor_data), "talkatu-anchor-url", url, g_free);
+ g_object_set_data_full(G_OBJECT(anchor_data), "talkatu-anchor-url", gtk_text_tag_table_add(table, anchor_data);
insert_mark = gtk_text_buffer_get_insert(priv->buffer);
@@ -491,7 +491,21 @@
- gtk_widget_destroy(link_dialog);
+ gtk_window_destroy(GTK_WINDOW(dialog)); + g_object_unref(dialog); +talkatu_action_insert_link(GSimpleAction *action, GVariant *parameter, + GtkWidget *link_dialog = talkatu_link_dialog_new(); + g_signal_connect(G_OBJECT(link_dialog), "response", + G_CALLBACK(talkatu_action_insert_link_response_cb), + gtk_window_set_modal(GTK_WINDOW(link_dialog), TRUE); + gtk_widget_show(link_dialog); /******************************************************************************
--- a/talkatu/talkatuattachmentdialog.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuattachmentdialog.c Sun Aug 28 22:44:59 2022 -0500
@@ -57,8 +57,7 @@
- gtk_image_set_from_gicon(GTK_IMAGE(dialog->preview), preview,
+ gtk_image_set_from_gicon(GTK_IMAGE(dialog->preview), preview); g_object_unref(G_OBJECT(preview));
@@ -77,7 +76,7 @@
if(GTK_IS_ENTRY(dialog->comment)) {
- gtk_entry_set_text(GTK_ENTRY(dialog->comment), comment);
+ gtk_editable_set_text(GTK_EDITABLE(dialog->comment), comment); g_object_notify_by_pspec(G_OBJECT(dialog), properties[PROP_COMMENT]);
@@ -228,7 +227,7 @@
g_return_val_if_fail(TALKATU_IS_ATTACHMENT_DIALOG(dialog), "");
if(GTK_IS_ENTRY(dialog->comment)) {
- return gtk_entry_get_text(GTK_ENTRY(dialog->comment));
+ return gtk_editable_get_text(GTK_EDITABLE(dialog->comment)); --- a/talkatu/talkatuattachmentpreview.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuattachmentpreview.c Sun Aug 28 22:44:59 2022 -0500
@@ -27,7 +27,7 @@
struct _TalkatuAttachmentPreview {
TalkatuAttachment *attachment;
@@ -47,9 +47,11 @@
/******************************************************************************
*****************************************************************************/
-talkatu_attachment_preview_download_cb(GtkButton *button, gpointer data) {
+talkatu_attachment_preview_download_cb(G_GNUC_UNUSED GtkInfoBar *self, + G_GNUC_UNUSED gint response_id, + G_GNUC_UNUSED gpointer user_data) /******************************************************************************
@@ -66,8 +68,7 @@
- gtk_image_set_from_gicon(GTK_IMAGE(preview->preview), icon,
+ gtk_image_set_from_gicon(GTK_IMAGE(preview->preview), icon); g_object_unref(G_OBJECT(icon));
@@ -88,7 +89,7 @@
/******************************************************************************
*****************************************************************************/
-G_DEFINE_TYPE(TalkatuAttachmentPreview, talkatu_attachment_preview, GTK_TYPE_INFO_BAR)
+G_DEFINE_TYPE(TalkatuAttachmentPreview, talkatu_attachment_preview, GTK_TYPE_WIDGET) talkatu_attachment_preview_get_property(GObject *obj, guint prop_id,
--- a/talkatu/talkatuattachmentpreview.h Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuattachmentpreview.h Sun Aug 28 22:44:59 2022 -0500
@@ -33,7 +33,7 @@
#define TALKATU_TYPE_ATTACHMENT_PREVIEW (talkatu_attachment_preview_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuAttachmentPreview, talkatu_attachment_preview, TALKATU, ATTACHMENT_PREVIEW, GtkInfoBar)
+G_DECLARE_FINAL_TYPE(TalkatuAttachmentPreview, talkatu_attachment_preview, TALKATU, ATTACHMENT_PREVIEW, GtkWidget) GtkWidget *talkatu_attachment_preview_new(TalkatuAttachment *attachment);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/talkatuautoscroller.c Sun Aug 28 22:44:59 2022 -0500
@@ -0,0 +1,154 @@
+ * Talkatu - GTK widgets for chat applications + * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com> + * This library 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 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 General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this library; if not, see <https://www.gnu.org/licenses/>. +#include <talkatu/talkatuautoscroller.h> + * This is a simple subclass of [class@Gtk.Adjustment] that has helpers for + * keyboard navigation as well as the ability to automatically scroll to the + * max when new items are added if the widget was already scrolled all the +struct _TalkatuAutoScroller { +G_DEFINE_TYPE(TalkatuAutoScroller, talkatu_auto_scroller, GTK_TYPE_ADJUSTMENT) +/****************************************************************************** + *****************************************************************************/ +talkatu_auto_scroller_scroll(gpointer data) { + GtkAdjustment *adjustment = data; + gdouble upper, pagesize; + upper = gtk_adjustment_get_upper(adjustment); + pagesize = gtk_adjustment_get_page_size(adjustment); + gtk_adjustment_set_value(adjustment, upper - pagesize); + return G_SOURCE_REMOVE; +talkatu_auto_scroller_changed(GtkAdjustment *adjustment) { + TalkatuAutoScroller *auto_scroller = TALKATU_AUTO_SCROLLER(adjustment); + if(auto_scroller->auto_scroll) { + /* If we set the value here, we interrupt the updates to the other + * values of the adjustment which breaks the adjustment. + * The specific behavior we've seen is that the upper property doesn't + * get updated when we call set value here. Which means you can't even + * scroll down anymore in a scrolled window because you're already at + * the upper bound. However, if you scroll up, even if there's no where + * to scroll, it will update the adjustment's properties and you can + * By using a timeout to set the value during the next main loop + * iteration we avoid this problem. + g_timeout_add(0, talkatu_auto_scroller_scroll, adjustment); +talkatu_auto_scroller_value_changed(GtkAdjustment *adjustment) { + TalkatuAutoScroller *auto_scroller = TALKATU_AUTO_SCROLLER(adjustment); + gdouble current, upper, pagesize; + current = gtk_adjustment_get_value(adjustment); + upper = gtk_adjustment_get_upper(adjustment); + pagesize = gtk_adjustment_get_page_size(adjustment); + auto_scroller->auto_scroll = (current + pagesize >= upper); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +talkatu_auto_scroller_init(TalkatuAutoScroller *auto_scroller) { + auto_scroller->auto_scroll = TRUE; +talkatu_auto_scroller_class_init(TalkatuAutoScrollerClass *klass) { + GtkAdjustmentClass *adjustment_class = GTK_ADJUSTMENT_CLASS(klass); + adjustment_class->changed = talkatu_auto_scroller_changed; + adjustment_class->value_changed = talkatu_auto_scroller_value_changed; +/****************************************************************************** + *****************************************************************************/ + * talkatu_auto_scroller_new: + * Creates a new #TalkatuAutoScroller. + * Returns: (transfer full): The new #TalkatuAutoScroller instance. +talkatu_auto_scroller_new(void) { + return g_object_new(TALKATU_TYPE_AUTO_SCROLLER, NULL); + * talkatu_auto_scroller_decrement: + * @auto_scroller: The #TalkatuAutoScroller instance. + * Decrements the value of @auto_scroller by a page increment. +talkatu_auto_scroller_decrement(TalkatuAutoScroller *auto_scroller) { + g_return_if_fail(TALKATU_IS_AUTO_SCROLLER(auto_scroller)); + value = gtk_adjustment_get_value(GTK_ADJUSTMENT(auto_scroller)); + value -= gtk_adjustment_get_page_increment(GTK_ADJUSTMENT(auto_scroller)); + gtk_adjustment_set_value(GTK_ADJUSTMENT(auto_scroller), value); + * talkatu_auto_scroller_increment: + * @auto_scroller: The #TalkatuAutoScroller instance. + * Increments the value of @auto_scroller by a page increment. +talkatu_auto_scroller_increment(TalkatuAutoScroller *auto_scroller) { + g_return_if_fail(TALKATU_IS_AUTO_SCROLLER(auto_scroller)); + value = gtk_adjustment_get_value(GTK_ADJUSTMENT(auto_scroller)); + value += gtk_adjustment_get_page_increment(GTK_ADJUSTMENT(auto_scroller)); + gtk_adjustment_set_value(GTK_ADJUSTMENT(auto_scroller), value); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/talkatuautoscroller.h Sun Aug 28 22:44:59 2022 -0500
@@ -0,0 +1,45 @@
+ * Talkatu - GTK widgets for chat applications + * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com> + * This library 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 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 General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this library; if not, see <https://www.gnu.org/licenses/>. +#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION) +#error "only <talkatu.h> may be included directly" +#ifndef TALKATU_AUTO_SCROLLER_H +#define TALKATU_AUTO_SCROLLER_H +#include <glib-object.h> +#define TALKATU_TYPE_AUTO_SCROLLER (talkatu_auto_scroller_get_type()) +G_DECLARE_FINAL_TYPE(TalkatuAutoScroller, talkatu_auto_scroller, TALKATU, + AUTO_SCROLLER, GtkAdjustment) +GtkAdjustment *talkatu_auto_scroller_new(void); +void talkatu_auto_scroller_decrement(TalkatuAutoScroller *auto_scroller); +void talkatu_auto_scroller_increment(TalkatuAutoScroller *auto_scroller); +#endif /* TALKATU_AUTO_SCROLLER_H */ --- a/talkatu/talkatubuffer.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatubuffer.c Sun Aug 28 22:44:59 2022 -0500
@@ -376,8 +376,8 @@
talkatu_buffer_init(TalkatuBuffer *buffer) {
- gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(buffer), NULL);
- gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(buffer), NULL);
+ // gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(buffer), NULL); + // gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(buffer), NULL); --- a/talkatu/talkatuhistory.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuhistory.c Sun Aug 28 22:44:59 2022 -0500
@@ -1,6 +1,6 @@
* Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +20,6 @@
#include <talkatu/talkatuhistory.h>
-#include <talkatu/talkatuattachmentpreview.h>
#include <talkatu/talkatuhistoryrow.h>
#include <talkatu/talkatumessage.h>
@@ -30,20 +29,46 @@
* A #TalkatuView subclass that is used to display a conversation.
-G_DEFINE_TYPE(TalkatuHistory, talkatu_history, GTK_TYPE_LIST_BOX)
+G_DEFINE_TYPE(TalkatuHistory, talkatu_history, GTK_TYPE_WIDGET) /******************************************************************************
+ * GObject Implementation *****************************************************************************/
+talkatu_history_dispose(GObject *obj) { + TalkatuHistory *history = TALKATU_HISTORY(obj); + g_clear_pointer(&history->list_box, gtk_widget_unparent); + G_OBJECT_CLASS(talkatu_history_parent_class)->dispose(obj); talkatu_history_init(TalkatuHistory *history) {
+ gtk_widget_init_template(GTK_WIDGET(history)); talkatu_history_class_init(TalkatuHistoryClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + obj_class->dispose = talkatu_history_dispose; + gtk_widget_class_set_template_from_resource( + "/org/imfreedom/keep/talkatu/talkatu/ui/history.ui" + gtk_widget_class_set_layout_manager_type(widget_class, GTK_TYPE_BIN_LAYOUT); + gtk_widget_class_bind_template_child(widget_class, TalkatuHistory, /******************************************************************************
@@ -58,10 +83,7 @@
* Returns: (transfer full): The new #TalkatuHistory instance.
GtkWidget *talkatu_history_new(void) {
- return GTK_WIDGET(g_object_new(
+ return g_object_new(TALKATU_TYPE_HISTORY, NULL); @@ -82,5 +104,5 @@
g_return_if_fail(TALKATU_IS_MESSAGE(message));
row = talkatu_history_row_new(message);
- gtk_container_add(GTK_CONTAINER(history), row);
+ gtk_list_box_append(GTK_LIST_BOX(history->list_box), row); --- a/talkatu/talkatuhistory.h Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuhistory.h Sun Aug 28 22:44:59 2022 -0500
@@ -1,6 +1,6 @@
* Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@
#define TALKATU_TYPE_HISTORY (talkatu_history_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuHistory, talkatu_history, TALKATU, HISTORY, GtkListBox)
+G_DECLARE_FINAL_TYPE(TalkatuHistory, talkatu_history, TALKATU, HISTORY, GtkWidget) GtkWidget *talkatu_history_new(void);
--- a/talkatu/talkatuhistoryrow.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuhistoryrow.c Sun Aug 28 22:44:59 2022 -0500
@@ -34,7 +34,6 @@
- GtkWidget *avatar_event;
@@ -230,8 +229,6 @@
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
gtk_widget_class_bind_template_child(widget_class, TalkatuHistoryRow,
- gtk_widget_class_bind_template_child(widget_class, TalkatuHistoryRow,
gtk_widget_class_bind_template_child(widget_class, TalkatuHistoryRow,
--- a/talkatu/talkatuhtmlbuffer.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuhtmlbuffer.c Sun Aug 28 22:44:59 2022 -0500
@@ -65,21 +65,21 @@
*****************************************************************************/
talkatu_html_buffer_init(TalkatuHtmlBuffer *buffer) {
- gtk_text_buffer_register_deserialize_format(
- GTK_TEXT_BUFFER(buffer),
- talkatu_markup_deserialize_html,
+ // gtk_text_buffer_register_deserialize_format( + // GTK_TEXT_BUFFER(buffer), + // talkatu_markup_deserialize_html, - gtk_text_buffer_register_serialize_format(
- GTK_TEXT_BUFFER(buffer),
- talkatu_markup_serialize_html,
+ // gtk_text_buffer_register_serialize_format( + // GTK_TEXT_BUFFER(buffer), + // talkatu_markup_serialize_html, --- a/talkatu/talkatuinput.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuinput.c Sun Aug 28 22:44:59 2022 -0500
@@ -1,6 +1,6 @@
* Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +20,6 @@
#include <glib/gi18n-lib.h>
-#include <gspell/gspell.h>
#include "talkatu/talkatuinput.h"
#include "talkatu/talkatuactiongroup.h"
@@ -47,8 +45,6 @@
- * @should_send_message: The class handler for the
- * #TalkatuInput::should_send_message signal.
* @send_message: The class handler for the #TalkatuInput::send_message signal.
* The backing class to #TalkatuInput instances.
@@ -66,20 +62,11 @@
- GspellTextView *gspell_view;
TalkatuInputSendBinding send_binding;
- /* this mark is used to keep track of our context for the context menu. It
- * is updated via cursor-moved and button-press callbacks.
- GtkTextMark *context_mark;
/* TalkatuMessage properties: content type and contents are derived from
@@ -365,64 +352,51 @@
*****************************************************************************/
-talkatu_input_send_message_cb(GtkMenuItem *item, gpointer data) {
- talkatu_input_send_message(TALKATU_INPUT(data));
+talkatu_input_send_message_cb(GtkWidget *widget, + G_GNUC_UNUSED const gchar *action_name, + G_GNUC_UNUSED GVariant *parameter) + talkatu_input_send_message(TALKATU_INPUT(widget)); - gtk_widget_grab_focus(GTK_WIDGET(data));
+ gtk_widget_grab_focus(widget); +talkatu_input_key_pressed_cb(G_GNUC_UNUSED GtkEventControllerKey *self, + guint keyval, G_GNUC_UNUSED guint keycode, + GdkModifierType state, gpointer data) + TalkatuInput *input = data; + TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input); + TalkatuInputSendBinding binding = 0; + gboolean handled = FALSE;
-talkatu_input_populate_popup_cb(GtkTextView *view, GtkWidget *popup) {
- TalkatuInputPrivate *priv = NULL;
- GtkTextBuffer *buffer = NULL;
- GtkWidget *item = NULL;
- /* if the popup isn't a menu, bail */
- if(!GTK_IS_MENU(popup)) {
+ if(keyval == GDK_KEY_Return) { + if(state == GDK_SHIFT_MASK) { + binding = TALKATU_INPUT_SEND_BINDING_SHIFT_RETURN; + } else if(state == GDK_CONTROL_MASK) { + binding = TALKATU_INPUT_SEND_BINDING_CONTROL_RETURN; + binding = TALKATU_INPUT_SEND_BINDING_RETURN; + } else if(keyval == GDK_KEY_KP_Enter) { + binding = TALKATU_INPUT_SEND_BINDING_KP_ENTER; - priv = talkatu_input_get_instance_private(TALKATU_INPUT(view));
- buffer = gtk_text_view_get_buffer(view);
- gtk_text_buffer_get_iter_at_mark(buffer, &iter, priv->context_mark);
+ if((priv->send_binding & binding) != 0) { + talkatu_input_send_message(input); - /* add the send message item */
- if(gtk_text_view_get_editable(view)) {
- item = gtk_menu_item_new_with_label(_("Send message"));
- g_signal_connect_after(
- G_CALLBACK(talkatu_input_send_message_cb),
- gtk_menu_shell_insert(GTK_MENU_SHELL(popup), item, pos++);
- item = gtk_separator_menu_item_new();
- gtk_menu_shell_insert(GTK_MENU_SHELL(popup), item , pos++);
talkatu_input_buffer_set_cb(GObject *view, GParamSpec *pspec, gpointer data) {
- TalkatuInputPrivate *priv = NULL;
TalkatuInput *input = TALKATU_INPUT(view);
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
- priv = talkatu_input_get_instance_private(input);
- gspell_text_view_basic_setup(priv->gspell_view);
- /* grab our context_mark */
- gtk_text_buffer_get_start_iter(buffer, &start);
- priv->context_mark = gtk_text_buffer_create_mark(buffer, NULL, &start, TRUE);
if(TALKATU_IS_BUFFER(buffer)) {
GSimpleActionGroup *ag = NULL;
@@ -448,7 +422,7 @@
/* we call this separately for GTK_RESPONSE_CANCEL because
* GTK_RESPONSE_DELETE_EVENT already destroys the dialog.
- gtk_widget_destroy(GTK_WIDGET(dialog));
+ gtk_window_destroy(GTK_WINDOW(dialog)); } else if(response == GTK_RESPONSE_ACCEPT) {
GtkTextBuffer *buffer = NULL;
TalkatuAttachment *attachment = NULL;
@@ -474,10 +448,13 @@
talkatu_input_send_message(input);
- gtk_widget_destroy(GTK_WIDGET(dialog));
+ gtk_window_destroy(GTK_WINDOW(dialog)); + g_object_unref(dialog); talkatu_input_image_received_cb(GtkClipboard *clipboard, GdkPixbuf *pixbuf,
@@ -565,56 +542,25 @@
g_object_unref(G_OBJECT(stream));
-/******************************************************************************
- * Default Signal Handlers
- *****************************************************************************/
-talkatu_input_popup_menu(GtkWidget *widget) {
- TalkatuInputPrivate *priv = talkatu_input_get_instance_private(TALKATU_INPUT(widget));
- GtkTextBuffer *buffer = NULL;
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
- gtk_text_buffer_get_iter_at_mark(
- gtk_text_buffer_get_insert(buffer)
- gtk_text_buffer_move_mark(buffer, priv->context_mark, &iter);
- return GTK_WIDGET_CLASS(talkatu_input_parent_class)->popup_menu(widget);
-talkatu_input_should_send_message(TalkatuInput *input, TalkatuInputSendBinding binding) {
- TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
- if((priv->send_binding & binding) != 0) {
- talkatu_input_send_message(input);
- } else if(gtk_text_view_get_editable(GTK_TEXT_VIEW(input))) {
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(input));
- gtk_text_buffer_insert_at_cursor(buffer, "\n", 1);
/******************************************************************************
* GtkTextViewClass overrides
*****************************************************************************/
talkatu_input_paste_clipboard(GtkTextView *view) {
- GtkClipboard *clipboard =
- gtk_widget_get_clipboard(GTK_WIDGET(view), GDK_SELECTION_CLIPBOARD);
+ GdkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(view)); if(gtk_clipboard_wait_is_image_available(clipboard)) {
gtk_clipboard_request_image(clipboard, talkatu_input_image_received_cb,
GTK_TEXT_VIEW_CLASS(talkatu_input_parent_class)->paste_clipboard(view);
/******************************************************************************
@@ -694,31 +640,10 @@
talkatu_input_init(TalkatuInput *input) {
TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+ gtk_widget_init_template(GTK_WIDGET(input)); priv->attachments = g_hash_table_new_full(g_int64_hash, g_int64_equal,
- /* we need to know when the buffer is changed in our parent so we can
- * update our actions and other stuff.
- G_CALLBACK(talkatu_input_buffer_set_cb),
- priv->gspell_view = gspell_text_view_get_from_gtk_text_view(GTK_TEXT_VIEW(input));
- /* we need to connect this signal *AFTER* everything to make sure our items
- * end up in the correct place.
- g_signal_connect_after(
- G_CALLBACK(talkatu_input_populate_popup_cb),
@@ -741,21 +666,17 @@
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS(klass);
- GtkBindingSet *binding_set = NULL;
obj_class->get_property = talkatu_input_get_property;
obj_class->set_property = talkatu_input_set_property;
obj_class->finalize = talkatu_input_finalize;
- widget_class->popup_menu = talkatu_input_popup_menu;
text_view_class->paste_clipboard = talkatu_input_paste_clipboard;
- klass->should_send_message = talkatu_input_should_send_message;
properties[PROP_SEND_BINDING] = g_param_spec_flags(
- "send-binding", "send-binding", "The keybindings that will trigger the send signal",
+ "send-binding", "send-binding", + "The keybindings that will trigger the send signal", TALKATU_TYPE_INPUT_SEND_BINDING,
TALKATU_INPUT_SEND_BINDING_RETURN | TALKATU_INPUT_SEND_BINDING_KP_ENTER,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT
@@ -772,28 +693,6 @@
g_object_class_override_property(obj_class, PROP_EDITED, "edited");
- * TalkatuInput::should-send-message:
- * @talkatuinput: The #TalkatuInput instance.
- * @arg1: The #TalkatuInputSendBinding that was entered.
- * @user_data: User supplied data.
- * Emitted when a potential keybinding to send the message is entered to
- * determine if the message should be sent.
- signals[SIG_SHOULD_SEND_MESSAGE] = g_signal_new(
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET(TalkatuInputClass, should_send_message),
- TALKATU_TYPE_INPUT_SEND_BINDING
* TalkatuInput::send-message:
* @talkatuinput: The #TalkatuInput instance.
* @user_data: User supplied data.
@@ -812,13 +711,20 @@
- /* setup key bindings */
- binding_set = gtk_binding_set_by_class(talkatu_input_parent_class);
+ gtk_widget_class_install_action(widget_class, "message.send", NULL, + talkatu_input_send_message_cb); - gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, 0, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_RETURN);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, GDK_SHIFT_MASK, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_SHIFT_RETURN);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, GDK_CONTROL_MASK, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_CONTROL_RETURN);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_KP_Enter, 0, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_KP_ENTER);
+ gtk_widget_class_set_template_from_resource( + "/org/imfreedom/keep/talkatu/talkatu/ui/input.ui" + gtk_widget_class_bind_template_callback(widget_class, + talkatu_input_buffer_set_cb); + gtk_widget_class_bind_template_callback(widget_class, + talkatu_input_key_pressed_cb); /******************************************************************************
@@ -834,7 +740,7 @@
talkatu_input_new(void) {
- return GTK_WIDGET(g_object_new(TALKATU_TYPE_INPUT, NULL));
+ return g_object_new(TALKATU_TYPE_INPUT, NULL); @@ -852,7 +758,7 @@
g_return_if_fail(TALKATU_IS_INPUT(input));
- priv = talkatu_input_get_instance_private(TALKATU_INPUT(input));
+ priv = talkatu_input_get_instance_private(input); priv->send_binding = bindings;
@@ -874,7 +780,7 @@
g_return_val_if_fail(TALKATU_IS_INPUT(input), 0);
- priv = talkatu_input_get_instance_private(TALKATU_INPUT(priv));
+ priv = talkatu_input_get_instance_private(input); return priv->send_binding;
--- a/talkatu/talkatuinput.h Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuinput.h Sun Aug 28 22:44:59 2022 -0500
@@ -48,7 +48,6 @@
- void (*should_send_message)(TalkatuInput *input, TalkatuInputSendBinding binding);
void (*send_message)(TalkatuInput *input);
--- a/talkatu/talkatulinkdialog.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatulinkdialog.c Sun Aug 28 22:44:59 2022 -0500
@@ -90,7 +90,7 @@
if(GTK_IS_ENTRY(dialog->url)) {
gchar *raw = NULL, *ret = NULL;
- raw = g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->url)));
+ raw = g_strdup(gtk_editable_get_text(GTK_EDITABLE(dialog->url))); ret = g_strdup(g_strstrip(raw));
@@ -116,7 +116,7 @@
if(GTK_IS_ENTRY(dialog->display)) {
- ret = g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->display)));
+ ret = g_strdup(gtk_editable_get_text(GTK_EDITABLE(dialog->display))); --- a/talkatu/talkatumarkdownbuffer.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatumarkdownbuffer.c Sun Aug 28 22:44:59 2022 -0500
@@ -270,13 +270,13 @@
*****************************************************************************/
talkatu_markdown_buffer_init(TalkatuMarkdownBuffer *buffer) {
- gtk_text_buffer_register_deserialize_format(
- GTK_TEXT_BUFFER(buffer),
- talkatu_markdown_buffer_deserialize_markdown,
+ // gtk_text_buffer_register_deserialize_format( + // GTK_TEXT_BUFFER(buffer), + // talkatu_markdown_buffer_deserialize_markdown, --- a/talkatu/talkatumenutoolbutton.c Sat Aug 13 22:03:08 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
- * Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
- * This library 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 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this library; if not, see <https://www.gnu.org/licenses/>.
-#include "talkatu/talkatumenutoolbutton.h"
- * TalkatuMenuToolButton:
- * A #GtkToolButton subclass that behaves like a #GtkComboBox.
-struct _TalkatuMenuToolButton {
-G_DEFINE_TYPE(TalkatuMenuToolButton, talkatu_menu_tool_button, GTK_TYPE_TOOL_BUTTON)
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
-/******************************************************************************
- *****************************************************************************/
-talkatu_menu_tool_button_clicked(GtkToolButton *button) {
- TalkatuMenuToolButton *menu_button = TALKATU_MENU_TOOL_BUTTON(button);
- gtk_menu_popup_at_widget(GTK_MENU(menu_button->menu),
- GDK_GRAVITY_SOUTH_WEST,
- GDK_GRAVITY_NORTH_WEST,
-talkatu_menu_tool_button_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) {
- TalkatuMenuToolButton *menu_button = TALKATU_MENU_TOOL_BUTTON(obj);
- g_value_set_object(value, talkatu_menu_tool_button_get_menu(menu_button));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
-talkatu_menu_tool_button_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) {
- TalkatuMenuToolButton *menu_button = TALKATU_MENU_TOOL_BUTTON(obj);
- talkatu_menu_tool_button_set_menu(menu_button, g_value_get_object(value));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
-talkatu_menu_tool_button_init(TalkatuMenuToolButton *menu_button) {
-talkatu_menu_tool_button_class_init(TalkatuMenuToolButtonClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- GtkToolButtonClass *button_class = GTK_TOOL_BUTTON_CLASS(klass);
- obj_class->get_property = talkatu_menu_tool_button_get_property;
- obj_class->set_property = talkatu_menu_tool_button_set_property;
- button_class->clicked = talkatu_menu_tool_button_clicked;
- properties[PROP_MENU] = g_param_spec_object(
- "menu", "menu", "The menu to show",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT
- g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
-/******************************************************************************
- *****************************************************************************/
- * talkatu_menu_tool_button_new:
- * @label: The label to display.
- * @icon_name: The optional name of the icon to display.
- * @menu: The menu to display.
- * Creates a new #TalkatuMenuToolButton with the given @label, @icon_name, and
- * Returns: (transfer full): The new #TalkatuMenuToolButton instance.
-talkatu_menu_tool_button_new(const gchar *label, const gchar *icon_name, GtkWidget *menu) {
- TALKATU_TYPE_MENU_TOOL_BUTTON,
- "icon-name", icon_name,
- * talkatu_menu_tool_button_get_menu:
- * @menu_button: The #TalkatuMenuToolButton instance.
- * Gets the menu that this tool button will display on click or #NULL if no
- * Returns: (transfer full): The menu.
-talkatu_menu_tool_button_get_menu(TalkatuMenuToolButton *menu_button) {
- g_return_val_if_fail(TALKATU_IS_MENU_TOOL_BUTTON(menu_button), FALSE);
- if(menu_button->menu) {
- return g_object_ref(menu_button->menu);
- * talkatu_menu_tool_button_set_menu:
- * @menu_button: The #TalkatuMenuToolButton instance.
- * @menu: The menu to set.
- * Sets the menu to be displayed when the user clicks the button.
-talkatu_menu_tool_button_set_menu(TalkatuMenuToolButton *menu_button, GtkWidget *menu) {
- g_return_if_fail(TALKATU_IS_MENU_TOOL_BUTTON(menu_button));
- if(menu_button->menu) {
- gtk_menu_detach(GTK_MENU(menu_button->menu));
- g_object_unref(G_OBJECT(menu_button->menu));
- menu_button->menu = GTK_WIDGET(g_object_ref(G_OBJECT(menu)));
- gtk_menu_attach_to_widget(GTK_MENU(menu_button->menu), GTK_WIDGET(menu_button), NULL);
- menu_button->menu = NULL;
--- a/talkatu/talkatumenutoolbutton.h Sat Aug 13 22:03:08 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
- * Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
- * This library 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 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this library; if not, see <https://www.gnu.org/licenses/>.
-#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION)
-#error "only <talkatu.h> may be included directly"
-#ifndef TALKATU_MENU_TOOL_BUTTON_H
-#define TALKATU_MENU_TOOL_BUTTON_H
-#include <glib-object.h>
-#define TALKATU_TYPE_MENU_TOOL_BUTTON (talkatu_menu_tool_button_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuMenuToolButton, talkatu_menu_tool_button, TALKATU, MENU_TOOL_BUTTON, GtkToolButton)
-GtkToolItem *talkatu_menu_tool_button_new(const gchar *label, const gchar *icon_name, GtkWidget *menu);
-GtkWidget *talkatu_menu_tool_button_get_menu(TalkatuMenuToolButton *menu_button);
-void talkatu_menu_tool_button_set_menu(TalkatuMenuToolButton *menu_button, GtkWidget *menu);
-#endif /* TALKATU_MENU_TOOL_BUTTON_H */
--- a/talkatu/talkatumessageactions.c Sat Aug 13 22:03:08 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
- * Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
- * This library 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 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this library; if not, see <https://www.gnu.org/licenses/>.
-#include "talkatu/talkatumessageactions.h"
- * TalkatuMessageActions:
- * A composite #GtkWidget to allow the user to interact with a message in a
-struct _TalkatuMessageActions {
- TalkatuMessage *message;
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
-G_DEFINE_TYPE(TalkatuMessageActions, talkatu_message_actions, GTK_TYPE_BOX)
-/******************************************************************************
- *****************************************************************************/
-talkatu_message_actions_set_message(TalkatuMessageActions *message_actions,
- TalkatuMessage *message)
- if(message_actions->message) {
- g_object_unref(G_OBJECT(message_actions->message));
- if(g_set_object(&message_actions->message, message)) {
- g_object_notify_by_pspec(G_OBJECT(message_actions), properties[PROP_MESSAGE]);
-/******************************************************************************
- *****************************************************************************/
-talkatu_message_actions_get_property(GObject *obj,
- TalkatuMessageActions *message_actions = TALKATU_MESSAGE_ACTIONS(obj);
- g_value_set_object(value, talkatu_message_actions_get_message(message_actions));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
-talkatu_message_actions_set_property(GObject *obj,
- TalkatuMessageActions *message_actions = TALKATU_MESSAGE_ACTIONS(obj);
- talkatu_message_actions_set_message(message_actions, g_value_get_object(value));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
-talkatu_message_actions_finalize(GObject *obj) {
- TalkatuMessageActions *message_actions = TALKATU_MESSAGE_ACTIONS(obj);
- g_object_unref(G_OBJECT(message_actions->message));
- G_OBJECT_CLASS(talkatu_message_actions_parent_class)->finalize(obj);
-talkatu_message_actions_init(TalkatuMessageActions *message_actions) {
- gtk_widget_init_template(GTK_WIDGET(message_actions));
-talkatu_message_actions_class_init(TalkatuMessageActionsClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- obj_class->get_property = talkatu_message_actions_get_property;
- obj_class->set_property = talkatu_message_actions_set_property;
- obj_class->finalize = talkatu_message_actions_finalize;
- properties[PROP_MESSAGE] = g_param_spec_object(
- "message", "message", "The message that this widget is for",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
- g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
- gtk_widget_class_set_template_from_resource(
- GTK_WIDGET_CLASS(klass),
- "/org/imfreedom/keep/talkatu/talkatu/ui/messageactions.ui"
-/******************************************************************************
- *****************************************************************************/
- * talkatu_message_actions_new:
- * @message: The #TalkatuMessage instance.
- * Creates a new #TalkatuMessageActions that provides the user with an interface to
- * control the formatting of a #TalkatuBuffer.
- * Returns: (transfer full): The new #TalkatuMessageActions instance.
-talkatu_message_actions_new(TalkatuMessage *message) {
- return GTK_WIDGET(g_object_new(
- TALKATU_TYPE_MESSAGE_ACTIONS,
- * talkatu_message_actions_get_message:
- * @message_actions: The #TalkatuMessageActions instance.
- * Gets the #TalkatuMessage associated with @message_action.
- * Returns: (transfer none): The #TalkatuMessage associated with @message_action.
-talkatu_message_actions_get_message(TalkatuMessageActions *message_actions) {
- g_return_val_if_fail(TALKATU_IS_MESSAGE_ACTIONS(message_actions), NULL);
- return message_actions->message;
--- a/talkatu/talkatumessageactions.h Sat Aug 13 22:03:08 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
- * Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
- * This library 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 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this library; if not, see <https://www.gnu.org/licenses/>.
-#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION)
-#error "only <talkatu.h> may be included directly"
-#ifndef TALKATU_MESSAGE_ACTIONS_H
-#define TALKATU_MESSAGE_ACTIONS_H
-#include <glib-object.h>
-#include <talkatu/talkatumessage.h>
-#define TALKATU_TYPE_MESSAGE_ACTIONS (talkatu_message_actions_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuMessageActions, talkatu_message_actions, TALKATU, MESSAGE_ACTIONS, GtkBox)
-GtkWidget *talkatu_message_actions_new(TalkatuMessage *message);
-TalkatuMessage *talkatu_message_actions_get_message(TalkatuMessageActions *message_actions);
-#endif /* TALKATU_MESSAGE_ACTIONS_H */
--- a/talkatu/talkatuscrolledwindow.c Sat Aug 13 22:03:08 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
- * Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
- * This library 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 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this library; if not, see <https://www.gnu.org/licenses/>.
-#include <talkatu/talkatuscrolledwindow.h>
- * TalkatuScrolledWindow:
- * This widget is a simple subclass of #GtkScrolledWindow that has helpers for
- * keyboard navigation as well as the ability to automatically scroll to the
- * bottom when new items are added if the widget was already scrolled all the
-struct _TalkatuScrolledWindow {
- GtkScrolledWindow parent;
- GtkAdjustment *vadjustment;
-G_DEFINE_TYPE(TalkatuScrolledWindow, talkatu_scrolled_window,
- GTK_TYPE_SCROLLED_WINDOW)
-/******************************************************************************
- *****************************************************************************/
-talkatu_scrolled_window_vadjustment_changed_cb(GtkAdjustment *adjustment,
- TalkatuScrolledWindow *sw = TALKATU_SCROLLED_WINDOW(data);
- gdouble upper, pagesize;
- upper = gtk_adjustment_get_upper(adjustment);
- pagesize = gtk_adjustment_get_page_size(adjustment);
- gtk_adjustment_set_value(adjustment, upper - pagesize);
-talkatu_scrolled_window_vadjustment_value_changed_cb(GtkAdjustment *adjustment,
- TalkatuScrolledWindow *sw = TALKATU_SCROLLED_WINDOW(data);
- gdouble current, upper, pagesize;
- current = gtk_adjustment_get_value(adjustment);
- upper = gtk_adjustment_get_upper(adjustment);
- pagesize = gtk_adjustment_get_page_size(adjustment);
- sw->auto_scroll = (current + pagesize >= upper);
-talkatu_scrolled_window_vadjustment_notify_cb(GObject *obj, GParamSpec *pspec,
- TalkatuScrolledWindow *sw = TALKATU_SCROLLED_WINDOW(obj);
- GtkAdjustment *adjustment = NULL;
- adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(obj));
- if(g_set_object(&sw->vadjustment, adjustment)) {
- sw->auto_scroll = TRUE;
- g_signal_connect(G_OBJECT(adjustment), "value-changed",
- G_CALLBACK(talkatu_scrolled_window_vadjustment_value_changed_cb),
- g_signal_connect(G_OBJECT(adjustment), "changed",
- G_CALLBACK(talkatu_scrolled_window_vadjustment_changed_cb),
-/******************************************************************************
- *****************************************************************************/
-talkatu_scrolled_window_init(TalkatuScrolledWindow *sw) {
- sw->auto_scroll = TRUE;
- g_signal_connect(G_OBJECT(sw), "notify::vadjustment",
- G_CALLBACK(talkatu_scrolled_window_vadjustment_notify_cb),
-talkatu_scrolled_window_finalize(GObject *obj) {
- TalkatuScrolledWindow *sw = TALKATU_SCROLLED_WINDOW(obj);
- g_clear_object(&sw->vadjustment);
- G_OBJECT_CLASS(talkatu_scrolled_window_parent_class)->finalize(obj);
-talkatu_scrolled_window_class_init(TalkatuScrolledWindowClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- obj_class->finalize = talkatu_scrolled_window_finalize;
-/******************************************************************************
- *****************************************************************************/
- * talkatu_scrolled_window_new:
- * @hadjustment: The GtkAdjustment for the horizontal position.
- * @vadjustment: The GtkAdjustment for the vertical position.
- * Creates a new #TalkatuScrolledWindow.
- * Returns: (transfer full): The new #TalkatuScrolledWindow instance.
-GtkWidget *talkatu_scrolled_window_new(GtkAdjustment *hadjustment,
- GtkAdjustment *vadjustment)
- return GTK_WIDGET(g_object_new(
- TALKATU_TYPE_SCROLLED_WINDOW,
- "hadjustment", hadjustment,
- "vadjustment", vadjustment,
- * talkatu_scrolled_window_page_up:
- * @sw: The #TalkatuScrolledWindow instance.
- * Scrolls @sw up one page.
-talkatu_scrolled_window_page_up(TalkatuScrolledWindow *sw) {
- g_return_if_fail(TALKATU_IS_SCROLLED_WINDOW(sw));
- if(sw->vadjustment != NULL) {
- value = gtk_adjustment_get_value(sw->vadjustment);
- value -= gtk_adjustment_get_page_increment(sw->vadjustment);
- gtk_adjustment_set_value(sw->vadjustment, value);
- * talkatu_scrolled_window_page_down:
- * @sw: The #TalkatuScrolledWindow instance.
- * Scrolls @sw down one page.
-talkatu_scrolled_window_page_down(TalkatuScrolledWindow *sw) {
- g_return_if_fail(TALKATU_IS_SCROLLED_WINDOW(sw));
- if(sw->vadjustment != NULL) {
- value = gtk_adjustment_get_value(sw->vadjustment);
- value += gtk_adjustment_get_page_increment(sw->vadjustment);
- gtk_adjustment_set_value(sw->vadjustment, value);
--- a/talkatu/talkatuscrolledwindow.h Sat Aug 13 22:03:08 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
- * Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
- * This library 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 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this library; if not, see <https://www.gnu.org/licenses/>.
-#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION)
-#error "only <talkatu.h> may be included directly"
-#ifndef TALKATU_SCROLLED_WINDOW_H
-#define TALKATU_SCROLLED_WINDOW_H
-#include <glib-object.h>
-#define TALKATU_TYPE_SCROLLED_WINDOW (talkatu_scrolled_window_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuScrolledWindow, talkatu_scrolled_window, TALKATU, SCROLLED_WINDOW, GtkScrolledWindow)
-GtkWidget *talkatu_scrolled_window_new(GtkAdjustment *hadjustment, GtkAdjustment *vadjustment);
-void talkatu_scrolled_window_page_up(TalkatuScrolledWindow *sw);
-void talkatu_scrolled_window_page_down(TalkatuScrolledWindow *sw);
-#endif /* TALKATU_SCROLLED_WINDOW_H */
--- a/talkatu/talkatutagtable.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatutagtable.c Sun Aug 28 22:44:59 2022 -0500
@@ -24,24 +24,12 @@
#include <talkatu/talkatutag.h>
#include <talkatu/talkatutagtable.h>
- * A #GtkTextTagTable subclass that is preloaded with all of the #TalkatuTag's.
-struct _TalkatuTagTable {
- GtkTextTagTable parent;
-G_DEFINE_TYPE(TalkatuTagTable, talkatu_tag_table, GTK_TYPE_TEXT_TAG_TABLE)
/******************************************************************************
*****************************************************************************/
-talkatu_tag_table_init(TalkatuTagTable *table) {
+talkatu_tag_table_populate(GtkTextTagTable *tag_table) { GdkRGBA color = {0.0, 0.0, 0.0, 0.0};
- GtkTextTagTable *tag_table = GTK_TEXT_TAG_TABLE(table);
@@ -276,10 +264,6 @@
-talkatu_tag_table_class_init(TalkatuTagTableClass *klass) {
/******************************************************************************
*****************************************************************************/
@@ -287,14 +271,15 @@
- * Creates a new #TalkatuTagTable that provides the user with an interface to
- * control the formatting of a #TalkatuBuffer.
+ * Creates a new [class@Gtk.TextTagTable] that is populated with all of the + * tags that Talkatu uses. - * Returns: (transfer full): The new #TalkatuTagTable instance.
+ * Returns: (transfer full): The new instance. GtkTextTagTable *talkatu_tag_table_new(void) {
- return GTK_TEXT_TAG_TABLE(g_object_new(
- TALKATU_TYPE_TAG_TABLE,
+ GtkTextTagTable *table = gtk_text_tag_table_new(); + talkatu_tag_table_populate(table); --- a/talkatu/talkatutagtable.h Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatutagtable.h Sun Aug 28 22:44:59 2022 -0500
@@ -24,16 +24,11 @@
#define TALKATU_TAG_TABLE_H
-#include <glib-object.h>
-#define TALKATU_TYPE_TAG_TABLE (talkatu_tag_table_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuTagTable, talkatu_tag_table, TALKATU, TAG_TABLE, GtkTextTagTable)
GtkTextTagTable *talkatu_tag_table_new(void);
--- a/talkatu/talkatutoolbar.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatutoolbar.c Sun Aug 28 22:44:59 2022 -0500
@@ -28,10 +28,10 @@
-G_DEFINE_TYPE(TalkatuToolbar, talkatu_toolbar, GTK_TYPE_TOOLBAR)
+G_DEFINE_TYPE(TalkatuToolbar, talkatu_toolbar, GTK_TYPE_BOX) /******************************************************************************
--- a/talkatu/talkatutoolbar.h Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatutoolbar.h Sun Aug 28 22:44:59 2022 -0500
@@ -32,7 +32,7 @@
#define TALKATU_TYPE_TOOLBAR (talkatu_toolbar_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuToolbar, talkatu_toolbar, TALKATU, TOOLBAR, GtkToolbar)
+G_DECLARE_FINAL_TYPE(TalkatuToolbar, talkatu_toolbar, TALKATU, TOOLBAR, GtkBox) GtkWidget *talkatu_toolbar_new(void);
--- a/talkatu/talkatutooldrawer.c Sat Aug 13 22:03:08 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,357 +0,0 @@
- * Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
- * This library 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 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this library; if not, see <https://www.gnu.org/licenses/>.
-#include "talkatu/talkatutooldrawer.h"
-#include "talkatu/talkatumenutoolbutton.h"
-} TalkatuToolDrawerItem;
- * A #GtkToolItem subclass that displays a menu of items or can be expanded
- * to show all of the items as a toolbar.
-struct _TalkatuToolDrawer {
- GtkToolItem *menu_button;
-static GParamSpec *properties[N_PROPERTIES] = {NULL,};
-G_DEFINE_TYPE(TalkatuToolDrawer, talkatu_tool_drawer, GTK_TYPE_TOOL_ITEM)
-/******************************************************************************
- *****************************************************************************/
-talkatu_tool_drawer_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) {
- TalkatuToolDrawer *drawer = TALKATU_TOOL_DRAWER(obj);
- g_value_set_string(value, talkatu_tool_drawer_get_label(drawer));
- g_value_set_string(value, talkatu_tool_drawer_get_icon_name(drawer));
- g_value_set_boolean(value, talkatu_tool_drawer_get_expanded(drawer));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
-talkatu_tool_drawer_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) {
- TalkatuToolDrawer *drawer = TALKATU_TOOL_DRAWER(obj);
- talkatu_tool_drawer_set_label(drawer, g_value_get_string(value));
- talkatu_tool_drawer_set_icon_name(drawer, g_value_get_string(value));
- talkatu_tool_drawer_set_expanded(drawer, g_value_get_boolean(value));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
-talkatu_tool_drawer_init(TalkatuToolDrawer *drawer) {
-talkatu_tool_drawer_constructed(GObject *obj) {
- TalkatuToolDrawer *drawer = TALKATU_TOOL_DRAWER(obj);
- drawer->menu = gtk_menu_new();
- drawer->box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_container_add(GTK_CONTAINER(drawer), drawer->box);
- drawer->menu_button = talkatu_menu_tool_button_new(drawer->label, drawer->icon_name, drawer->menu);
- gtk_box_pack_start(GTK_BOX(drawer->box), GTK_WIDGET(drawer->menu_button), FALSE, FALSE, 0);
- drawer->icons = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
- gtk_box_pack_start(GTK_BOX(drawer->box), drawer->icons, FALSE, FALSE, 0);
- g_object_set(G_OBJECT(drawer->menu_button), "no-show-all", FALSE, NULL);
- gtk_widget_show_all(GTK_WIDGET(drawer->menu_button));
- g_object_set(G_OBJECT(drawer->icons), "no-show-all", TRUE, NULL);
-talkatu_tool_drawer_class_init(TalkatuToolDrawerClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- obj_class->get_property = talkatu_tool_drawer_get_property;
- obj_class->set_property = talkatu_tool_drawer_set_property;
- obj_class->constructed = talkatu_tool_drawer_constructed;
- properties[PROP_LABEL] = g_param_spec_string(
- "label", "label", "The label to display when not expanded",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
- properties[PROP_ICON_NAME] = g_param_spec_string(
- "icon-name", "icon-name", "The name of the icon to display when not expanded",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
- properties[PROP_EXPANDED] = g_param_spec_boolean(
- "expanded", "expanded", "Whether or not the drawer is expanded",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT
- g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
-/******************************************************************************
- *****************************************************************************/
- * talkatu_tool_drawer_new:
- * @label: The label to give item.
- * @icon_name: The name of the icon for this item.
- * Creates a new #TalkatuToolDrawer instance.
- * Returns: (transfer full): The new #TalkatuToolDrawer instance.
-talkatu_tool_drawer_new(const gchar *label, const gchar *icon_name) {
- TALKATU_TYPE_TOOL_DRAWER,
- "icon-name", icon_name,
- * talkatu_tool_drawer_add_item:
- * @drawer: The #TalkatuToolDrawer instance.
- * @action: The #GAction to add.
- * @markup: Pango markup to use as a label.
- * @icon_name: The name of the icon to display.
- * @tooltip: UTF-8 text to display as a tooltip.
- * @callback: (scope notified): The callback to call when the item is
- * Adds a new item to @drawer.
-talkatu_tool_drawer_add_item(TalkatuToolDrawer *drawer, GAction *action, const gchar *markup, const gchar *icon_name, gchar *tooltip, GCallback callback) {
- GtkWidget *button = NULL, *item = NULL, *label = NULL, *image = NULL;
- const GVariantType *state_type = NULL;
- g_return_if_fail(TALKATU_IS_TOOL_DRAWER(drawer));
- /* create the menu item */
- state_type = g_action_get_state_type(action);
- item = gtk_check_menu_item_new();
- item = gtk_menu_item_new();
- label = gtk_label_new(markup);
- gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
- gtk_label_set_xalign(GTK_LABEL(label), 0);
- gtk_container_add(GTK_CONTAINER(item), label);
- gtk_menu_shell_append(GTK_MENU_SHELL(drawer->menu), item);
- gtk_widget_show_all(item);
- /* create the toolbar button and add it to the toolbar */
- button = gtk_toggle_button_new();
- button = gtk_button_new();
- gtk_widget_set_can_focus(button, FALSE);
- gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
- image = gtk_image_new_from_icon_name(icon_name, GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_container_add(GTK_CONTAINER(button), image);
- gtk_box_pack_start(GTK_BOX(drawer->icons), button, FALSE, FALSE, 0);
- * talkatu_tool_drawer_add_separator:
- * @drawer: The #TalkatuToolDrawer instance.
- * Adds a separator to the end of @drawer.
-talkatu_tool_drawer_add_separator(TalkatuToolDrawer *drawer) {
- g_return_if_fail(TALKATU_IS_TOOL_DRAWER(drawer));
- gtk_menu_shell_append(GTK_MENU_SHELL(drawer->menu), gtk_separator_menu_item_new());
- gtk_box_pack_start(GTK_BOX(drawer->icons), gtk_separator_new(GTK_ORIENTATION_VERTICAL), FALSE, FALSE, 0);
- * talkatu_tool_drawer_get_label:
- * @drawer: The #TalkatuToolDrawer instance.
- * Gets the label that's displayed when @drawer is collapsed.
- * Returns: The label to use when @drawer is collapsed.
-talkatu_tool_drawer_get_label(TalkatuToolDrawer *drawer) {
- g_return_val_if_fail(TALKATU_IS_TOOL_DRAWER(drawer), FALSE);
- * talkatu_tool_drawer_set_label:
- * @drawer: The #TalkatuToolDrawer instance.
- * @label: The label to use when @drawer is collapsed.
- * Sets the label to be displayed when @drawer is collapsed.
-talkatu_tool_drawer_set_label(TalkatuToolDrawer *drawer, const gchar *label) {
- g_return_if_fail(TALKATU_IS_TOOL_DRAWER(drawer));
- drawer->label = g_strdup(label);
- g_object_notify_by_pspec(G_OBJECT(drawer), properties[PROP_LABEL]);
- * talkatu_tool_drawer_get_icon_name:
- * @drawer: The #TalkatuToolDrawer instance.
- * Gets the icon name for @drawer.
- * Returns: The icon name for @drawer.
-talkatu_tool_drawer_get_icon_name(TalkatuToolDrawer *drawer) {
- g_return_val_if_fail(TALKATU_IS_TOOL_DRAWER(drawer), FALSE);
- return drawer->icon_name;
- * talkatu_tool_drawer_set_icon_name:
- * @drawer: The #TalkatuToolDrawer instance.
- * @icon_name: The name of the icon to display when collapse.
- * Sets the name of the icon to be displayed when @drawer is collapsed.
-talkatu_tool_drawer_set_icon_name(TalkatuToolDrawer *drawer, const gchar *icon_name) {
- g_return_if_fail(TALKATU_IS_TOOL_DRAWER(drawer));
- g_free(drawer->icon_name);
- drawer->icon_name = g_strdup(icon_name);
- g_object_notify_by_pspec(G_OBJECT(drawer), properties[PROP_ICON_NAME]);
- * talkatu_tool_drawer_set_expanded:
- * @drawer: The #TalkatuToolDrawer instance.
- * @expanded: %TRUE to expand @drawer, %FALSE to collapse.
- * Sets whether or not @drawer is expanded.
-talkatu_tool_drawer_set_expanded(TalkatuToolDrawer *drawer, gboolean expanded) {
- g_return_if_fail(TALKATU_IS_TOOL_DRAWER(drawer));
- if(expanded != drawer->expanded) {
- drawer->expanded = expanded;
- g_object_set(G_OBJECT(drawer->menu_button), "no-show-all", drawer->expanded, NULL);
- g_object_set(G_OBJECT(drawer->icons), "no-show-all", !drawer->expanded, NULL);
- gtk_widget_hide(GTK_WIDGET(drawer->menu_button));
- gtk_widget_show_all(drawer->icons);
- gtk_widget_show_all(GTK_WIDGET(drawer->menu_button));
- gtk_widget_hide(drawer->icons);
- g_object_notify_by_pspec(G_OBJECT(drawer), properties[PROP_EXPANDED]);
- * talkatu_tool_drawer_get_expanded:
- * @drawer: The #TalkatuToolDrawer instance.
- * Gets whether or not @drawer is expanded.
- * Returns: %TRUE if @drawer is expanded, %FALSE otherwise.
-talkatu_tool_drawer_get_expanded(TalkatuToolDrawer *drawer) {
- g_return_val_if_fail(TALKATU_IS_TOOL_DRAWER(drawer), FALSE);
- return drawer->expanded;
--- a/talkatu/talkatutooldrawer.h Sat Aug 13 22:03:08 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
- * Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
- * This library 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 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this library; if not, see <https://www.gnu.org/licenses/>.
-#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION)
-#error "only <talkatu.h> may be included directly"
-#ifndef TALKATU_TOOL_DRAWER_H
-#define TALKATU_TOOL_DRAWER_H
-#include <glib-object.h>
-#define TALKATU_TYPE_TOOL_DRAWER (talkatu_tool_drawer_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuToolDrawer, talkatu_tool_drawer, TALKATU, TOOL_DRAWER, GtkToolItem)
-GtkToolItem *talkatu_tool_drawer_new(const gchar *label, const gchar *icon_name);
-void talkatu_tool_drawer_add_item(TalkatuToolDrawer *drawer, GAction *action, const gchar *markup, const gchar *icon_name, gchar *tooltip, GCallback callback);
-void talkatu_tool_drawer_add_separator(TalkatuToolDrawer *drawer);
-const gchar *talkatu_tool_drawer_get_label(TalkatuToolDrawer *drawer);
-void talkatu_tool_drawer_set_label(TalkatuToolDrawer *drawer, const gchar *label);
-const gchar *talkatu_tool_drawer_get_icon_name(TalkatuToolDrawer *drawer);
-void talkatu_tool_drawer_set_icon_name(TalkatuToolDrawer *drawer, const gchar *icon_name);
-void talkatu_tool_drawer_set_expanded(TalkatuToolDrawer *drawer, gboolean expanded);
-gboolean talkatu_tool_drawer_get_expanded(TalkatuToolDrawer *drawer);
-#endif /* TALKATU_TOOL_DRAWER_H */
--- a/talkatu/talkatutypinglabel.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatutypinglabel.c Sun Aug 28 22:44:59 2022 -0500
@@ -37,11 +37,13 @@
* Usernames are passed in as strings and their default display can be
* overridden by connecting to the #TalkatuTypingLabel::changed signal.
+struct _TalkatuTypingLabel { -} TalkatuTypingLabelPrivate;
* TalkatuTypingLabelClass:
@@ -62,7 +64,7 @@
static guint signals[LAST_SIGNAL] = {0, };
-G_DEFINE_TYPE_WITH_PRIVATE(TalkatuTypingLabel, talkatu_typing_label, GTK_TYPE_LABEL)
+G_DEFINE_TYPE(TalkatuTypingLabel, talkatu_typing_label, GTK_TYPE_WIDGET) #define TALKATU_TYPING_LABEL_TIMEOUT (30)
@@ -101,14 +103,14 @@
- gtk_label_set_text(GTK_LABEL(label), "");
+ gtk_label_set_text(GTK_LABEL(label->label), ""); n_typers = g_list_length(typers);
- gtk_label_set_text(GTK_LABEL(label),
+ gtk_label_set_text(GTK_LABEL(label->label), _("Several people are typing..."));
@@ -126,7 +128,7 @@
(gchar *)typers->next->next->data);
- gtk_label_set_text(GTK_LABEL(label), text);
+ gtk_label_set_text(GTK_LABEL(label->label), text); @@ -136,24 +138,26 @@
*****************************************************************************/
talkatu_typing_label_init(TalkatuTypingLabel *label) {
- TalkatuTypingLabelPrivate *priv = NULL;
+ gtk_widget_init_template(GTK_WIDGET(label)); - /* set our xalign to 0 to make it left justified... */
- gtk_label_set_xalign(GTK_LABEL(label), 0);
+ label->typers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + talkatu_typing_label_typer_value_free); - priv = talkatu_typing_label_get_instance_private(TALKATU_TYPING_LABEL(label));
+talkatu_typing_label_dispose(GObject *obj) { + TalkatuTypingLabel *label = TALKATU_TYPING_LABEL(obj); - priv->typers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
- talkatu_typing_label_typer_value_free);
+ g_clear_pointer(&label->label, gtk_widget_unparent); + G_OBJECT_CLASS(talkatu_typing_label_parent_class)->dispose(obj); talkatu_typing_label_finalize(GObject *obj) {
- TalkatuTypingLabelPrivate *priv = NULL;
+ TalkatuTypingLabel *label = TALKATU_TYPING_LABEL(obj); - priv = talkatu_typing_label_get_instance_private(TALKATU_TYPING_LABEL(obj));
- g_hash_table_destroy(priv->typers);
+ g_hash_table_destroy(label->typers); G_OBJECT_CLASS(talkatu_typing_label_parent_class)->finalize(obj);
@@ -161,11 +165,11 @@
talkatu_typing_label_class_init(TalkatuTypingLabelClass *klass) {
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + obj_class->dispose = talkatu_typing_label_dispose; obj_class->finalize = talkatu_typing_label_finalize;
- klass->changed = talkatu_typing_label_default_changed;
* TalkatuTypingLabel::changed:
* @talkatutypinglabel: The #TalkatuTypingLabel instance.
@@ -174,11 +178,11 @@
* Emitted when the typing state of an individual has changed.
- signals[SIG_CHANGED] = g_signal_new(
+ signals[SIG_CHANGED] = g_signal_new_class_handler( G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET(TalkatuTypingLabelClass, changed),
+ G_CALLBACK(talkatu_typing_label_default_changed), @@ -186,6 +190,16 @@
+ gtk_widget_class_set_template_from_resource( + GTK_WIDGET_CLASS(klass), + "/org/imfreedom/keep/talkatu/talkatu/ui/typinglabel.ui" + gtk_widget_class_set_layout_manager_type(widget_class, GTK_TYPE_BIN_LAYOUT); + gtk_widget_class_bind_template_child(widget_class, TalkatuTypingLabel, /******************************************************************************
@@ -200,10 +214,7 @@
* Returns: (transfer full): The new #TalkatuTypingLabel instance.
GtkWidget *talkatu_typing_label_new(void) {
- return GTK_WIDGET(g_object_new(
- TALKATU_TYPE_TYPING_LABEL,
+ return g_object_new(TALKATU_TYPE_TYPING_LABEL, NULL); @@ -215,7 +226,6 @@
talkatu_typing_label_start_typing(TalkatuTypingLabel *label, const gchar *who) {
- TalkatuTypingLabelPrivate *priv = NULL;
TalkatuTypingLabelTimeoutData *typing_data = NULL;
@@ -223,8 +233,6 @@
g_return_if_fail(TALKATU_IS_TYPING_LABEL(label));
g_return_if_fail(who != NULL);
- priv = talkatu_typing_label_get_instance_private(label);
/* create a timeout to remove this person from the list */
typing_data = g_new(TalkatuTypingLabelTimeoutData, 1);
typing_data->label = label;
@@ -240,9 +248,9 @@
value = GUINT_TO_POINTER(timeout_id);
- if(g_hash_table_replace(priv->typers, typing_data->who, value)) {
+ if(g_hash_table_replace(label->typers, typing_data->who, value)) { /* the user wasn't in the list so we need to emit our changed signal */
- GList *typers = g_hash_table_get_keys(priv->typers);
+ GList *typers = g_hash_table_get_keys(label->typers); g_signal_emit(label, signals[SIG_CHANGED], 0, typers);
@@ -261,15 +269,11 @@
talkatu_typing_label_finish_typing(TalkatuTypingLabel *label,
- TalkatuTypingLabelPrivate *priv = NULL;
g_return_if_fail(TALKATU_IS_TYPING_LABEL(label));
g_return_if_fail(who != NULL);
- priv = talkatu_typing_label_get_instance_private(label);
- if(g_hash_table_remove(priv->typers, who)) {
- GList *typers = g_hash_table_get_keys(priv->typers);
+ if(g_hash_table_remove(label->typers, who)) { + GList *typers = g_hash_table_get_keys(label->typers); /* emit our changed signal */
g_signal_emit(label, signals[SIG_CHANGED], 0, typers);
@@ -277,4 +281,3 @@
--- a/talkatu/talkatutypinglabel.h Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatutypinglabel.h Sun Aug 28 22:44:59 2022 -0500
@@ -1,6 +1,6 @@
* Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,18 +31,7 @@
#define TALKATU_TYPE_TYPING_LABEL (talkatu_typing_label_get_type())
-G_DECLARE_DERIVABLE_TYPE(TalkatuTypingLabel, talkatu_typing_label, TALKATU, TYPING_LABEL, GtkLabel)
-struct _TalkatuTypingLabelClass {
- void (*changed)(TalkatuTypingLabel *label, GList *typers);
+G_DECLARE_FINAL_TYPE(TalkatuTypingLabel, talkatu_typing_label, TALKATU, TYPING_LABEL, GtkWidget) GtkWidget *talkatu_typing_label_new(void);
--- a/talkatu/talkatuview.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuview.c Sun Aug 28 22:44:59 2022 -0500
@@ -32,8 +32,6 @@
- * @format_activate: The class handler for the #TalkatuView::format_activate
* @open_url: The class handler for the #TalkatuView::open_url signal.
* The backing class to #TalkatuView instances.
@@ -48,15 +46,11 @@
GSimpleActionGroup *action_group;
- /* we cache the cursor that's displayed while hovering over a link as well
- * the tag for links/anchors to avoid extra lookups.
- GdkCursor *cursor_hand;
- GtkTextTag *tag_anchor;
@@ -67,7 +61,7 @@
/******************************************************************************
*****************************************************************************/
talkatu_view_url_from_iter(TalkatuView *view, GtkTextIter *iter) {
@@ -89,158 +83,113 @@
/******************************************************************************
*****************************************************************************/
-talkatu_view_open_url_cb(GtkMenuItem *item, gpointer data) {
- TalkatuView *view = g_object_get_data(G_OBJECT(item), "view");
- gchar *url = g_object_get_data(G_OBJECT(item), "url");
+talkatu_view_link_open_cb(GtkWidget *widget, const gchar *action_name, + TalkatuView *view = TALKATU_VIEW(widget); + TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view); - g_signal_emit(view, signals[SIG_OPEN_URL], 0, url);
+ g_signal_emit(view, signals[SIG_OPEN_URL], 0, priv->url); -talkatu_view_copy_url_cb(GtkMenuItem *item, gpointer data) {
- GtkClipboard *clipboard = gtk_widget_get_clipboard(
- GDK_SELECTION_CLIPBOARD
+talkatu_view_link_copy_cb(GtkWidget *widget, const gchar *action_name, + TalkatuView *view = TALKATU_VIEW(widget); + TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view); - gtk_clipboard_set_text(clipboard, (gchar *)data, -1);
+ if(priv->url != NULL) { + GdkClipboard *clipboard = NULL; + clipboard = gtk_widget_get_clipboard(widget); + gdk_clipboard_set_text(clipboard, priv->url);
-talkatu_view_anchor_tag_event_cb(GtkTextTag *tag,
+/****************************************************************************** + *****************************************************************************/ +talkatu_view_pressed_cb(GtkGestureClick *gesture, guint n_press, double wx, + double wy, gpointer data) - GdkEventType event_type = gdk_event_get_event_type(event);
- if(event_type == GDK_BUTTON_PRESS) {
- GdkEventButton *event_button = (GdkEventButton *)event;
- /* the user is right clicking on a link so stop the default handler */
- if(event_button->button == GDK_BUTTON_SECONDARY) {
- } else if(gdk_event_triggers_context_menu(event)) {
- GdkEventButton *event_button = (GdkEventButton *)event;
- TalkatuView *view = TALKATU_VIEW(object);
- url = talkatu_view_url_from_iter(view, iter);
- /* if we didn't find a url, bail */
- if(event_button->button == GDK_BUTTON_PRIMARY) {
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
- /* old behavior from pidgin2, if the users has something selected
- * we don't open links. Other clients don't do this.. but it seems
- * to be a work around for someone pressing a button over text,
- * then moving the cursor to the link and then releasing. Without
- * the selection check that'll cause that to open the link if the
- * button is released in the middle of the link.
- if(gtk_text_buffer_get_has_selection(buffer)) {
- g_signal_emit(view, signals[SIG_OPEN_URL], 0, url);
+ TalkatuView *view = TALKATU_VIEW(data); + const gchar *url = NULL;
- } else if(gdk_event_triggers_context_menu(event)) {
- GtkWidget *menu = gtk_menu_new();
- GtkWidget *item = NULL;
+ gtk_text_view_window_to_buffer_coords( + gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(view), &iter, x, y); - item = gtk_menu_item_new_with_label(_("Open Link"));
- /* to make it easier to deal with the life cycle, we just add data
- * to the menu item itself with destroy notifies.
- g_object_set_data_full(
- g_object_set_data_full(
- G_CALLBACK(talkatu_view_open_url_cb),
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ url = talkatu_view_url_from_iter(view, &iter); + gint button = gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(gesture)); - item = gtk_menu_item_new_with_label(_("Copy Link"));
- G_CALLBACK(talkatu_view_copy_url_cb),
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ g_signal_emit(view, signals[SIG_OPEN_URL], 0, url); + } else if(button == 2) { + TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view); - gtk_widget_show_all(menu);
- G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, event_button->time);
- G_GNUC_END_IGNORE_DEPRECATIONS
+ g_clear_pointer(&priv->url, g_free); + priv->url = g_strdup(url);
+ gtk_popover_set_pointing_to(GTK_POPOVER(priv->menu), + &(const GdkRectangle){ x, y, 1, 1}); + gtk_popover_popup(GTK_POPOVER(priv->menu));
+talkatu_view_motion_cb(GtkEventControllerMotion *controller, gdouble wx, + gdouble wy, gpointer data) + TalkatuView *view = TALKATU_VIEW(data); + const gchar *url = NULL; + gtk_text_view_window_to_buffer_coords( + gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(view), &iter, x, y); + url = talkatu_view_url_from_iter(view, &iter); + gtk_widget_set_cursor_from_name(GTK_WIDGET(view), "pointer"); + gtk_widget_set_cursor_from_name(GTK_WIDGET(view), "text"); talkatu_view_buffer_set_cb(GObject *view, GParamSpec *pspec, gpointer data) {
TalkatuViewPrivate *priv = talkatu_view_get_instance_private(TALKATU_VIEW(view));
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
- GtkTextTagTable *table = gtk_text_buffer_get_tag_table(buffer);
if(TALKATU_IS_BUFFER(buffer)) {
priv->action_group = talkatu_buffer_get_action_group(TALKATU_BUFFER(buffer));
- /* check for the anchor tag, if we have it, add a signal handler to it */
- priv->tag_anchor = gtk_text_tag_table_lookup(table, TALKATU_TAG_ANCHOR);
- if(priv->tag_anchor != NULL) {
- G_CALLBACK(talkatu_view_anchor_tag_event_cb),
/******************************************************************************
* Default Signal Handlers
*****************************************************************************/
-talkatu_view_format_activate(TalkatuView *view, const gchar *action_name) {
- TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view);
- if(priv->action_group) {
- GAction *action = g_action_map_lookup_action(G_ACTION_MAP(priv->action_group), action_name);
- g_action_activate(action, NULL);
talkatu_view_query_tooltip(GtkWidget *widget,
@@ -249,7 +198,7 @@
+ const gchar *url = NULL; @@ -283,35 +232,6 @@
return GTK_WIDGET_CLASS(talkatu_view_parent_class)->query_tooltip(widget, x, y, keyboard, tooltip);
-talkatu_view_motion_notify_event(GtkWidget *widget, GdkEventMotion *event) {
- TalkatuViewPrivate *priv = talkatu_view_get_instance_private(TALKATU_VIEW(widget));
- GdkCursor *cursor = NULL;
- gtk_text_view_window_to_buffer_coords(
- gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &iter, x, y);
- if(gtk_text_iter_has_tag(&iter, priv->tag_anchor)) {
- cursor = priv->cursor_hand;
- if(cursor != gdk_window_get_cursor(event->window)) {
- gdk_window_set_cursor(event->window, cursor);
- return GTK_WIDGET_CLASS(talkatu_view_parent_class)->motion_notify_event(widget, event);
/******************************************************************************
* GtkTextViewClass overrides
*****************************************************************************/
@@ -327,37 +247,24 @@
talkatu_view_finalize(GObject *obj) {
TalkatuViewPrivate *priv = talkatu_view_get_instance_private(TALKATU_VIEW(obj));
- g_clear_object(&priv->cursor_hand);
+ g_clear_pointer(&priv->url, g_free); G_OBJECT_CLASS(talkatu_view_parent_class)->finalize(obj);
-talkatu_view_init(TalkatuView *view) {
+talkatu_view_dispose(GObject *obj) { + TalkatuView *view = TALKATU_VIEW(obj); TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view);
- priv->cursor_hand = gdk_cursor_new_from_name(gdk_display_get_default(), "pointer");
- /* tell the widget class that we support tooltips. This is used to show
- * link targets, and probably other stuff at some point.
- gtk_widget_set_has_tooltip(GTK_WIDGET(view), TRUE);
+ g_clear_pointer(&priv->menu, gtk_widget_unparent); - /* set our event mask for the signals we care about */
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK
+ G_OBJECT_CLASS(talkatu_view_parent_class)->dispose(obj); - /* we need to know when the buffer is changed in our parent so we can
- * update our actions and other stuff.
- G_CALLBACK(talkatu_view_buffer_set_cb),
+talkatu_view_init(TalkatuView *view) { + gtk_widget_init_template(GTK_WIDGET(view)); @@ -365,42 +272,22 @@
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS(klass);
- GtkBindingSet *binding_set = NULL;
+ obj_class->dispose = talkatu_view_dispose; obj_class->finalize = talkatu_view_finalize;
- widget_class->motion_notify_event = talkatu_view_motion_notify_event;
widget_class->query_tooltip = talkatu_view_query_tooltip;
+ gtk_widget_class_set_template_from_resource( + "/org/imfreedom/keep/talkatu/talkatu/ui/view.ui" text_view_class->create_buffer = talkatu_view_create_buffer;
- /* add our default signal handlers */
- klass->format_activate = talkatu_view_format_activate;
- * TalkatuView::format-activate
- * @talkatutextview: The #TalkatuView instance.
- * @arg1: The name of the action to activated.
- * @user_data: User supplied data.
- * Emitted by the keybindings to apply a format to the underlying buffer.
- signals[SIG_FORMAT_ACTIVATE] = g_signal_new(
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET(TalkatuViewClass, format_activate),
* @talkatutextview: The #TalkatuView instances.
@@ -421,22 +308,30 @@
- /* setup key bindings */
- binding_set = gtk_binding_set_by_class(talkatu_view_parent_class);
+ gtk_widget_class_bind_template_callback(widget_class, + talkatu_view_pressed_cb); + gtk_widget_class_bind_template_callback(widget_class, + talkatu_view_motion_cb); + gtk_widget_class_bind_template_callback(widget_class, + talkatu_view_buffer_set_cb); - /* remove existing keybindings that we're overriding */
- gtk_binding_entry_remove(binding_set, GDK_KEY_slash, GDK_CONTROL_MASK);
+ gtk_widget_class_bind_template_child_private(widget_class, TalkatuView, menu); + gtk_widget_class_install_action(widget_class, "link.open", NULL, + talkatu_view_link_open_cb); + gtk_widget_class_install_action(widget_class, "link.copy", NULL, + talkatu_view_link_copy_cb); /* add our custom keybindings */
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_b, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_BOLD);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_i, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_ITALIC);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_u, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_UNDERLINE);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_slash, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_STRIKETHROUGH);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_plus, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_GROW);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_equal, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_GROW);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_minus, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_SHRINK);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_r, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_RESET);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_Insert, GDK_MOD1_MASK | GDK_SHIFT_MASK, "insert-at-cursor", 1, G_TYPE_STRING, "🐣");
+ gtk_widget_class_add_binding_action(widget_class, GDK_KEY_b, GDK_CONTROL_MASK, TALKATU_ACTION_FORMAT_BOLD, NULL); + gtk_widget_class_add_binding_action(widget_class, GDK_KEY_i, GDK_CONTROL_MASK, TALKATU_ACTION_FORMAT_ITALIC, NULL); + gtk_widget_class_add_binding_action(widget_class, GDK_KEY_slash, GDK_CONTROL_MASK, TALKATU_ACTION_FORMAT_STRIKETHROUGH, NULL); + gtk_widget_class_add_binding_action(widget_class, GDK_KEY_plus, GDK_CONTROL_MASK, TALKATU_ACTION_FORMAT_GROW, NULL); + gtk_widget_class_add_binding_action(widget_class, GDK_KEY_equal, GDK_CONTROL_MASK, TALKATU_ACTION_FORMAT_GROW, NULL); + gtk_widget_class_add_binding_action(widget_class, GDK_KEY_minus, GDK_CONTROL_MASK, TALKATU_ACTION_FORMAT_SHRINK, NULL); + gtk_widget_class_add_binding_action(widget_class, GDK_KEY_r, GDK_CONTROL_MASK, TALKATU_ACTION_FORMAT_RESET, NULL); + gtk_widget_class_add_binding_signal(widget_class, GDK_KEY_Insert, GDK_META_MASK | GDK_SHIFT_MASK, "insert-at-cursor", "s", "🐣"); /******************************************************************************
@@ -463,8 +358,5 @@
* Returns: (transfer full): The new #TalkatuView.
GtkWidget *talkatu_view_new_with_buffer(GtkTextBuffer *buffer) {
- return GTK_WIDGET(g_object_new(
+ return g_object_new(TALKATU_TYPE_VIEW, "buffer", buffer, NULL); --- a/talkatu/talkatuview.h Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/talkatuview.h Sun Aug 28 22:44:59 2022 -0500
@@ -30,8 +30,7 @@
-#define TALKATU_TYPE_VIEW (talkatu_view_get_type())
+#define TALKATU_TYPE_VIEW (talkatu_view_get_type()) G_DECLARE_DERIVABLE_TYPE(TalkatuView, talkatu_view, TALKATU, VIEW, GtkTextView)
struct _TalkatuViewClass {
--- a/talkatu/tests/meson.build Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/tests/meson.build Sun Aug 28 22:44:59 2022 -0500
@@ -8,14 +8,14 @@
'test-html-serialization',
'talkatutesthtmlserialization.c',
- dependencies : [talkatu_dep, GLIB, GTK3]
+ dependencies : [talkatu_dep, GLIB, GTK4] test('html', TEST_WRAPPER, args : e, is_parallel : false, env : testenv)
'talkatutestactiongroup.c',
- dependencies : [talkatu_dep, GLIB, GTK3]
+ dependencies : [talkatu_dep, GLIB, GTK4] test('action-group', TEST_WRAPPER, args : e, is_parallel : false, env : testenv)
--- a/talkatu/tests/talkatutestactiongroup.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/tests/talkatutestactiongroup.c Sun Aug 28 22:44:59 2022 -0500
@@ -84,7 +84,7 @@
g_test_init(&argc, &argv, NULL);
- gtk_init(&argc, &argv);
--- a/talkatu/tests/talkatutesthtmlpangorenderer.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/tests/talkatutesthtmlpangorenderer.c Sun Aug 28 22:44:59 2022 -0500
@@ -140,7 +140,7 @@
g_test_init(&argc, &argv, NULL);
- gtk_init(&argc, &argv);
--- a/talkatu/tests/talkatutesthtmlrenderer.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/tests/talkatutesthtmlrenderer.c Sun Aug 28 22:44:59 2022 -0500
@@ -205,7 +205,7 @@
g_test_init(&argc, &argv, NULL);
- gtk_init(&argc, &argv);
--- a/talkatu/tests/talkatutesthtmlserialization.c Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/tests/talkatutesthtmlserialization.c Sun Aug 28 22:44:59 2022 -0500
@@ -79,7 +79,7 @@
g_test_init(&argc, &argv, NULL);
- gtk_init(&argc, &argv);
--- a/talkatu/tests/test-wrapper.py Sat Aug 13 22:03:08 2022 -0500
+++ b/talkatu/tests/test-wrapper.py Sun Aug 28 22:44:59 2022 -0500
@@ -27,7 +27,7 @@
- broadwayd = subprocess.Popen(['broadwayd'])
+ broadwayd = subprocess.Popen(['gtk4-broadwayd']) # run the unit test but set the GDK_BACKEND envvar to broadway
env = {**os.environ, 'GDK_BACKEND': 'broadway'}
--- a/vapi/meson.build Sat Aug 13 22:03:08 2022 -0500
+++ b/vapi/meson.build Sun Aug 28 22:44:59 2022 -0500
@@ -7,7 +7,7 @@
talkatu_vapi = gnome.generate_vapi('talkatu',
sources : talkatu_gir[0],
- packages : [ 'gtk+-3.0' ],
gir_dirs : meson.current_build_dir() / '..' / 'talkatu',