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) self._nec_chatstate_received)
app.ged.register_event_handler('caps-received', ged.GUI1, app.ged.register_event_handler('caps-received', ged.GUI1,
self._nec_caps_received) 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 # PluginSystem: adding GUI extension point for this ChatControl
# instance object # instance object
@ -811,6 +813,35 @@ class ChatControl(ChatControlBase):
app.plugin_manager.extension_point( app.plugin_manager.extension_point(
'encryption_dialog' + self.encryption, self) '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, def send_message(self, message, keyID='', chatstate=None, xhtml=None,
process_commands=True, attention=False): process_commands=True, attention=False):
""" """
@ -843,32 +874,9 @@ class ChatControl(ChatControlBase):
self._schedule_activity_timers() 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', ChatControlBase.send_message(self, message, keyID, type_='chat',
chatstate=chatstate_to_send, xhtml=xhtml, callback=_on_sent, chatstate=chatstate_to_send, xhtml=xhtml,
callback_args=[message, self.encryption, xhtml, self.get_seclabel()], process_commands=process_commands, attention=attention)
process_commands=process_commands,
attention=attention)
def on_cancel_session_negotiation(self): def on_cancel_session_negotiation(self):
msg = _('Session negotiation cancelled') msg = _('Session negotiation cancelled')
@ -1138,6 +1146,8 @@ class ChatControl(ChatControlBase):
self._nec_chatstate_received) self._nec_chatstate_received)
app.ged.remove_event_handler('caps-received', ged.GUI1, app.ged.remove_event_handler('caps-received', ged.GUI1,
self._nec_caps_received) self._nec_caps_received)
app.ged.remove_event_handler('stanza-message-outgoing', ged.OUT_POSTCORE,
self._message_sent)
self.unsubscribe_events() self.unsubscribe_events()

View File

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

View File

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

View File

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

View File

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

View File

@ -493,6 +493,8 @@ class GroupchatControl(ChatControlBase):
self._nec_signed_in) self._nec_signed_in)
app.ged.register_event_handler('decrypted-message-received', ged.GUI2, app.ged.register_event_handler('decrypted-message-received', ged.GUI2,
self._nec_decrypted_message_received) 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 app.gc_connected[self.account][self.room_jid] = False
# disable win, we are not connected yet # disable win, we are not connected yet
ChatControlBase.got_disconnected(self) ChatControlBase.got_disconnected(self)
@ -1985,6 +1987,15 @@ class GroupchatControl(ChatControlBase):
if self.model.iter_n_children(parent_iter) == 0: if self.model.iter_n_children(parent_iter) == 0:
self.model.remove(parent_iter) 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): def send_message(self, message, xhtml=None, process_commands=True):
""" """
Call this function to send our message Call this function to send our message
@ -2011,15 +2022,6 @@ class GroupchatControl(ChatControlBase):
if message != '' or message != '\n': if message != '' or message != '\n':
self.save_message(message, 'sent') 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: if self.correcting and self.last_sent_msg:
correct_id = self.last_sent_msg correct_id = self.last_sent_msg
else: else:
@ -2027,7 +2029,7 @@ class GroupchatControl(ChatControlBase):
# Send the message # Send the message
app.nec.push_outgoing_event(GcMessageOutgoingEvent(None, app.nec.push_outgoing_event(GcMessageOutgoingEvent(None,
account=self.account, jid=self.room_jid, message=message, 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)) automatic_message=False))
self.msg_textview.get_buffer().set_text('') self.msg_textview.get_buffer().set_text('')
self.msg_textview.grab_focus() self.msg_textview.grab_focus()
@ -2148,6 +2150,8 @@ class GroupchatControl(ChatControlBase):
self._nec_signed_in) self._nec_signed_in)
app.ged.remove_event_handler('decrypted-message-received', ged.GUI2, app.ged.remove_event_handler('decrypted-message-received', ged.GUI2,
self._nec_decrypted_message_received) 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 \ if self.room_jid in app.gc_connected[self.account] and \
app.gc_connected[self.account][self.room_jid]: app.gc_connected[self.account][self.room_jid]: