xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #249: decode-nonUIthread-for-osx.patch

File decode-nonUIthread-for-osx.patch, 3.6 KB (added by Antoine Martin, 8 years ago)

changes OSX to not use the UI thread to schedule decode, which is not enough to fix the problem

  • xpra/client.py

     
    320320            "desktop_size":         self._process_desktop_size,
    321321            "window-icon":          self._process_window_icon,
    322322            "sound-data":           self._process_sound_data,
    323             "draw":                 self._process_draw,
    324323            # "clipboard-*" packets are handled by a special case below.
    325324            }.items():
    326325            self._ui_packet_handlers[k] = v
     
    331330            "info-response":        self._process_info_response,
    332331            }.items():
    333332            self._packet_handlers[k] = v
     333        #UGLY OSX workaround:
     334        #For all platforms but OSX: run from UI thread to serialize access
     335        #and ensure that the window is created before we try to draw onto it. See:
     336        #https://www.xpra.org/trac/ticket/242
     337        #
     338        #On OSX, the UI thread can block for a very long time when the user
     339        #clicks on the menu bar, and we don't want the server to think that
     340        #we are suddenly slowing down or not responding/crashed,
     341        #so we process this request directly, not from the UI thread,
     342        #it won't be updated on screen (actual paint is still done from the UI thread)
     343        #but at least we decode the frame and reply to the server,
     344        #which also means that this is racy and may trigger errors...
     345        if sys.platform.startswith("darwin"):
     346            self._packet_handlers["draw"] = self._process_draw
     347        else:
     348            self._ui_packet_handlers["draw"] = self._process_draw
    334349
    335350    def run(self):
    336351        gtk_main_quit_on_fatal_exceptions_enable()
     
    11321147        window = self._id_to_window.get(wid)
    11331148        if not window:
    11341149            #window is gone
    1135             def draw_cleanup():
    1136                 if coding=="mmap":
    1137                     assert self.mmap_enabled
    1138                     def free_mmap_area():
    1139                         #we need to ack the data to free the space!
    1140                         data_start = ctypes.c_uint.from_buffer(self.mmap, 0)
    1141                         offset, length = data[-1]
    1142                         data_start.value = offset+length
    1143                     #clear the mmap area via idle_add so any pending draw requests
    1144                     #will get a chance to run first (preserving the order)
    1145                 self.send_damage_sequence(wid, packet_sequence, width, height, -1)
    1146             gobject.idle_add(draw_cleanup)
     1150            if coding=="mmap":
     1151                assert self.mmap_enabled
     1152                def free_mmap_area():
     1153                    #we need to ack the data to free the space!
     1154                    data_start = ctypes.c_uint.from_buffer(self.mmap, 0)
     1155                    offset, length = data[-1]
     1156                    data_start.value = offset+length
     1157                #clear the mmap area via idle_add so any pending draw requests
     1158                #will get a chance to run first (preserving the order)
     1159            self.send_damage_sequence(wid, packet_sequence, width, height, -1)
    11471160            return
    11481161        options = {}
    11491162        if len(packet)>10:
     
    11681181            window.draw_region(x, y, width, height, coding, data, rowstride, packet_sequence, options, [record_decode_time])
    11691182        except:
    11701183            log.error("draw error", exc_info=True)
    1171             gobject.idle_add(record_decode_time, False)
    1172             raise
     1184            record_decode_time(False)
    11731185
    11741186    def _process_cursor(self, packet):
    11751187        if not self.cursors_enabled: