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,
 | 
			
		||||
            composing_xep=composing_xep, resource=resource,
 | 
			
		||||
            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
 | 
			
		||||
        self.save_message(message, 'sent')
 | 
			
		||||
| 
						 | 
				
			
			@ -2631,13 +2631,15 @@ class ChatControl(ChatControlBase):
 | 
			
		|||
        if contact.our_chatstate == 'inactive' and state == 'composing':
 | 
			
		||||
            # go active before
 | 
			
		||||
            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'
 | 
			
		||||
            self.reset_kbd_mouse_timeout_vars()
 | 
			
		||||
 | 
			
		||||
        gajim.nec.push_outgoing_event(MessageOutgoingEvent(None,
 | 
			
		||||
            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
 | 
			
		||||
        if contact.our_chatstate == 'active':
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -926,23 +926,6 @@ class ConnectionHandlersBase:
 | 
			
		|||
                    continue
 | 
			
		||||
                if sess.control:
 | 
			
		||||
                    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 \
 | 
			
		||||
        gajim.config.should_log(self.name, obj.jid):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2187,6 +2187,7 @@ class MessageOutgoingEvent(nec.NetworkIncomingEvent):
 | 
			
		|||
        self.callback_args = []
 | 
			
		||||
        self.now = False
 | 
			
		||||
        self.is_loggable = True
 | 
			
		||||
        self.control = None
 | 
			
		||||
 | 
			
		||||
    def generate(self):
 | 
			
		||||
        return True
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ class StanzaSession(object):
 | 
			
		|||
        self.conn = conn
 | 
			
		||||
        self.jid = jid
 | 
			
		||||
        self.type = type_
 | 
			
		||||
        self.resource = None
 | 
			
		||||
        self.resource = jid.getResource()
 | 
			
		||||
 | 
			
		||||
        if thread_id:
 | 
			
		||||
            self.received_thread_id = True
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -358,15 +358,9 @@ class Interface:
 | 
			
		|||
        highest = gajim.contacts.get_contact_with_highest_priority(account, jid)
 | 
			
		||||
        is_highest = (highest and highest.resource == resource)
 | 
			
		||||
 | 
			
		||||
        # disconnect the session from the ctrl if the highest resource has
 | 
			
		||||
        # changed
 | 
			
		||||
        if (obj.was_highest and not is_highest) or \
 | 
			
		||||
        (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
 | 
			
		||||
        ctrl = self.msg_win_mgr.get_control(jid, account)
 | 
			
		||||
        if ctrl and ctrl.session and ctrl.session.resource == resource:
 | 
			
		||||
            ctrl.remove_session(ctrl.session)
 | 
			
		||||
 | 
			
		||||
    def handle_event_msgerror(self, obj):
 | 
			
		||||
        #'MSGERROR' (account, (jid, error_code, error_msg, msg, time[session]))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,8 @@ class MessageControl(object):
 | 
			
		|||
    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}
 | 
			
		||||
        # keep all registered callbacks of widgets, created by self.xml
 | 
			
		||||
        self.handlers = {}
 | 
			
		||||
| 
						 | 
				
			
			@ -59,6 +60,7 @@ class MessageControl(object):
 | 
			
		|||
        self.resource = resource
 | 
			
		||||
 | 
			
		||||
        self.session = None
 | 
			
		||||
        self.other_sessions = []
 | 
			
		||||
 | 
			
		||||
        gajim.last_message_time[self.account][self.get_full_jid()] = 0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -201,15 +203,15 @@ class MessageControl(object):
 | 
			
		|||
 | 
			
		||||
        if oldsession:
 | 
			
		||||
            oldsession.control = None
 | 
			
		||||
            self.other_sessions.append(oldsession)
 | 
			
		||||
 | 
			
		||||
            jid = self.contact.jid
 | 
			
		||||
            if self.resource:
 | 
			
		||||
                jid += '/' + self.resource
 | 
			
		||||
        if self.session in self.other_sessions:
 | 
			
		||||
            self.other_sessions.remove(self.session)
 | 
			
		||||
 | 
			
		||||
        crypto_changed = bool(session and isinstance(session,
 | 
			
		||||
                EncryptedStanzaSession) and session.enable_encryption) != \
 | 
			
		||||
                bool(oldsession and isinstance(oldsession,
 | 
			
		||||
                EncryptedStanzaSession) and oldsession.enable_encryption)
 | 
			
		||||
            EncryptedStanzaSession) and session.enable_encryption) != \
 | 
			
		||||
            bool(oldsession and isinstance(oldsession, EncryptedStanzaSession) \
 | 
			
		||||
            and oldsession.enable_encryption)
 | 
			
		||||
 | 
			
		||||
        archiving_changed = bool(session and isinstance(session,
 | 
			
		||||
            ArchivingStanzaSession) and session.archiving) != \
 | 
			
		||||
| 
						 | 
				
			
			@ -219,12 +221,21 @@ class MessageControl(object):
 | 
			
		|||
        if crypto_changed or archiving_changed:
 | 
			
		||||
            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):
 | 
			
		||||
        # Send the given message to the active tab.
 | 
			
		||||
        # Doesn't return None if error
 | 
			
		||||
        if obj.account != self.account:
 | 
			
		||||
            return
 | 
			
		||||
        if self.contact.jid != obj.jid:
 | 
			
		||||
        if obj.control != self:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        obj.message = helpers.remove_invalid_xml_chars(obj.message)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1087,6 +1087,26 @@ class MessageWindowMgr(gobject.GObject):
 | 
			
		|||
            return win.get_control(jid, acct)
 | 
			
		||||
        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):
 | 
			
		||||
        """
 | 
			
		||||
        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 ==\
 | 
			
		||||
            'offline'
 | 
			
		||||
 | 
			
		||||
        if not pm and is_highest:
 | 
			
		||||
            jid_of_control = obj.jid
 | 
			
		||||
        else:
 | 
			
		||||
            jid_of_control = obj.fjid
 | 
			
		||||
 | 
			
		||||
        if not self.control:
 | 
			
		||||
            ctrl = gajim.interface.msg_win_mgr.get_control(jid_of_control,
 | 
			
		||||
                self.conn.name)
 | 
			
		||||
            ctrl = gajim.interface.msg_win_mgr.search_control(obj.jid,
 | 
			
		||||
                obj.conn.name, obj.resource)
 | 
			
		||||
            if ctrl:
 | 
			
		||||
                self.control = ctrl
 | 
			
		||||
                self.control.set_session(self)
 | 
			
		||||
| 
						 | 
				
			
			@ -183,8 +178,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
 | 
			
		|||
        contact = None
 | 
			
		||||
        jid = obj.jid
 | 
			
		||||
        resource = obj.resource
 | 
			
		||||
        # if chat window will be for specific resource
 | 
			
		||||
        resource_for_chat = resource
 | 
			
		||||
 | 
			
		||||
        fjid = jid
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -211,7 +204,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
 | 
			
		|||
            else:
 | 
			
		||||
                # Default to highest prio
 | 
			
		||||
                fjid = jid
 | 
			
		||||
                resource_for_chat = None
 | 
			
		||||
                contact = highest_contact
 | 
			
		||||
 | 
			
		||||
        if not contact:
 | 
			
		||||
| 
						 | 
				
			
			@ -220,21 +212,15 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
 | 
			
		|||
                obj.conn.name, jid, obj.user_nick)
 | 
			
		||||
 | 
			
		||||
        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:
 | 
			
		||||
                self.control = ctrl
 | 
			
		||||
                self.control.set_session(self)
 | 
			
		||||
            else:
 | 
			
		||||
                # if no control exists and message comes from highest prio,
 | 
			
		||||
                # 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
 | 
			
		||||
                fjid = jid
 | 
			
		||||
 | 
			
		||||
        obj.popup = helpers.allow_popup_window(self.conn.name)
 | 
			
		||||
        obj.resource_for_chat = resource_for_chat
 | 
			
		||||
 | 
			
		||||
        type_ = 'chat'
 | 
			
		||||
        event_type = 'message_received'
 | 
			
		||||
| 
						 | 
				
			
			@ -268,9 +254,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
 | 
			
		|||
        Display the message or show notification in the roster
 | 
			
		||||
        """
 | 
			
		||||
        contact = None
 | 
			
		||||
        # if chat window will be for specific resource
 | 
			
		||||
        resource_for_chat = resource
 | 
			
		||||
 | 
			
		||||
        fjid = jid
 | 
			
		||||
 | 
			
		||||
        # Try to catch the contact with correct resource
 | 
			
		||||
| 
						 | 
				
			
			@ -298,7 +281,6 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
 | 
			
		|||
            else:
 | 
			
		||||
                # Default to highest prio
 | 
			
		||||
                fjid = jid
 | 
			
		||||
                resource_for_chat = None
 | 
			
		||||
                contact = highest_contact
 | 
			
		||||
 | 
			
		||||
        if not contact:
 | 
			
		||||
| 
						 | 
				
			
			@ -312,12 +294,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
 | 
			
		|||
                self.control = ctrl
 | 
			
		||||
                self.control.set_session(self)
 | 
			
		||||
            else:
 | 
			
		||||
                # if no control exists and message comes from highest prio, the new
 | 
			
		||||
                # 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
 | 
			
		||||
                fjid = jid
 | 
			
		||||
 | 
			
		||||
        # Do we have a queue?
 | 
			
		||||
        no_queue = len(gajim.events.get_events(self.conn.name, fjid)) == 0
 | 
			
		||||
| 
						 | 
				
			
			@ -367,7 +344,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
 | 
			
		|||
        if popup:
 | 
			
		||||
            if not self.control:
 | 
			
		||||
                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)):
 | 
			
		||||
                    self.control.read_queue()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue