From f657bd0cd9c09770cce7c52aeda413d589774ff8 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 26 Apr 2016 11:49:56 +0200 Subject: [PATCH] Overlay icons: Fix invalidation with nautilus #3249 This avoids an extra socketapi call after invalidate_extension_info is called from a STATUS message. --- shell_integration/nautilus/syncstate.py | 104 ++++++++++++++++-------- 1 file changed, 69 insertions(+), 35 deletions(-) diff --git a/shell_integration/nautilus/syncstate.py b/shell_integration/nautilus/syncstate.py index 33d53fad75..ca74ed0384 100644 --- a/shell_integration/nautilus/syncstate.py +++ b/shell_integration/nautilus/syncstate.py @@ -66,6 +66,7 @@ class SocketConnect(GObject.GObject): GObject.timeout_add(5000, self._connectToSocketServer) def sendCommand(self, cmd): + # print("Server command: " + cmd) if self.connected: try: self._sock.send(cmd) @@ -232,6 +233,48 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info # Handles a single line of server response and sets the emblem def handle_commands(self, action, args): + # file = args[0] # For debug only + # print("Action for " + file + ": " + args[0]) # For debug only + if action == 'STATUS': + newState = args[0] + filename = ':'.join(args[1:]) + + itemStore = self.find_item_for_file(filename) + if itemStore: + if( not itemStore['state'] or newState != itemStore['state'] ): + item = itemStore['item'] + + # print("Setting emblem on " + filename + "<>" + emblem + "<>") # For debug only + + # If an emblem is already set for this item, we need to + # clear the existing extension info before setting a new one. + # + # That will also trigger a new call to + # update_file_info for this item! That's why we set + # skipNextUpdate to True: we don't want to pull the + # current data from the client after getting a push + # notification. + invalidate = itemStore['state'] != None + if invalidate: + item.invalidate_extension_info() + self.set_emblem(item, newState) + + socketConnect.nautilusVFSFile_table[filename] = { + 'item': item, + 'state': newState, + 'skipNextUpdate': invalidate } + + elif action == 'UPDATE_VIEW': + # Search all items underneath this path and invalidate them + if args[0] in socketConnect.registered_paths: + self.invalidate_items_underneath(args[0]) + + elif action == 'REGISTER_PATH': + self.invalidate_items_underneath(args[0]) + elif action == 'UNREGISTER_PATH': + self.invalidate_items_underneath(args[0]) + + def set_emblem(self, item, state): Emblems = { 'OK' : appname +'_ok', 'SYNC' : appname +'_sync', 'NEW' : appname +'_sync', @@ -245,34 +288,10 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info 'NOP' : '' } - # file = args[0] # For debug only - # print("Action for " + file + ": " + args[0]) # For debug only - if action == 'STATUS': - newState = args[0] - emblem = 'NOP' # Show nothing if no emblem si defined. - if newState in Emblems: - emblem = Emblems[newState] - filename = ':'.join(args[1:]) - - if emblem: - itemStore = self.find_item_for_file(filename) - if itemStore: - if( not itemStore['state'] or newState != itemStore['state'] ): - item = itemStore['item'] - item.invalidate_extension_info() # clears the old emblem - item.add_emblem(emblem) - # print("Setting emblem on " + filename + "<>" + emblem + "<>") # For debug only - socketConnect.nautilusVFSFile_table[filename] = {'item': item, 'state':newState} - - elif action == 'UPDATE_VIEW': - # Search all items underneath this path and invalidate them - if args[0] in socketConnect.registered_paths: - self.invalidate_items_underneath(args[0]) - - elif action == 'REGISTER_PATH': - self.invalidate_items_underneath(args[0]) - elif action == 'UNREGISTER_PATH': - self.invalidate_items_underneath(args[0]) + emblem = 'NOP' # Show nothing if no emblem is defined. + if state in Emblems: + emblem = Emblems[state] + item.add_emblem(emblem) def update_file_info(self, item): if item.get_uri_scheme() != 'file': @@ -282,13 +301,28 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info if item.is_directory(): filename += '/' + inScope = False for reg_path in socketConnect.registered_paths: if filename.startswith(reg_path): - socketConnect.nautilusVFSFile_table[filename] = {'item': item, 'state':''} - - # item.add_string_attribute('share_state', "share state") # ? - self.askForOverlay(filename) + inScope = True break - else: - # print("Not in scope:" + filename) # For debug only - pass + + if not inScope: + return + + # Ask for the current state from the client -- unless this update was + # triggered by receiving a STATUS message from the client in the first + # place. + itemStore = self.find_item_for_file(filename) + if itemStore and itemStore['skipNextUpdate'] and itemStore['state']: + itemStore['skipNextUpdate'] = False + itemStore['item'] = item + self.set_emblem(item, itemStore['state']) + else: + socketConnect.nautilusVFSFile_table[filename] = { + 'item': item, + 'state': None, + 'skipNextUpdate': False } + + # item.add_string_attribute('share_state', "share state") # ? + self.askForOverlay(filename)