Dont use callbacks when sending messages

Using a callback to display a sent message inside the ChatControl means
that all messages we send have to be issued from the GUI layer
(send_message()) if we want them to display in the ChatControl.

This replaces the callback and catches the stanza-message-outgoing event
after it was processed by the core.

This is easier to read/understand than dealing with callbacks and lets
the core issue messages without having to care if a ChatControl is open or not
This commit is contained in:
Philipp Hörist 2017-12-10 14:35:41 +01:00
parent 4cccdad5a1
commit 7815ce19a5
6 changed files with 59 additions and 53 deletions

View File

@ -236,6 +236,8 @@ class ChatControl(ChatControlBase):
self._nec_chatstate_received)
app.ged.register_event_handler('caps-received', ged.GUI1,
self._nec_caps_received)
app.ged.register_event_handler('stanza-message-outgoing', ged.OUT_POSTCORE,
self._message_sent)
# PluginSystem: adding GUI extension point for this ChatControl
# instance object
@ -811,6 +813,35 @@ class ChatControl(ChatControlBase):
app.plugin_manager.extension_point(
'encryption_dialog' + self.encryption, self)
def _message_sent(self, obj):
if obj.conn.name != self.account:
return
if obj.jid != self.contact.jid:
return
if not obj.message:
return
self.last_sent_msg = obj.stanza_id
id_ = obj.msg_iq.getID()
xep0184_id = None
if self.contact.jid != app.get_jid_from_account(self.account):
if app.config.get_per('accounts', self.account, 'request_receipt'):
xep0184_id = id_
if obj.label:
displaymarking = obj.label.getTag('displaymarking')
else:
displaymarking = None
if self.correcting:
self.correcting = False
gtkgui_helpers.remove_css_class(
self.msg_textview, 'msgcorrectingcolor')
self.print_conversation(obj.message, self.contact.jid, tim=obj.timestamp,
encrypted=obj.encrypted, xep0184_id=xep0184_id, xhtml=obj.xhtml,
displaymarking=displaymarking, msg_stanza_id=id_,
correct_id=obj.correct_id,
additional_data=obj.additional_data)
def send_message(self, message, keyID='', chatstate=None, xhtml=None,
process_commands=True, attention=False):
"""
@ -843,32 +874,9 @@ class ChatControl(ChatControlBase):
self._schedule_activity_timers()
def _on_sent(obj, msg_stanza, message, encrypted, xhtml, label):
id_ = msg_stanza.getID()
xep0184_id = None
if self.contact.jid != app.get_jid_from_account(self.account):
if app.config.get_per('accounts', self.account, 'request_receipt'):
xep0184_id = id_
if label:
displaymarking = label.getTag('displaymarking')
else:
displaymarking = None
if self.correcting:
self.correcting = False
gtkgui_helpers.remove_css_class(
self.msg_textview, 'msgcorrectingcolor')
self.print_conversation(message, self.contact.jid, tim=obj.timestamp,
encrypted=encrypted, xep0184_id=xep0184_id, xhtml=xhtml,
displaymarking=displaymarking, msg_stanza_id=id_,
correct_id=obj.correct_id,
additional_data=obj.additional_data)
ChatControlBase.send_message(self, message, keyID, type_='chat',
chatstate=chatstate_to_send, xhtml=xhtml, callback=_on_sent,
callback_args=[message, self.encryption, xhtml, self.get_seclabel()],
process_commands=process_commands,
attention=attention)
chatstate=chatstate_to_send, xhtml=xhtml,
process_commands=process_commands, attention=attention)
def on_cancel_session_negotiation(self):
msg = _('Session negotiation cancelled')
@ -1138,6 +1146,8 @@ class ChatControl(ChatControlBase):
self._nec_chatstate_received)
app.ged.remove_event_handler('caps-received', ged.GUI1,
self._nec_caps_received)
app.ged.remove_event_handler('stanza-message-outgoing', ged.OUT_POSTCORE,
self._message_sent)
self.unsubscribe_events()

View File

@ -742,17 +742,13 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
return label
def send_message(self, message, keyID='', type_='chat', chatstate=None,
resource=None, xhtml=None, callback=None, callback_args=None,
process_commands=True, attention=False):
resource=None, xhtml=None, process_commands=True, attention=False):
"""
Send the given message to the active tab. Doesn't return None if error
"""
if not message or message == '\n':
return None
if callback_args is None:
callback_args = []
if process_commands and self.process_as_command(message):
return
@ -766,11 +762,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
label = self.get_seclabel()
def _cb(obj, msg, cb, *cb_args):
self.last_sent_msg = obj.stanza_id
if cb:
cb(obj, msg, *cb_args)
if self.correcting and self.last_sent_msg:
correct_id = self.last_sent_msg
else:
@ -780,8 +771,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
account=self.account, jid=self.contact.jid, message=message,
keyID=keyID, type_=type_, chatstate=chatstate,
resource=resource, user_nick=self.user_nick, xhtml=xhtml,
label=label, callback=_cb, callback_args=[callback] + callback_args,
control=self, attention=attention, correct_id=correct_id,
label=label, control=self, attention=attention, correct_id=correct_id,
automatic_message=False, encryption=self.encryption))
# Record the history of sent messages

View File

@ -2061,6 +2061,9 @@ class Connection(CommonConnection, ConnectionHandlers):
if encryption:
app.plugin_manager.extension_point(
'encrypt' + encryption, self, obj, self.send_message)
if not obj.encrypted:
# Dont propagate event
return True
else:
self.send_message(obj)
@ -2072,8 +2075,6 @@ class Connection(CommonConnection, ConnectionHandlers):
None, conn=self, jid=obj.jid, message=obj.message, keyID=obj.keyID,
chatstate=obj.chatstate, automatic_message=obj.automatic_message,
stanza_id=obj.stanza_id, additional_data=obj.additional_data))
if obj.callback:
obj.callback(obj, obj.msg_iq, *obj.callback_args)
if isinstance(obj.jid, list):
for j in obj.jid:
@ -2702,8 +2703,6 @@ class Connection(CommonConnection, ConnectionHandlers):
None, conn=self, jid=obj.jid, message=obj.message, keyID=None,
chatstate=None, automatic_message=obj.automatic_message,
stanza_id=obj.stanza_id, additional_data=obj.additional_data))
if obj.callback:
obj.callback(obj)
def send_gc_subject(self, jid, subject):
if not app.account_is_connected(self.name):

View File

@ -2845,6 +2845,7 @@ class MessageOutgoingEvent(nec.NetworkOutgoingEvent):
self.correct_id = None
self.automatic_message = True
self.encryption = ''
self.encrypted = False
def get_full_jid(self):
if self.resource:

View File

@ -342,8 +342,6 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
jid=obj.jid, message=obj.message, keyID=obj.keyID,
automatic_message=obj.automatic_message, chatstate=None,
stanza_id=stanza_id))
if obj.callback:
obj.callback(obj.msg_iq, *obj.callback_args)
self.log_message(obj, obj.jid)
@ -352,6 +350,8 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
app.nec.push_incoming_event(MessageErrorEvent(None, conn=self,
fjid=obj.jid, error_code=-1, error_msg=reason, msg=None,
time_=None, session=obj.session))
# Dont propagate event
return True
ret = self.connection.send(
obj.msg_iq, obj.message is not None,
@ -363,6 +363,8 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
fjid=obj.jid, error_code=-1, error_msg=_(
'Contact is offline. Your message could not be sent.'),
msg=None, time_=None, session=obj.session))
# Dont propagate event
return True
def send_stanza(self, stanza):
# send a stanza untouched

View File

@ -493,6 +493,8 @@ class GroupchatControl(ChatControlBase):
self._nec_signed_in)
app.ged.register_event_handler('decrypted-message-received', ged.GUI2,
self._nec_decrypted_message_received)
app.ged.register_event_handler('gc-stanza-message-outgoing', ged.OUT_POSTCORE,
self._message_sent)
app.gc_connected[self.account][self.room_jid] = False
# disable win, we are not connected yet
ChatControlBase.got_disconnected(self)
@ -1985,6 +1987,15 @@ class GroupchatControl(ChatControlBase):
if self.model.iter_n_children(parent_iter) == 0:
self.model.remove(parent_iter)
def _message_sent(self, obj):
# we'll save sent message text when we'll receive it in
# _nec_gc_message_received
self.last_sent_msg = obj.stanza_id
if self.correcting:
self.correcting = False
gtkgui_helpers.remove_css_class(
self.msg_textview, 'msgcorrectingcolor')
def send_message(self, message, xhtml=None, process_commands=True):
"""
Call this function to send our message
@ -2011,15 +2022,6 @@ class GroupchatControl(ChatControlBase):
if message != '' or message != '\n':
self.save_message(message, 'sent')
def _cb(obj):
# we'll save sent message text when we'll receive it in
# _nec_gc_message_received
self.last_sent_msg = obj.stanza_id
if self.correcting:
self.correcting = False
gtkgui_helpers.remove_css_class(
self.msg_textview, 'msgcorrectingcolor')
if self.correcting and self.last_sent_msg:
correct_id = self.last_sent_msg
else:
@ -2027,7 +2029,7 @@ class GroupchatControl(ChatControlBase):
# Send the message
app.nec.push_outgoing_event(GcMessageOutgoingEvent(None,
account=self.account, jid=self.room_jid, message=message,
xhtml=xhtml, label=label, callback=_cb, correct_id=correct_id,
xhtml=xhtml, label=label, correct_id=correct_id,
automatic_message=False))
self.msg_textview.get_buffer().set_text('')
self.msg_textview.grab_focus()
@ -2148,6 +2150,8 @@ class GroupchatControl(ChatControlBase):
self._nec_signed_in)
app.ged.remove_event_handler('decrypted-message-received', ged.GUI2,
self._nec_decrypted_message_received)
app.ged.remove_event_handler('gc-stanza-message-outgoing', ged.OUT_POSTCORE,
self._message_sent)
if self.room_jid in app.gc_connected[self.account] and \
app.gc_connected[self.account][self.room_jid]: