follow chat in tabs more easily. Don't open as many chattabs as there are lowe priority chats. Fixes #5227
This commit is contained in:
parent
9d12023ec5
commit
31bfc4969a
8 changed files with 58 additions and 70 deletions
|
@ -868,7 +868,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
||||||
keyID=keyID, type_=type_, chatstate=chatstate, msg_id=msg_id,
|
keyID=keyID, type_=type_, chatstate=chatstate, msg_id=msg_id,
|
||||||
composing_xep=composing_xep, resource=resource,
|
composing_xep=composing_xep, resource=resource,
|
||||||
user_nick=self.user_nick, xhtml=xhtml, label=label,
|
user_nick=self.user_nick, xhtml=xhtml, label=label,
|
||||||
callback=callback, callback_args= callback_args))
|
callback=callback, callback_args=callback_args, control=self))
|
||||||
|
|
||||||
# Record the history of sent messages
|
# Record the history of sent messages
|
||||||
self.save_message(message, 'sent')
|
self.save_message(message, 'sent')
|
||||||
|
@ -2631,13 +2631,15 @@ class ChatControl(ChatControlBase):
|
||||||
if contact.our_chatstate == 'inactive' and state == 'composing':
|
if contact.our_chatstate == 'inactive' and state == 'composing':
|
||||||
# go active before
|
# go active before
|
||||||
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
|
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
|
||||||
account=self.account, jid=self.contact.jid, chatstate='active'))
|
account=self.account, jid=self.contact.jid, chatstate='active',
|
||||||
|
control=self))
|
||||||
contact.our_chatstate = 'active'
|
contact.our_chatstate = 'active'
|
||||||
self.reset_kbd_mouse_timeout_vars()
|
self.reset_kbd_mouse_timeout_vars()
|
||||||
|
|
||||||
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
|
gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
|
||||||
account=self.account, jid=self.contact.jid, chatstate=state,
|
account=self.account, jid=self.contact.jid, chatstate=state,
|
||||||
msg_id=contact.msg_id, composing_xep=contact.composing_xep))
|
msg_id=contact.msg_id, composing_xep=contact.composing_xep,
|
||||||
|
control=self))
|
||||||
|
|
||||||
contact.our_chatstate = state
|
contact.our_chatstate = state
|
||||||
if contact.our_chatstate == 'active':
|
if contact.our_chatstate == 'active':
|
||||||
|
|
|
@ -926,23 +926,6 @@ class ConnectionHandlersBase:
|
||||||
continue
|
continue
|
||||||
if sess.control:
|
if sess.control:
|
||||||
sess.control.no_autonegotiation = False
|
sess.control.no_autonegotiation = False
|
||||||
if sess.enable_encryption:
|
|
||||||
sess.terminate_e2e()
|
|
||||||
self.delete_session(jid, sess.thread_id)
|
|
||||||
|
|
||||||
if obj.ptype == 'unavailable':
|
|
||||||
for jid in (obj.jid, obj.fjid):
|
|
||||||
if jid not in self.sessions:
|
|
||||||
continue
|
|
||||||
# automatically terminate sessions that they haven't sent a
|
|
||||||
# thread ID in, only if other part support thread ID
|
|
||||||
for sess in self.sessions[jid].values():
|
|
||||||
if not sess.received_thread_id:
|
|
||||||
contact = gajim.contacts.get_contact(self.name, jid)
|
|
||||||
if contact and (contact.supports(xmpp.NS_SSN) or \
|
|
||||||
contact.supports(xmpp.NS_ESESSION)):
|
|
||||||
sess.terminate()
|
|
||||||
del self.sessions[jid][sess.thread_id]
|
|
||||||
|
|
||||||
if gajim.config.get('log_contact_status_changes') and \
|
if gajim.config.get('log_contact_status_changes') and \
|
||||||
gajim.config.should_log(self.name, obj.jid):
|
gajim.config.should_log(self.name, obj.jid):
|
||||||
|
|
|
@ -2187,6 +2187,7 @@ class MessageOutgoingEvent(nec.NetworkIncomingEvent):
|
||||||
self.callback_args = []
|
self.callback_args = []
|
||||||
self.now = False
|
self.now = False
|
||||||
self.is_loggable = True
|
self.is_loggable = True
|
||||||
|
self.control = None
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -58,7 +58,7 @@ class StanzaSession(object):
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
self.jid = jid
|
self.jid = jid
|
||||||
self.type = type_
|
self.type = type_
|
||||||
self.resource = None
|
self.resource = jid.getResource()
|
||||||
|
|
||||||
if thread_id:
|
if thread_id:
|
||||||
self.received_thread_id = True
|
self.received_thread_id = True
|
||||||
|
|
|
@ -358,15 +358,9 @@ class Interface:
|
||||||
highest = gajim.contacts.get_contact_with_highest_priority(account, jid)
|
highest = gajim.contacts.get_contact_with_highest_priority(account, jid)
|
||||||
is_highest = (highest and highest.resource == resource)
|
is_highest = (highest and highest.resource == resource)
|
||||||
|
|
||||||
# disconnect the session from the ctrl if the highest resource has
|
ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||||
# changed
|
if ctrl and ctrl.session and ctrl.session.resource == resource:
|
||||||
if (obj.was_highest and not is_highest) or \
|
ctrl.remove_session(ctrl.session)
|
||||||
(not obj.was_highest and is_highest):
|
|
||||||
ctrl = self.msg_win_mgr.get_control(jid, account)
|
|
||||||
if ctrl:
|
|
||||||
ctrl.no_autonegotiation = False
|
|
||||||
ctrl.set_session(None)
|
|
||||||
ctrl.contact = highest
|
|
||||||
|
|
||||||
def handle_event_msgerror(self, obj):
|
def handle_event_msgerror(self, obj):
|
||||||
#'MSGERROR' (account, (jid, error_code, error_msg, msg, time[session]))
|
#'MSGERROR' (account, (jid, error_code, error_msg, msg, time[session]))
|
||||||
|
|
|
@ -46,7 +46,8 @@ class MessageControl(object):
|
||||||
MessageWindow
|
MessageWindow
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, type_id, parent_win, widget_name, contact, account, resource = None):
|
def __init__(self, type_id, parent_win, widget_name, contact, account,
|
||||||
|
resource=None):
|
||||||
# dict { cb id : widget}
|
# dict { cb id : widget}
|
||||||
# keep all registered callbacks of widgets, created by self.xml
|
# keep all registered callbacks of widgets, created by self.xml
|
||||||
self.handlers = {}
|
self.handlers = {}
|
||||||
|
@ -59,6 +60,7 @@ class MessageControl(object):
|
||||||
self.resource = resource
|
self.resource = resource
|
||||||
|
|
||||||
self.session = None
|
self.session = None
|
||||||
|
self.other_sessions = []
|
||||||
|
|
||||||
gajim.last_message_time[self.account][self.get_full_jid()] = 0
|
gajim.last_message_time[self.account][self.get_full_jid()] = 0
|
||||||
|
|
||||||
|
@ -201,15 +203,15 @@ class MessageControl(object):
|
||||||
|
|
||||||
if oldsession:
|
if oldsession:
|
||||||
oldsession.control = None
|
oldsession.control = None
|
||||||
|
self.other_sessions.append(oldsession)
|
||||||
|
|
||||||
jid = self.contact.jid
|
if self.session in self.other_sessions:
|
||||||
if self.resource:
|
self.other_sessions.remove(self.session)
|
||||||
jid += '/' + self.resource
|
|
||||||
|
|
||||||
crypto_changed = bool(session and isinstance(session,
|
crypto_changed = bool(session and isinstance(session,
|
||||||
EncryptedStanzaSession) and session.enable_encryption) != \
|
EncryptedStanzaSession) and session.enable_encryption) != \
|
||||||
bool(oldsession and isinstance(oldsession,
|
bool(oldsession and isinstance(oldsession, EncryptedStanzaSession) \
|
||||||
EncryptedStanzaSession) and oldsession.enable_encryption)
|
and oldsession.enable_encryption)
|
||||||
|
|
||||||
archiving_changed = bool(session and isinstance(session,
|
archiving_changed = bool(session and isinstance(session,
|
||||||
ArchivingStanzaSession) and session.archiving) != \
|
ArchivingStanzaSession) and session.archiving) != \
|
||||||
|
@ -219,12 +221,21 @@ class MessageControl(object):
|
||||||
if crypto_changed or archiving_changed:
|
if crypto_changed or archiving_changed:
|
||||||
self.print_session_details()
|
self.print_session_details()
|
||||||
|
|
||||||
|
def remove_session(self, session):
|
||||||
|
if session != self.session:
|
||||||
|
return
|
||||||
|
last_session = None
|
||||||
|
if self.other_sessions:
|
||||||
|
last_session = self.other_sessions.pop(0)
|
||||||
|
if session not in self.other_sessions:
|
||||||
|
self.other_sessions.append(session)
|
||||||
|
if last_session:
|
||||||
|
self.session = last_session
|
||||||
|
|
||||||
def _nec_message_outgoing(self, obj):
|
def _nec_message_outgoing(self, obj):
|
||||||
# Send the given message to the active tab.
|
# Send the given message to the active tab.
|
||||||
# Doesn't return None if error
|
# Doesn't return None if error
|
||||||
if obj.account != self.account:
|
if obj.control != self:
|
||||||
return
|
|
||||||
if self.contact.jid != obj.jid:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
obj.message = helpers.remove_invalid_xml_chars(obj.message)
|
obj.message = helpers.remove_invalid_xml_chars(obj.message)
|
||||||
|
|
|
@ -1087,6 +1087,26 @@ class MessageWindowMgr(gobject.GObject):
|
||||||
return win.get_control(jid, acct)
|
return win.get_control(jid, acct)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def search_control(self, jid, account, resource=None):
|
||||||
|
"""
|
||||||
|
Search windows with this policy:
|
||||||
|
1. try to find already opened tab for resource
|
||||||
|
2. find the tab for this jid with ctrl.resource not set
|
||||||
|
3. there is none
|
||||||
|
"""
|
||||||
|
fjid = jid
|
||||||
|
if resource:
|
||||||
|
jid += '/' + resource
|
||||||
|
ctrl = self.get_control(fjid, account)
|
||||||
|
if ctrl:
|
||||||
|
return ctrl
|
||||||
|
win = self.get_window(jid, account)
|
||||||
|
if win:
|
||||||
|
ctrl = win.get_control(jid, account)
|
||||||
|
if not ctrl.resource:
|
||||||
|
return ctrl
|
||||||
|
return None
|
||||||
|
|
||||||
def get_gc_control(self, jid, acct):
|
def get_gc_control(self, jid, acct):
|
||||||
"""
|
"""
|
||||||
Same as get_control. Was briefly required, is not any more. May be useful
|
Same as get_control. Was briefly required, is not any more. May be useful
|
||||||
|
|
|
@ -155,14 +155,9 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
obj.resource == highest_contact.resource or highest_contact.show ==\
|
obj.resource == highest_contact.resource or highest_contact.show ==\
|
||||||
'offline'
|
'offline'
|
||||||
|
|
||||||
if not pm and is_highest:
|
|
||||||
jid_of_control = obj.jid
|
|
||||||
else:
|
|
||||||
jid_of_control = obj.fjid
|
|
||||||
|
|
||||||
if not self.control:
|
if not self.control:
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(jid_of_control,
|
ctrl = gajim.interface.msg_win_mgr.search_control(obj.jid,
|
||||||
self.conn.name)
|
obj.conn.name, obj.resource)
|
||||||
if ctrl:
|
if ctrl:
|
||||||
self.control = ctrl
|
self.control = ctrl
|
||||||
self.control.set_session(self)
|
self.control.set_session(self)
|
||||||
|
@ -183,8 +178,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
contact = None
|
contact = None
|
||||||
jid = obj.jid
|
jid = obj.jid
|
||||||
resource = obj.resource
|
resource = obj.resource
|
||||||
# if chat window will be for specific resource
|
|
||||||
resource_for_chat = resource
|
|
||||||
|
|
||||||
fjid = jid
|
fjid = jid
|
||||||
|
|
||||||
|
@ -211,7 +204,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
else:
|
else:
|
||||||
# Default to highest prio
|
# Default to highest prio
|
||||||
fjid = jid
|
fjid = jid
|
||||||
resource_for_chat = None
|
|
||||||
contact = highest_contact
|
contact = highest_contact
|
||||||
|
|
||||||
if not contact:
|
if not contact:
|
||||||
|
@ -220,21 +212,15 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
obj.conn.name, jid, obj.user_nick)
|
obj.conn.name, jid, obj.user_nick)
|
||||||
|
|
||||||
if not self.control:
|
if not self.control:
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(fjid, self.conn.name)
|
ctrl = gajim.interface.msg_win_mgr.search_control(obj.jid,
|
||||||
|
obj.conn.name, obj.resource)
|
||||||
if ctrl:
|
if ctrl:
|
||||||
self.control = ctrl
|
self.control = ctrl
|
||||||
self.control.set_session(self)
|
self.control.set_session(self)
|
||||||
else:
|
else:
|
||||||
# if no control exists and message comes from highest prio,
|
fjid = jid
|
||||||
# the new control shouldn't have a resource
|
|
||||||
if highest_contact and contact.resource == \
|
|
||||||
highest_contact.resource and jid != gajim.get_jid_from_account(
|
|
||||||
self.conn.name):
|
|
||||||
fjid = jid
|
|
||||||
resource_for_chat = None
|
|
||||||
|
|
||||||
obj.popup = helpers.allow_popup_window(self.conn.name)
|
obj.popup = helpers.allow_popup_window(self.conn.name)
|
||||||
obj.resource_for_chat = resource_for_chat
|
|
||||||
|
|
||||||
type_ = 'chat'
|
type_ = 'chat'
|
||||||
event_type = 'message_received'
|
event_type = 'message_received'
|
||||||
|
@ -268,9 +254,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
Display the message or show notification in the roster
|
Display the message or show notification in the roster
|
||||||
"""
|
"""
|
||||||
contact = None
|
contact = None
|
||||||
# if chat window will be for specific resource
|
|
||||||
resource_for_chat = resource
|
|
||||||
|
|
||||||
fjid = jid
|
fjid = jid
|
||||||
|
|
||||||
# Try to catch the contact with correct resource
|
# Try to catch the contact with correct resource
|
||||||
|
@ -298,7 +281,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
else:
|
else:
|
||||||
# Default to highest prio
|
# Default to highest prio
|
||||||
fjid = jid
|
fjid = jid
|
||||||
resource_for_chat = None
|
|
||||||
contact = highest_contact
|
contact = highest_contact
|
||||||
|
|
||||||
if not contact:
|
if not contact:
|
||||||
|
@ -312,12 +294,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
self.control = ctrl
|
self.control = ctrl
|
||||||
self.control.set_session(self)
|
self.control.set_session(self)
|
||||||
else:
|
else:
|
||||||
# if no control exists and message comes from highest prio, the new
|
fjid = jid
|
||||||
# control shouldn't have a resource
|
|
||||||
if highest_contact and contact.resource == highest_contact.resource\
|
|
||||||
and not jid == gajim.get_jid_from_account(self.conn.name):
|
|
||||||
fjid = jid
|
|
||||||
resource_for_chat = None
|
|
||||||
|
|
||||||
# Do we have a queue?
|
# Do we have a queue?
|
||||||
no_queue = len(gajim.events.get_events(self.conn.name, fjid)) == 0
|
no_queue = len(gajim.events.get_events(self.conn.name, fjid)) == 0
|
||||||
|
@ -367,7 +344,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
||||||
if popup:
|
if popup:
|
||||||
if not self.control:
|
if not self.control:
|
||||||
self.control = gajim.interface.new_chat(contact,
|
self.control = gajim.interface.new_chat(contact,
|
||||||
self.conn.name, resource=resource_for_chat, session=self)
|
self.conn.name, session=self)
|
||||||
|
|
||||||
if len(gajim.events.get_events(self.conn.name, fjid)):
|
if len(gajim.events.get_events(self.conn.name, fjid)):
|
||||||
self.control.read_queue()
|
self.control.read_queue()
|
||||||
|
|
Loading…
Add table
Reference in a new issue