Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package dino for openSUSE:Factory checked in at 2023-07-10 16:40:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dino (Old) and /work/SRC/openSUSE:Factory/.dino.new.23466 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "dino" Mon Jul 10 16:40:06 2023 rev:9 rq:1097860 version:0.4.3 Changes: -------- --- /work/SRC/openSUSE:Factory/dino/dino.changes 2023-03-24 15:21:50.171330651 +0100 +++ /work/SRC/openSUSE:Factory/.dino.new.23466/dino.changes 2023-07-10 16:40:06.858619245 +0200 @@ -1,0 +2,21 @@ +Mon Jul 10 05:42:08 UTC 2023 - Michael Vetter <mvet...@suse.com> + +- Update to 0.4.3: + * Fix video for cameras with rotated image + * Fix call window controlls hiding + * Fix call window styling + * Fix empty alias being handled different than none + * Fix crash on NS_URI call when own server has no MAM; + drop broken mam: 1 "support" #1405 + * Focus ChatInput textbox after selecting emoji + * Fix character counting for fallbacks #1420 + * Fix chat input status having a fixed width requirement #1439 + * Fix chat input for IME #1419 + * Fix reactions being made to the wrong message #1426 + * data: Set X-Purism-FormFactor in .desktop file + * Ignore non-DTLS data before handshake is complete + * Do not send DTLS datagrams to RTP even after handshake + * Fix certificate start time + * Fix potential crash in video calls + +------------------------------------------------------------------- Old: ---- dino-0.4.2.tar.gz New: ---- dino-0.4.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ dino.spec ++++++ --- /var/tmp/diff_new_pack.xkzNCB/_old 2023-07-10 16:40:07.566623465 +0200 +++ /var/tmp/diff_new_pack.xkzNCB/_new 2023-07-10 16:40:07.566623465 +0200 @@ -25,7 +25,7 @@ %endif Name: dino -Version: 0.4.2 +Version: 0.4.3 Release: 0 Summary: Modern Jabber/XMPP Client using GTK+/Vala License: GPL-3.0-only ++++++ dino-0.4.2.tar.gz -> dino-0.4.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/VERSION new/dino-0.4.3/VERSION --- old/dino-0.4.2/VERSION 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/VERSION 2023-07-09 19:00:00.000000000 +0200 @@ -1 +1 @@ -RELEASE 0.4.2 +RELEASE 0.4.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/libdino/src/service/history_sync.vala new/dino-0.4.3/libdino/src/service/history_sync.vala --- old/dino-0.4.2/libdino/src/service/history_sync.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/libdino/src/service/history_sync.vala 2023-07-09 19:00:00.000000000 +0200 @@ -90,11 +90,9 @@ if (!is_muc_mam && !from_our_server) return; // Get the server time of the message and store it in `mam_times` - Xmpp.MessageArchiveManagement.Flag? mam_flag = stream != null ? stream.get_flag(Xmpp.MessageArchiveManagement.Flag.IDENTITY) : null; - if (mam_flag == null) return; - string? id = message.stanza.get_deep_attribute(mam_flag.ns_ver + ":result", "id"); + string? id = message.stanza.get_deep_attribute(Xmpp.MessageArchiveManagement.NS_URI + ":result", "id"); if (id == null) return; - StanzaNode? delay_node = message.stanza.get_deep_subnode(mam_flag.ns_ver + ":result", StanzaForwarding.NS_URI + ":forwarded", DelayedDelivery.NS_URI + ":delay"); + StanzaNode? delay_node = message.stanza.get_deep_subnode(Xmpp.MessageArchiveManagement.NS_URI + ":result", StanzaForwarding.NS_URI + ":forwarded", DelayedDelivery.NS_URI + ":delay"); if (delay_node == null) { warning("MAM result did not contain delayed time %s", message.stanza.to_string()); return; @@ -104,7 +102,7 @@ mam_times[account][id] = time; // Check if this is the target message - string? query_id = message.stanza.get_deep_attribute(mam_flag.ns_ver + ":result", mam_flag.ns_ver + ":queryid"); + string? query_id = message.stanza.get_deep_attribute(Xmpp.MessageArchiveManagement.NS_URI + ":result", Xmpp.MessageArchiveManagement.NS_URI + ":queryid"); if (query_id != null && id == catchup_until_id[account]) { debug("[%s] Hitted range (id) %s", account.bare_jid.to_string(), id); hitted_range[query_id] = -2; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/libdino/src/service/message_processor.vala new/dino-0.4.3/libdino/src/service/message_processor.vala --- old/dino-0.4.2/libdino/src/service/message_processor.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/libdino/src/service/message_processor.vala 2023-07-09 19:00:00.000000000 +0200 @@ -170,19 +170,21 @@ XmppStream? stream = stream_interactor.get_stream(account); Xmpp.MessageArchiveManagement.MessageFlag? mam_message_flag = Xmpp.MessageArchiveManagement.MessageFlag.get_flag(message); - Xmpp.MessageArchiveManagement.Flag? mam_flag = stream != null ? stream.get_flag(Xmpp.MessageArchiveManagement.Flag.IDENTITY) : null; EntityInfo entity_info = stream_interactor.get_module(EntityInfo.IDENTITY); - if (mam_message_flag != null && mam_flag != null && mam_flag.ns_ver == Xmpp.MessageArchiveManagement.NS_URI_2 && mam_message_flag.mam_id != null) { - new_message.server_id = mam_message_flag.mam_id; + if (mam_message_flag != null && mam_message_flag.mam_id != null) { + bool server_does_mam = entity_info.has_feature_cached(account, account.bare_jid, Xmpp.MessageArchiveManagement.NS_URI); + if (server_does_mam) { + new_message.server_id = mam_message_flag.mam_id; + } } else if (message.type_ == Xmpp.MessageStanza.TYPE_GROUPCHAT) { bool server_supports_sid = (yield entity_info.has_feature(account, new_message.counterpart.bare_jid, Xep.UniqueStableStanzaIDs.NS_URI)) || - (yield entity_info.has_feature(account, new_message.counterpart.bare_jid, Xmpp.MessageArchiveManagement.NS_URI_2)); + (yield entity_info.has_feature(account, new_message.counterpart.bare_jid, Xmpp.MessageArchiveManagement.NS_URI)); if (server_supports_sid) { new_message.server_id = Xep.UniqueStableStanzaIDs.get_stanza_id(message, new_message.counterpart.bare_jid); } } else if (message.type_ == Xmpp.MessageStanza.TYPE_CHAT) { bool server_supports_sid = (yield entity_info.has_feature(account, account.bare_jid, Xep.UniqueStableStanzaIDs.NS_URI)) || - (yield entity_info.has_feature(account, account.bare_jid, Xmpp.MessageArchiveManagement.NS_URI_2)); + (yield entity_info.has_feature(account, account.bare_jid, Xmpp.MessageArchiveManagement.NS_URI)); if (server_supports_sid) { new_message.server_id = Xep.UniqueStableStanzaIDs.get_stanza_id(message, account.bare_jid); } @@ -378,7 +380,7 @@ public override async bool run(Entities.Message message, Xmpp.MessageStanza stanza, Conversation conversation) { bool is_mam_message = Xmpp.MessageArchiveManagement.MessageFlag.get_flag(stanza) != null; XmppStream? stream = stream_interactor.get_stream(conversation.account); - Xmpp.MessageArchiveManagement.Flag? mam_flag = stream != null ? stream.get_flag(Xmpp.MessageArchiveManagement.Flag.IDENTITY) : null; + Xmpp.MessageArchiveManagement.Flag mam_flag = Xmpp.MessageArchiveManagement.Flag.get_flag(stream); if (is_mam_message || (mam_flag != null && mam_flag.cought_up == true)) { conversation.account.mam_earliest_synced = message.local_time; } @@ -494,8 +496,7 @@ string fallback = FallbackBody.get_quoted_fallback_body(content_item); - long fallback_length = fallback.length; - var fallback_location = new Xep.FallbackIndication.FallbackLocation(0, (int)fallback_length); + var fallback_location = new Xep.FallbackIndication.FallbackLocation(0, (int)fallback.char_count()); Xep.FallbackIndication.set_fallback(new_stanza, new Xep.FallbackIndication.Fallback(Xep.Replies.NS_URI, new Xep.FallbackIndication.FallbackLocation[] { fallback_location })); return fallback; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/libdino/src/service/muc_manager.vala new/dino-0.4.3/libdino/src/service/muc_manager.vala --- old/dino-0.4.2/libdino/src/service/muc_manager.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/libdino/src/service/muc_manager.vala 2023-07-09 19:00:00.000000000 +0200 @@ -72,7 +72,7 @@ bool receive_history = true; EntityInfo entity_info = stream_interactor.get_module(EntityInfo.IDENTITY); - bool can_do_mam = yield entity_info.has_feature(account, jid, Xmpp.MessageArchiveManagement.NS_URI_2); + bool can_do_mam = yield entity_info.has_feature(account, jid, Xmpp.MessageArchiveManagement.NS_URI); if (can_do_mam) { receive_history = false; history_since = null; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/libdino/src/service/reactions.vala new/dino-0.4.3/libdino/src/service/reactions.vala --- old/dino-0.4.2/libdino/src/service/reactions.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/libdino/src/service/reactions.vala 2023-07-09 19:00:00.000000000 +0200 @@ -64,7 +64,7 @@ // The MUC server needs to 1) support stable stanza ids 2) either support occupant ids or be a private room (where we know real jids) var entity_info = stream_interactor.get_module(EntityInfo.IDENTITY); bool server_supports_sid = (entity_info.has_feature_cached(conversation.account, conversation.counterpart.bare_jid, Xep.UniqueStableStanzaIDs.NS_URI)) || - (entity_info.has_feature_cached(conversation.account, conversation.counterpart.bare_jid, Xmpp.MessageArchiveManagement.NS_URI_2)); + (entity_info.has_feature_cached(conversation.account, conversation.counterpart.bare_jid, Xmpp.MessageArchiveManagement.NS_URI)); if (!server_supports_sid) return false; bool? supports_occupant_ids = entity_info.has_feature_cached(conversation.account, conversation.counterpart, Xep.OccupantIds.NS_URI); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/libdino/src/service/replies.vala new/dino-0.4.3/libdino/src/service/replies.vala --- old/dino-0.4.2/libdino/src/service/replies.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/libdino/src/service/replies.vala 2023-07-09 19:00:00.000000000 +0200 @@ -105,7 +105,8 @@ string body = message.body; foreach (var fallback in message.get_fallbacks()) { if (fallback.ns_uri == Xep.Replies.NS_URI && message.quoted_item_id > 0) { - body = body[0:fallback.locations[0].from_char] + body[fallback.locations[0].to_char:body.length]; + body = body[0:body.index_of_nth_char(fallback.locations[0].from_char)] + + body[body.index_of_nth_char(fallback.locations[0].to_char):body.length]; } } return body; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/libdino/src/util/display_name.vala new/dino-0.4.3/libdino/src/util/display_name.vala --- old/dino-0.4.2/libdino/src/util/display_name.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/libdino/src/util/display_name.vala 2023-07-09 19:00:00.000000000 +0200 @@ -34,6 +34,7 @@ if (self_word != null && (account.alias == null || account.alias.length == 0)) { return self_word; } + if (account.alias != null && account.alias.length == 0) return null; return account.alias; } Roster.Item roster_item = stream_interactor.get_module(RosterManager.IDENTITY).get_roster_item(account, jid); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/main/data/chat_input.ui new/dino-0.4.3/main/data/chat_input.ui --- old/dino-0.4.2/main/data/chat_input.ui 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/main/data/chat_input.ui 2023-07-09 19:00:00.000000000 +0200 @@ -85,6 +85,7 @@ <property name="margin_bottom">3</property> <property name="margin_start">14</property> <property name="margin_end">14</property> + <property name="wrap">True</property> <attributes> <attribute name="scale" value="0.8"></attribute> </attributes> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/main/data/im.dino.Dino.desktop new/dino-0.4.3/main/data/im.dino.Dino.desktop --- old/dino-0.4.2/main/data/im.dino.Dino.desktop 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/main/data/im.dino.Dino.desktop 2023-07-09 19:00:00.000000000 +0200 @@ -11,3 +11,4 @@ Categories=GTK;Network;Chat;InstantMessaging; X-GNOME-UsesNotifications=true MimeType=x-scheme-handler/xmpp; +X-Purism-FormFactor=Workstation;Mobile; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/main/data/style.css new/dino-0.4.3/main/data/style.css --- old/dino-0.4.2/main/data/style.css 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/main/data/style.css 2023-07-09 19:00:00.000000000 +0200 @@ -392,17 +392,13 @@ text-shadow: 0 0 2px black; } -.dino-call-window .call-header-background { +.dino-call-window .participant-header-bar { background: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0)); border: 0; border-radius: 0; } -.dino-call-window .participant-header-bar button { - background: none; -} - -.dino-call-window .participant-header-bar button:hover { +.dino-call-window .participant-header-bar button:hover:not(.close) { background: rgba(255,255,255,0.15); border-color: rgba(255,255,255,0); box-shadow: none; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/main/src/ui/call_window/call_window.vala new/dino-0.4.3/main/src/ui/call_window/call_window.vala --- old/dino-0.4.2/main/src/ui/call_window/call_window.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/main/src/ui/call_window/call_window.vala 2023-07-09 19:00:00.000000000 +0200 @@ -22,7 +22,12 @@ private HashMap<string, ParticipantWidget> participant_widgets = new HashMap<string, ParticipantWidget>(); private ArrayList<string> participants = new ArrayList<string>(); + private EventControllerFocus this_focus_events = new EventControllerFocus(); + private GestureClick this_gesture_events = new GestureClick() { touch_only=true, propagation_phase=Gtk.PropagationPhase.CAPTURE }; private EventControllerMotion this_motion_events = new EventControllerMotion(); + private double latest_motion_x = -1; + private double latest_motion_y = -1; + private const double MOTION_RELEVANCE_THRESHOLD = 2; private int own_video_width = 150; private int own_video_height = 100; @@ -54,9 +59,20 @@ this.bind_property("controls-active", bottom_bar_revealer, "reveal-child", BindingFlags.SYNC_CREATE); ((Widget) this).add_controller(this_motion_events); - this_motion_events.motion.connect(reveal_control_elements); - this_motion_events.enter.connect(reveal_control_elements); - this_motion_events.leave.connect(reveal_control_elements); + this_motion_events.motion.connect((x, y) => { + if ((latest_motion_x - x).abs() <= MOTION_RELEVANCE_THRESHOLD && (latest_motion_y - y).abs() <= MOTION_RELEVANCE_THRESHOLD) return; + + latest_motion_x = x; + latest_motion_y = y; + reveal_control_elements(); + }); + + ((Widget) this).add_controller(this_focus_events); + this_focus_events.enter.connect(reveal_control_elements); + this_focus_events.leave.connect(reveal_control_elements); + + ((Widget) this).add_controller(this_gesture_events); + this_gesture_events.pressed.connect_after(reveal_control_elements); this.notify["default-width"].connect(reveal_control_elements); this.notify["default-height"].connect(reveal_control_elements); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/main/src/ui/call_window/participant_widget.vala new/dino-0.4.3/main/src/ui/call_window/participant_widget.vala --- old/dino-0.4.2/main/src/ui/call_window/participant_widget.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/main/src/ui/call_window/participant_widget.vala 2023-07-09 19:00:00.000000000 +0200 @@ -74,14 +74,11 @@ header_bar.show_title_buttons = is_highest_row; if (is_highest_row) { - header_bar.add_css_class("call-header-background"); Gtk.Settings? gtk_settings = Gtk.Settings.get_default(); if (gtk_settings != null) { string[] buttons = gtk_settings.gtk_decoration_layout.split(":"); header_bar.decoration_layout = (is_start ? buttons[0] : "") + ":" + (is_end && buttons.length == 2 ? buttons[1] : ""); } - } else { - header_bar.remove_css_class("call-header-background"); } reveal_or_hide_controls(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/main/src/ui/chat_input/chat_text_view.vala new/dino-0.4.3/main/src/ui/chat_input/chat_text_view.vala --- old/dino-0.4.2/main/src/ui/chat_input/chat_text_view.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/main/src/ui/chat_input/chat_text_view.vala 2023-07-09 19:00:00.000000000 +0200 @@ -94,8 +94,13 @@ } } - private bool on_text_input_key_press(uint keyval, uint keycode, Gdk.ModifierType state) { + private bool on_text_input_key_press(EventControllerKey controller, uint keyval, uint keycode, Gdk.ModifierType state) { if (keyval in new uint[]{ Key.Return, Key.KP_Enter }) { + // Allow the text view to process the event. Needed for IME. + if (text_view.im_context_filter_keypress(controller.get_current_event())) { + return true; + } + if ((state & ModifierType.SHIFT_MASK) > 0) { text_view.buffer.insert_at_cursor("\n", 1); } else if (text_view.buffer.text.strip() != "") { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/main/src/ui/chat_input/view.vala new/dino-0.4.3/main/src/ui/chat_input/view.vala --- old/dino-0.4.2/main/src/ui/chat_input/view.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/main/src/ui/chat_input/view.vala 2023-07-09 19:00:00.000000000 +0200 @@ -39,6 +39,8 @@ chooser.emoji_picked.connect((emoji) => { chat_text_view.text_view.buffer.insert_at_cursor(emoji, emoji.data.length); }); + chooser.closed.connect(do_focus); + emoji_button.set_popover(chooser); file_button.tooltip_text = Util.string_if_tooltips_active(_("Send a file")); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/main/src/ui/conversation_content_view/conversation_view.vala new/dino-0.4.3/main/src/ui/conversation_content_view/conversation_view.vala --- old/dino-0.4.2/main/src/ui/conversation_content_view/conversation_view.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/main/src/ui/conversation_content_view/conversation_view.vala 2023-07-09 19:00:00.000000000 +0200 @@ -95,7 +95,6 @@ EventControllerMotion main_wrap_motion_events = new EventControllerMotion(); main_wrap_box.add_controller(main_wrap_motion_events); main_wrap_motion_events.leave.connect(on_leave_notify_event); - main_wrap_motion_events.enter.connect(update_highlight); // The buttons of the overlaying message_menu_box may partially overlap the adjacent // conversation items. We connect to the main_event_box directly to avoid emitting // the pointer motion events as long as the pointer is above the message menu. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/plugins/ice/src/dtls_srtp.vala new/dino-0.4.3/plugins/ice/src/dtls_srtp.vala --- old/dino-0.4.2/plugins/ice/src/dtls_srtp.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/plugins/ice/src/dtls_srtp.vala 2023-07-09 19:00:00.000000000 +0200 @@ -38,7 +38,11 @@ } public uint8[]? process_incoming_data(uint component_id, uint8[] data) throws Crypto.Error { - if (srtp_session.has_decrypt) { + if (data[0] >= 128) { + if (!srtp_session.has_decrypt) { + debug("Received data before SRTP session is ready, dropping."); + return null; + } if (component_id == 1) { if (data.length >= 2 && data[1] >= 192 && data[1] < 224) { return srtp_session.decrypt_rtcp(data); @@ -46,9 +50,12 @@ return srtp_session.decrypt_rtp(data); } if (component_id == 2) return srtp_session.decrypt_rtcp(data); - } else if (component_id == 1) { + } + if (component_id == 1 && data.length >= 1 && (data[0] >= 20 && data[0] < 64)) { on_data_rec(data); + return null; } + debug("Dropping unknown data from component %u", component_id); return null; } @@ -79,7 +86,7 @@ err = private_key.generate(PKAlgorithm.ECDSA, 256); throw_if_error(err); - var start_time = new DateTime.now_local().add_days(1); + var start_time = new DateTime.now_local().add_days(-1); var end_time = start_time.add_days(2); X509.Certificate cert = X509.Certificate.create(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/plugins/rtp/src/device.vala new/dino-0.4.3/plugins/rtp/src/device.vala --- old/dino-0.4.2/plugins/rtp/src/device.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/plugins/rtp/src/device.vala 2023-07-09 19:00:00.000000000 +0200 @@ -215,7 +215,12 @@ } if (new_width == active_caps_width) return; int new_height = device_caps_height * new_width / device_caps_width; - Gst.Caps new_caps = new Gst.Caps.simple("video/x-raw", "width", typeof(int), new_width, "height", typeof(int), new_height, "framerate", typeof(Gst.Fraction), device_caps_framerate_num, device_caps_framerate_den, null); + Gst.Caps new_caps; + if (device_caps_framerate_den != 0) { + new_caps = new Gst.Caps.simple("video/x-raw", "width", typeof(int), new_width, "height", typeof(int), new_height, "framerate", typeof(Gst.Fraction), device_caps_framerate_num, device_caps_framerate_den, null); + } else { + new_caps = new Gst.Caps.simple("video/x-raw", "width", typeof(int), new_width, "height", typeof(int), new_height, null); + } double required_bitrate = get_target_bitrate(new_caps); debug("Changing resolution width from %d to %d (requires bitrate %f, current target is %u)", active_caps_width, new_width, required_bitrate, bitrate); if (bitrate < required_bitrate && new_width > active_caps_width) return; @@ -347,7 +352,7 @@ if (media == "audio") { return Gst.Caps.from_string("audio/x-raw,rate=48000,channels=1"); } else if (media == "video" && device.caps.get_size() > 0) { - int best_index = 0; + int best_index = -1; Value? best_fraction = null; int best_fps = 0; int best_width = 0; @@ -390,10 +395,25 @@ best_fraction = best_fraction_now; } } + if (best_index == -1) { + // No caps in first round, try without framerate + for (int i = 0; i < device.caps.get_size(); i++) { + unowned Gst.Structure? that = device.caps.get_structure(i); + if (!that.has_name("video/x-raw")) continue; + int width = 0, height = 0; + if (!that.has_field("width") || !that.get_int("width", out width)) continue; + if (!that.has_field("height") || !that.get_int("height", out height)) continue; + if (best_width < width || best_width == width && best_height < height) { + best_width = width; + best_height = height; + best_index = i; + } + } + } Gst.Caps res = caps_copy_nth(device.caps, best_index); unowned Gst.Structure? that = res.get_structure(0); - Value framerate = that.get_value("framerate"); - if (framerate.type() == typeof(Gst.ValueList)) { + Value? framerate = that.get_value("framerate"); + if (framerate != null && framerate.type() == typeof(Gst.ValueList) && best_fraction != null) { that.set_value("framerate", best_fraction); } debug("Selected caps %s", res.to_string()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/plugins/rtp/src/plugin.vala new/dino-0.4.3/plugins/rtp/src/plugin.vala --- old/dino-0.4.2/plugins/rtp/src/plugin.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/plugins/rtp/src/plugin.vala 2023-07-09 19:00:00.000000000 +0200 @@ -426,11 +426,11 @@ if (media == "video") { // Pick best FPS - int max_fps = 0; + int max_fps = -1; Device? max_fps_device = null; foreach (Device device in devices) { int fps = get_max_fps(device); - if (fps > max_fps) { + if (fps > max_fps || max_fps_device == null) { max_fps = fps; max_fps_device = device; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/plugins/rtp/src/stream.vala new/dino-0.4.3/plugins/rtp/src/stream.vala --- old/dino-0.4.2/plugins/rtp/src/stream.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/plugins/rtp/src/stream.vala 2023-07-09 19:00:00.000000000 +0200 @@ -102,6 +102,9 @@ send_rtp.drop = true; send_rtp.wait_on_eos = false; send_rtp.new_sample.connect(on_new_sample); +#if GST_1_20 + send_rtp.new_serialized_event.connect(on_new_event); +#endif send_rtp.connect("signal::eos", on_eos_static, this); pipe.add(send_rtp); @@ -294,6 +297,60 @@ } } + bool flip = false; + uint8 rotation = 0; +#if GST_1_20 + private bool on_new_event(Gst.App.Sink sink) { + if (sink == null || sink != send_rtp) { + return false; + } + Gst.MiniObject obj = sink.try_pull_object(0); + if (obj.type == typeof(Gst.Event)) { + unowned Gst.TagList tags; + if (((Gst.Event)obj).type == Gst.EventType.TAG) { + ((Gst.Event)obj).parse_tag(out tags); + Gst.Video.OrientationMethod orientation_method; + Gst.Video.Orientation.from_tag(tags, out orientation_method); + switch (orientation_method) { + case Gst.Video.OrientationMethod.IDENTITY: + case Gst.Video.OrientationMethod.VERT: + default: + rotation = 0; + break; + case Gst.Video.OrientationMethod.@90R: + case Gst.Video.OrientationMethod.UL_LR: + rotation = 1; + break; + case Gst.Video.OrientationMethod.@180: + case Gst.Video.OrientationMethod.HORIZ: + rotation = 2; + break; + case Gst.Video.OrientationMethod.@90L: + case Gst.Video.OrientationMethod.UR_LL: + rotation = 3; + break; + } + switch (orientation_method) { + case Gst.Video.OrientationMethod.IDENTITY: + case Gst.Video.OrientationMethod.@90R: + case Gst.Video.OrientationMethod.@180: + case Gst.Video.OrientationMethod.@90L: + default: + flip = false; + break; + case Gst.Video.OrientationMethod.VERT: + case Gst.Video.OrientationMethod.UL_LR: + case Gst.Video.OrientationMethod.HORIZ: + case Gst.Video.OrientationMethod.UR_LL: + flip = true; + break; + } + } + } + return false; + } +#endif + private Gst.FlowReturn on_new_sample(Gst.App.Sink sink) { if (sink == null) { debug("Sink is null"); @@ -323,6 +380,24 @@ #endif } +#if GST_1_20 + if (sink == send_rtp) { + Xmpp.Xep.JingleRtp.HeaderExtension? ext = header_extensions.first_match((it) => it.uri == "urn:3gpp:video-orientation"); + if (ext != null) { + buffer = (Gst.Buffer) buffer.make_writable(); + Gst.RTP.Buffer rtp_buffer; + if (Gst.RTP.Buffer.map(buffer, Gst.MapFlags.WRITE, out rtp_buffer)) { + uint8[] extension_data = new uint8[1]; + bool camera = false; + extension_data[0] = extension_data[0] | (rotation & 0x3); + if (flip) extension_data[0] = extension_data[0] | 0x4; + if (camera) extension_data[0] = extension_data[0] | 0x8; + rtp_buffer.add_extension_onebyte_header(ext.id, extension_data); + } + } + } +#endif + prepare_local_crypto(); uint8[] data; @@ -489,8 +564,8 @@ } } - private uint16 previous_video_orientation_degree = uint16.MAX; - public signal void video_orientation_changed(uint16 degree); + private uint16 previous_incoming_video_orientation_degree = uint16.MAX; + public signal void incoming_video_orientation_changed(uint16 degree); public override void on_recv_rtp_data(Bytes bytes) { if (rtcp_mux && bytes.length >= 2 && bytes.get(1) >= 192 && bytes.get(1) < 224) { @@ -545,9 +620,9 @@ case 2: rotation_degree = 180; break; case 3: rotation_degree = 270; break; } - if (rotation_degree != previous_video_orientation_degree) { - video_orientation_changed(rotation_degree); - previous_video_orientation_degree = rotation_degree; + if (rotation_degree != previous_incoming_video_orientation_degree) { + incoming_video_orientation_changed(rotation_degree); + previous_incoming_video_orientation_degree = rotation_degree; } } } @@ -723,7 +798,7 @@ private Gee.List<Gst.Element> outputs = new ArrayList<Gst.Element>(); private Gst.Element output_tee; private Gst.Element rotate; - private ulong video_orientation_changed_handler; + private ulong incoming_video_orientation_changed_handler; public VideoStream(Plugin plugin, Xmpp.Xep.Jingle.Content content) { base(plugin, content); @@ -731,7 +806,7 @@ } public override void create() { - video_orientation_changed_handler = video_orientation_changed.connect(on_video_orientation_changed); + incoming_video_orientation_changed_handler = incoming_video_orientation_changed.connect(on_video_orientation_changed); plugin.pause(); rotate = Gst.ElementFactory.make("videoflip", @"video_rotate_$rtpid"); pipe.add(rotate); @@ -780,7 +855,7 @@ output_tee.set_state(Gst.State.NULL); pipe.remove(output_tee); output_tee = null; - disconnect(video_orientation_changed_handler); + disconnect(incoming_video_orientation_changed_handler); } public override void add_output(Gst.Element element, Xmpp.Jid? participant) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/plugins/rtp/src/video_widget.vala new/dino-0.4.3/plugins/rtp/src/video_widget.vala --- old/dino-0.4.2/plugins/rtp/src/video_widget.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/plugins/rtp/src/video_widget.vala 2023-07-09 19:00:00.000000000 +0200 @@ -197,7 +197,11 @@ caps.get_structure(0).get_int("width", out width); caps.get_structure(0).get_int("height", out height); debug("Input resolution changed: %ix%i", width, height); - resolution_changed(width, height); + // Invoke signal on GTK main loop as recipients are likely to use it for doing GTK operations + Idle.add(() => { + resolution_changed(width, height); + return Source.REMOVE; + }); last_input_caps = caps; } @@ -227,9 +231,21 @@ if (connected_device == null) return; plugin.pause(); pipe.add(sink); +#if GST_1_20 + prepare = Gst.parse_bin_from_description(@"videoflip video-direction=auto name=video_widget_$(id)_orientation ! videoflip method=horizontal-flip name=video_widget_$(id)_flip ! videoconvert name=video_widget_$(id)_convert", true); +#else prepare = Gst.parse_bin_from_description(@"videoflip method=horizontal-flip name=video_widget_$(id)_flip ! videoconvert name=video_widget_$(id)_convert", true); +#endif prepare.name = @"video_widget_$(id)_prepare"; - prepare.get_static_pad("sink").notify["caps"].connect(input_caps_changed); +#if GST_1_20 + if (prepare is Gst.Bin) { + ((Gst.Bin) prepare).get_by_name(@"video_widget_$(id)_flip").get_static_pad("sink").notify["caps"].connect(input_caps_changed); + } else { +#endif + prepare.get_static_pad("sink").notify["caps"].connect(input_caps_changed); +#if GST_1_20 + } +#endif pipe.add(prepare); connected_device_element = connected_device.link_source(); connected_device_element.link(prepare); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/xmpp-vala/src/module/xep/0313_2_message_archive_management.vala new/dino-0.4.3/xmpp-vala/src/module/xep/0313_2_message_archive_management.vala --- old/dino-0.4.2/xmpp-vala/src/module/xep/0313_2_message_archive_management.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/xmpp-vala/src/module/xep/0313_2_message_archive_management.vala 2023-07-09 19:00:00.000000000 +0200 @@ -58,7 +58,7 @@ fields.add(field); } - return MessageArchiveManagement.create_base_query(stream, MessageArchiveManagement.NS_URI_2, mam_params.query_id, fields); + return MessageArchiveManagement.create_base_query(stream, mam_params.query_id, fields); } public async QueryResult query_archive(XmppStream stream, MamQueryParams mam_params, Cancellable? cancellable = null) { @@ -67,14 +67,14 @@ query_node.put_node(ResultSetManagement.create_set_rsm_node_before(mam_params.end_id)); } - return yield MessageArchiveManagement.query_archive(stream, MessageArchiveManagement.NS_URI_2, mam_params.mam_server, query_node, cancellable); + return yield MessageArchiveManagement.query_archive(stream, mam_params.mam_server, query_node, cancellable); } public async QueryResult page_through_results(XmppStream stream, MamQueryParams mam_params, QueryResult prev_result, Cancellable? cancellable = null) { var query_node = create_base_query(stream, mam_params); query_node.put_node(ResultSetManagement.create_set_rsm_node_before(prev_result.first)); - return yield MessageArchiveManagement.query_archive(stream, MessageArchiveManagement.NS_URI_2, mam_params.mam_server, query_node, cancellable); + return yield MessageArchiveManagement.query_archive(stream, mam_params.mam_server, query_node, cancellable); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dino-0.4.2/xmpp-vala/src/module/xep/0313_message_archive_management.vala new/dino-0.4.3/xmpp-vala/src/module/xep/0313_message_archive_management.vala --- old/dino-0.4.2/xmpp-vala/src/module/xep/0313_message_archive_management.vala 2023-03-23 19:00:00.000000000 +0100 +++ new/dino-0.4.3/xmpp-vala/src/module/xep/0313_message_archive_management.vala 2023-07-09 19:00:00.000000000 +0200 @@ -4,8 +4,6 @@ namespace Xmpp.MessageArchiveManagement { public const string NS_URI = "urn:xmpp:mam:2"; -public const string NS_URI_2 = "urn:xmpp:mam:2"; -public const string NS_URI_1 = "urn:xmpp:mam:1"; public class QueryResult { public bool error { get; set; default=false; } @@ -36,43 +34,33 @@ private async void query_availability(XmppStream stream) { Jid own_jid = stream.get_flag(Bind.Flag.IDENTITY).my_jid.bare_jid; - - bool ver_2_available = yield stream.get_module(ServiceDiscovery.Module.IDENTITY).has_entity_feature(stream, own_jid, NS_URI); - if (ver_2_available) { - stream.add_flag(new Flag(NS_URI)); + bool mam_available = yield stream.get_module(ServiceDiscovery.Module.IDENTITY).has_entity_feature(stream, own_jid, NS_URI); + if (mam_available) { feature_available(stream); - return; - } - - bool ver_1_available = yield stream.get_module(ServiceDiscovery.Module.IDENTITY).has_entity_feature(stream, own_jid, NS_URI_1); - if (ver_1_available) { - stream.add_flag(new Flag(NS_URI_1)); - feature_available(stream); - return; } } } - internal StanzaNode create_base_query(XmppStream stream, string ns, string? queryid, Gee.List<DataForms.DataForm.Field> fields) { + internal StanzaNode create_base_query(XmppStream stream, string? queryid, Gee.List<DataForms.DataForm.Field> fields) { DataForms.DataForm data_form = new DataForms.DataForm(); DataForms.DataForm.HiddenField form_type_field = new DataForms.DataForm.HiddenField() { var="FORM_TYPE" }; - form_type_field.set_value_string(NS_VER(stream)); + form_type_field.set_value_string(NS_URI); data_form.add_field(form_type_field); foreach (var field in fields) { data_form.add_field(field); } - StanzaNode query_node = new StanzaNode.build("query", NS_VER(stream)).add_self_xmlns().put_node(data_form.get_submit_node()); + StanzaNode query_node = new StanzaNode.build("query", NS_URI).add_self_xmlns().put_node(data_form.get_submit_node()); query_node.put_attribute("queryid", queryid); return query_node; } - internal async QueryResult query_archive(XmppStream stream, string ns, Jid? mam_server, StanzaNode query_node, Cancellable? cancellable = null) { + internal async QueryResult query_archive(XmppStream stream, Jid? mam_server, StanzaNode query_node, Cancellable? cancellable = null) { var res = new QueryResult(); - Flag? flag = stream.get_flag(Flag.IDENTITY); + Flag flag = Flag.get_flag(stream); string? query_id = query_node.get_attribute("queryid"); if (flag == null || query_id == null) { res.error = true; return res; } flag.active_query_ids.add(query_id); @@ -83,7 +71,7 @@ Iq.Stanza result_iq = yield stream.get_module(Iq.Module.IDENTITY).send_iq_async(stream, iq, Priority.LOW, cancellable); // Parse the response IQ into a QueryResult. - StanzaNode? fin_node = result_iq.stanza.get_subnode("fin", ns); + StanzaNode? fin_node = result_iq.stanza.get_subnode("fin", NS_URI); if (fin_node == null) { res.malformed = true; return res; } StanzaNode? rsm_node = fin_node.get_subnode("set", Xmpp.ResultSetManagement.NS_URI); @@ -92,7 +80,7 @@ res.first = rsm_node.get_deep_string_content("first"); res.last = rsm_node.get_deep_string_content("last"); if ((res.first == null) != (res.last == null)) { res.malformed = true; return res; } - res.complete = fin_node.get_attribute_bool("complete", false, ns); + res.complete = fin_node.get_attribute_bool("complete", false, NS_URI); Idle.add(() => { flag.active_query_ids.remove(query_id); @@ -110,15 +98,14 @@ public override string[] after_actions { get { return after_actions_const; } } public override async bool run(XmppStream stream, MessageStanza message) { - Flag? flag = stream.get_flag(Flag.IDENTITY); - if (flag == null) return false; + Flag flag = Flag.get_flag(stream); - StanzaNode? message_node = message.stanza.get_deep_subnode(NS_VER(stream) + ":result", StanzaForwarding.NS_URI + ":forwarded", Xmpp.NS_URI + ":message"); + StanzaNode? message_node = message.stanza.get_deep_subnode(NS_URI + ":result", StanzaForwarding.NS_URI + ":forwarded", Xmpp.NS_URI + ":message"); if (message_node != null) { - StanzaNode? forward_node = message.stanza.get_deep_subnode(NS_VER(stream) + ":result", StanzaForwarding.NS_URI + ":forwarded", DelayedDelivery.NS_URI + ":delay"); + StanzaNode? forward_node = message.stanza.get_deep_subnode(NS_URI + ":result", StanzaForwarding.NS_URI + ":forwarded", DelayedDelivery.NS_URI + ":delay"); DateTime? datetime = DelayedDelivery.get_time_for_node(forward_node); - string? mam_id = message.stanza.get_deep_attribute(NS_VER(stream) + ":result", NS_VER(stream) + ":id"); - string? query_id = message.stanza.get_deep_attribute(NS_VER(stream) + ":result", NS_VER(stream) + ":queryid"); + string? mam_id = message.stanza.get_deep_attribute(NS_URI + ":result", NS_URI + ":id"); + string? query_id = message.stanza.get_deep_attribute(NS_URI + ":result", NS_URI + ":queryid"); if (query_id == null) { warning("Received MAM message without queryid from %s, ignoring", message.from.to_string()); @@ -154,10 +141,14 @@ public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "message_archive_management"); public bool cought_up { get; set; default=false; } public Gee.Set<string> active_query_ids { get; set; default = new HashSet<string>(); } - public string ns_ver; - public Flag(string ns_ver) { - this.ns_ver = ns_ver; + public static Flag get_flag(XmppStream stream) { + Flag? flag = stream.get_flag(Flag.IDENTITY); + if (flag == null) { + flag = new Flag(); + stream.add_flag(flag); + } + return flag; } public override string get_ns() { return NS_URI; } @@ -185,8 +176,4 @@ public override string get_id() { return ID; } } -private static string NS_VER(XmppStream stream) { - return stream.get_flag(Flag.IDENTITY).ns_ver; -} - } \ No newline at end of file