xpra icon
Bug tracker and wiki

Ticket #51: xpra-debug-focus.patch

File xpra-debug-focus.patch, 18.0 KB (added by Antoine Martin, 9 years ago)

patch to make it easier to debug focus problems by printing all focus debug only

  • wimpiggy/error.py

     
    119119            self.call_unsynced(fun, *args, **kwargs)
    120120            return True
    121121        except XError, e:
    122             log("Ignoring X error: %s on %s", XErrorToName(e), fun)
     122            log.info("Ignoring X error: %s on %s", XErrorToName(e), fun)
    123123            return False
    124124
    125125    def swallow_synced(self, fun, *args, **kwargs):
     
    127127            self.call_synced(fun, *args, **kwargs)
    128128            return True
    129129        except XError, e:
    130             log("Ignoring X error: %s on %s", XErrorToName(e), fun)
     130            log.info("Ignoring X error: %s on %s", XErrorToName(e), fun)
    131131            return False
    132132
    133133    swallow = swallow_unsynced
  • wimpiggy/lowlevel/__init__.py

     
    66#We must import "*" or things will fail in mysterious ways!
    77from wimpiggy.lowlevel.bindings import *
    88
    9 from wimpiggy.log import Logger
    10 log = Logger()
    11 
    129def int32(x):
    1310    if x>0xFFFFFFFF:
    1411        raise OverflowError
     
    2219
    2320def send_wm_take_focus(target, time):
    2421    log("sending WM_TAKE_FOCUS: %r, %r", target, time)
    25     sendClientMessage(target, False, 0,
     22    sendClientMessage(target, False, 0,                     #@UndefinedVariable"
    2623                      "WM_PROTOCOLS",
    2724                      "WM_TAKE_FOCUS", int32(time), 0, 0, 0)
    2825
    2926def send_wm_delete_window(target):
    3027    log("sending WM_DELETE_WINDOW")
    31     sendClientMessage(target, False, 0,
     28    sendClientMessage(target, False, 0,                     #@UndefinedVariable"
    3229                      "WM_PROTOCOLS",
    33                       "WM_DELETE_WINDOW", const["CurrentTime"], 0, 0, 0)
     30                      "WM_DELETE_WINDOW",
     31                      const["CurrentTime"], 0, 0, 0)        #@UndefinedVariable"
  • wimpiggy/lowlevel/bindings.pyx

     
    17261726        return
    17271727    if event.window is event.delivered_to:
    17281728        if signal is not None:
    1729             log("  event was delivered to window itself")
     1729            #log("  event was delivered to window itself")
    17301730            _maybe_send_event(event.window, signal, event)
    17311731        else:
    17321732            log("  received event on window itself but have no signal for that")
    17331733    else:
    17341734        if parent_signal is not None:
    1735             log("  event was delivered to parent window")
     1735            #log("  event was delivered to parent window")
    17361736            _maybe_send_event(event.delivered_to, parent_signal, event)
    17371737        else:
    17381738            log("  received event on a parent window but have no parent signal")
     
    18171817                    pyev.window = _gw(d, e.xfocus.window)
    18181818                    pyev.mode = e.xfocus.mode
    18191819                    pyev.detail = e.xfocus.detail
     1820                    log("FocusIn/FocusOut received: mode=%s, detail=%s", pyev.mode, pyev.detail)
    18201821                elif e.type == ClientMessage:
    18211822                    log("ClientMessage received")
    18221823                    pyev.window = _gw(d, e.xany.window)
     
    18411842                        pieces.append(int(e.xclient.data.l[i]) & 0xffffffff)
    18421843                    pyev.data = tuple(pieces)
    18431844                elif e.type == MapNotify:
    1844                     log("MapNotify event received")
     1845                    log.info("MapNotify event received")
    18451846                    pyev.window = _gw(d, e.xmap.window)
    18461847                    pyev.override_redirect = e.xmap.override_redirect
    18471848                elif e.type == UnmapNotify:
    1848                     log("UnmapNotify event received")
     1849                    log.info("UnmapNotify event received")
    18491850                    pyev.serial = e.xany.serial
    18501851                    pyev.window = _gw(d, e.xunmap.window)
    18511852                elif e.type == DestroyNotify:
     
    18681869                    log("ReparentNotify event received")
    18691870                    pyev.window = _gw(d, e.xreparent.window)
    18701871                elif e.type == KeyPress:
    1871                     log("KeyPress event received")
     1872                    log.info("KeyPress event received")
    18721873                    pyev.window = _gw(d, e.xany.window)
    18731874                    pyev.hardware_keycode = e.xkey.keycode
    18741875                    pyev.state = e.xkey.state
  • wimpiggy/window.py

     
    671671            # FIXME: extract state and input hint
    672672
    673673            if wm_hints.urgency:
     674                log.info("wm_hints.urgency: setting attention-requested")
    674675                self.set_property("attention-requested", True)
    675676
    676677            log("wm_hints.input = %s", wm_hints.input)
    677678            if wm_hints.input is not None:
    678679                self._input_field = wm_hints.input
     680                log.info("wm_hints: input_field=%s, can-focus", self._input_field)
    679681                self.notify("can-focus")
    680682
    681683    _property_handlers["WM_HINTS"] = _handle_wm_hints
     
    776778        if protocols is None:
    777779            protocols = []
    778780        self._internal_set_property("protocols", protocols)
     781        log.info("initial_properties: sending can-focus")
    779782        self.notify("can-focus")
    780783
    781784        window_types = self.prop_get("_NET_WM_WINDOW_TYPE", ["atom"])
     
    895898
    896899    def do_get_property_can_focus(self, name):
    897900        assert name == "can-focus"
    898         return self._input_field or "WM_TAKE_FOCUS" in self.get_property("protocols")
     901        cf = self._input_field or "WM_TAKE_FOCUS" in self.get_property("protocols")
     902        log.info("do_get_property_can_focus()=%s", cf)
     903        return cf
    899904
    900905    def do_get_property(self, pspec):
    901906        if pspec.name in self._state_properties:
     
    967972        # the WM's XSetInputFocus.
    968973        success = True
    969974        if self._input_field:
    970             log("... using XSetInputFocus")
     975            log.info("... using XSetInputFocus")
    971976            if not trap.swallow(XSetInputFocus, self.client_window, now):
    972                 log("XSetInputFocus failed...")
     977                log.info("XSetInputFocus failed...")
    973978                success = False
    974979        if "WM_TAKE_FOCUS" in self.get_property("protocols"):
    975             log("... using WM_TAKE_FOCUS")
     980            log.info("... using WM_TAKE_FOCUS")
    976981            if not trap.swallow(send_wm_take_focus, self.client_window, now):
    977                 log("WM_TAKE_FOCUS failed...")
     982                log.info("WM_TAKE_FOCUS failed...")
    978983                success = False
    979984        return success
    980985
     
    10221027        # Standard GTK double-buffering is useless for us, because it's on our
    10231028        # "official" window, and we don't draw to that.
    10241029        self.set_double_buffered(False)
    1025         self.set_property("can-focus", self.model.get_property("can-focus"))
     1030        cf = self.model.get_property("can-focus")
     1031        log.info("widget.init: can-focus=%s", cf)
     1032        self.set_property("can-focus", cf)
    10261033
    10271034
    10281035    def _unmanaged(self, model, wm_is_exiting):
  • wimpiggy/world_window.py

     
    9494        self.move(0, 0)
    9595        self._resize()
    9696       
     97        def has_tlf(*args):
     98            log.info("has-toplevel-focus: %s", args)
     99        self.connect("notify::has-toplevel-focus", has_tlf)
     100       
    97101    def _resize(self, *args):
    98102        x = gtk.gdk.screen_width()
    99103        y = gtk.gdk.screen_height()
     
    136140            send_wm_take_focus(self.window, current_time)
    137141
    138142    def do_focus_in_event(self, *args):
    139         log("world window got focus", type="focus")
     143        log.info("world window got focus", type="focus")
    140144        if not self.get_property("has-toplevel-focus"):
    141145            #super(WorldWindow, self).do_focus_in_event(*args)
    142146            gtk.Window.do_focus_in_event(self, *args)
    143147            self.reset_x_focus()
     148        self.notify("has-toplevel-focus")
    144149
    145150    def do_focus_out_event(self, *args):
    146151        # Do nothing -- harder:
     152        log.info("do_focus_out_event(%s)", args)
    147153        self.stop_emission("focus-out-event")
    148154        return False
    149155
    150156    def _take_focus(self):
    151         log("Focus -> world window", type="focus")
     157        log.info("Focus -> world window", type="focus")
    152158        assert self.flags() & gtk.REALIZED
    153159        # Weird hack: we are a GDK window, and the only way to properly get
    154160        # input focus to a GDK window is to send it WM_TAKE_FOCUS.  So this is
     
    161167
    162168    def reset_x_focus(self):
    163169        focus = self.get_focus()
    164         log("widget with focus: %s", focus, type="focus")
     170        log.info("widget with focus: %s", focus, type="focus")
    165171        if isinstance(focus, wimpiggy.window.WindowView):
    166172            # FIXME: ugly:
    167173            focus.model.give_client_focus()
     
    174180                                   "_NET_ACTIVE_WINDOW", "u32", const["XNone"])
    175181
    176182    def _after_set_focus(self, *args):
     183        log.info("_after_set_focus(%s)", args)
    177184        # GTK focus has changed.  See comment in __init__ for why this isn't a
    178185        # default handler.
    179186        if self.get_focus() is not None:
  • wimpiggy/log.py

     
    55
    66import sys
    77import logging
     8import time
    89# This module is used by non-GUI programs and thus must not import gtk.
    910
    1011# A wrapper around 'logging' with some convenience stuff.  In particular:
     
    3637        if "type" in kwargs:
    3738            type = kwargs["type"]
    3839            del kwargs["type"]
    39         self.getLogger(type).log(level, msg, *args, **kwargs)
     40        self.getLogger(type).log(level, str(time.time()).ljust(15)+" "+msg, *args, **kwargs)
     41        #self.getLogger(type).log(level, msg, *args, **kwargs)
    4042
    4143    def _method_maker(level):
    4244        return (lambda self, msg, *args, **kwargs:
  • wimpiggy/wm.py

     
    329329        # gone to PointerRoot or None, so that it can be given back to
    330330        # something real.  This is easy to detect -- a FocusIn event with
    331331        # detail PointerRoot or None is generated on the root window.
     332        log.info("do_wimpiggy_focus_in_event(%s)", repr(event))
    332333        if event.detail in (const["NotifyPointerRoot"], const["NotifyDetailNone"]):
    333334            self._world_window.reset_x_focus()
    334335
    335336    def do_wimpiggy_focus_out_event(self, event):
     337        log.info("do_wimpiggy_focus_out_event(%s)", repr(event))
    336338        printFocus(self._display)
    337339
    338340    def do_desktop_list_changed(self, desktops):
  • xpra/protocol.py

     
    6262def dump_packet(packet):
    6363    return "[" + ", ".join([repr_ellipsized(str(x), 50) for x in packet]) + "]"
    6464
    65 def main_thread_call(fn, *args, **kwargs):
    66     def cb(*foo):
    67         fn(*args, **kwargs)
    68         return False
    69     gobject.timeout_add(0, cb)
    7065
    71 
    7266class Protocol(object):
    7367    CONNECTION_LOST = object()
    7468    GIBBERISH = object()
     
    111105    def _maybe_queue_more_writes(self):
    112106        if self._write_queue.empty() and self._source_has_more:
    113107            self._flush_one_packet_into_buffer()
     108        return False
    114109
    115110    def _queue_write(self, data, flush=False):
    116111        if len(data)==0:
     
    165160                    assert self._closed
    166161                    break
    167162                if self._write_queue.empty():
    168                     main_thread_call(self._maybe_queue_more_writes)
     163                    gobject.idle_add(self._maybe_queue_more_writes)
    169164        finally:
    170165            log("write thread: ended, closing socket")
    171166            self._conn.close()
     
    191186            log("read thread: ended")
    192187
    193188    def _call_connection_lost(self, message="", exc_info=False):
    194         main_thread_call(self._connection_lost, message="", exc_info=False)
     189        gobject.idle_add(self._connection_lost, message, exc_info)
    195190
    196191    def _connection_lost(self, message="", exc_info=False):
    197192        log.info("connection lost: %s", message, exc_info=exc_info)
    198193        if not self._closed:
    199194            self._process_packet_cb(self, [Protocol.CONNECTION_LOST])
    200195            self.close()
     196        return False
    201197
    202198    def _read_parse_thread_loop(self):
    203199        try:
     
    223219                    if result is None:
    224220                        break
    225221                    packet, unprocessed = result
    226                     main_thread_call(self._process_packet, packet)
     222                    gobject.idle_add(self._process_packet, packet)
    227223                    if not had_deflate and (self._decompressor is not None):
    228224                        # deflate was just enabled: so decompress the unprocessed
    229225                        # data
     
    246242            log.warn("Unhandled error while processing packet from peer",
    247243                     exc_info=True)
    248244            # Ignore and continue, maybe things will work out anyway
     245        return False
    249246
    250247    def enable_deflate(self, level):
    251248        assert self._compressor is None and self._decompressor is None
  • xpra/server.py

     
    6868class DesktopManager(gtk.Widget):
    6969    def __init__(self):
    7070        gtk.Widget.__init__(self)
     71        log.info("DesktopManager.init() setting can-focus")
    7172        self.set_property("can-focus", True)
    7273        self.set_flags(gtk.NO_WINDOW)
    7374        self._models = {}
     
    925926
    926927    def _clear_keys_pressed(self):
    927928        if len(self.keys_pressed)>0:
    928             log.debug("clearing keys pressed: %s", self.keys_pressed)
     929            log.info("clearing keys pressed: %s", self.keys_pressed)
    929930            for keycode in self.keys_pressed.keys():
    930931                xtest_fake_key(gtk.gdk.display_get_default(), keycode, False)
    931932                #cancel any repeat timers:
     
    936937            self.keys_repeat_timers = {}
    937938
    938939    def _focus(self, id, modifiers):
    939         log.debug("_focus(%s,%s) has_focus=%s", id, modifiers, self._has_focus)
     940        log.info("_focus(%s,%s) has_focus=%s", id, modifiers, self._has_focus)
    940941        if self._has_focus != id:
    941942            if id == 0:
    942943                self._clear_keys_pressed()
     
    14191420        """ Does the actual press/unpress for keys
    14201421            Either from a packet (_process_key_action) or timeout (_key_repeat_timeout)
    14211422        """
    1422         if pressed and (id is not None) and (id not in self._id_to_window):
    1423             log("window %s is gone, ignoring key press", id)
    1424             return
     1423        if pressed and (id is not None):
     1424            if id not in self._id_to_window:
     1425                log.info("window %s is gone, ignoring key press: %s / %s", id, name, keycode)
     1426                return
     1427            if id!=self._has_focus:
     1428                log.info("window %s does not have focus, ignoring key press: %s / %s", id, name, keycode)
     1429                return
    14251430        if not keycode:
    14261431            keycode = self._keycode_from_keyname(keyval, name, modifiers)
    14271432            if not keycode:
  • xpra/client.py

     
    251251        return (x, y, w, h)
    252252
    253253    def do_map_event(self, event):
    254         log("Got map event")
     254        log.info("Got map event")
    255255        gtk.Window.do_map_event(self, event)
    256256        if not self._override_redirect:
    257257            x, y, w, h = self._geometry()
     
    259259            self._pos = (x, y)
    260260            self._size = (w, h)
    261261        self._been_mapped = True
     262        log.info("do_map_event: now calling focus change")
    262263        gobject.idle_add(self._focus_change)
    263264
    264265    def do_configure_event(self, event):
     
    279280        self.window.move_resize(x, y, w, h)
    280281        self._new_backing(w, h)
    281282
     283    def destroy(self):
     284        log.info("window.destroy() id=%s", self._id)
     285        self._unfocus()
     286        gtk.Window.destroy(self)
     287
     288    def _unfocus(self):
     289        if self._client._focused==self._id:
     290            self._client.update_focus(self._id, False)
     291
    282292    def do_unmap_event(self, event):
     293        log.info("do_unmap_event(%s) focused=%s, our id=%s", event, self._client._focused, self._id)
    283294        if not self._override_redirect:
     295            self._unfocus()
    284296            self._client.send(["unmap-window", self._id])
    285297
    286298    def do_delete_event(self, event):
     299        log.info("do_delete_event(%s)", event)
    287300        self._client.send(["close-window", self._id])
    288301        return True
    289302
     
    333346        self._button_action(scroll_map[event.direction], event, False)
    334347
    335348    def _focus_change(self, *args):
    336         log.debug("_focus_change(%s)" % str(args))
     349        log.info("_focus_change(%s)" % str(args))
    337350        if self._been_mapped:
    338351            self._client.update_focus(self._id, self.get_property("has-toplevel-focus"))
    339352
     
    665678                self.send(["focus", _id, self.mask_to_names(current_mask)])
    666679            else:
    667680                self.send(["focus", _id])
    668         log.debug("update_focus(%s,%s) _focused=%s", id, gotit, self._focused)
     681        log.info("update_focus(%s,%s) _focused=%s", id, gotit, self._focused)
    669682        if gotit and self._focused is not id:
    670683            self.clear_repeat()
    671684            send_focus(id)
     
    964977
    965978    def _process_lost_window(self, packet):
    966979        (_, id) = packet
     980        log.info("process_lost_window(%s)", id)
    967981        window = self._id_to_window[id]
    968982        del self._id_to_window[id]
    969983        del self._window_to_id[window]