コード例 #1
0
ファイル: win32_tray.py プロジェクト: rudresh2319/Xpra
 def cleanup(self):
     log("Win32Tray.cleanup() tray_widget=%s", self.tray_widget)
     if self.tray_widget:
         self.tray_widget.close()
         self.tray_widget = None
     get_win32_event_listener().remove_event_callback(win32con.WM_DISPLAYCHANGE, self.calculate_offset)
     log("Win32Tray.cleanup() ended")
コード例 #2
0
ファイル: win32_tray.py プロジェクト: rudresh2319/Xpra
 def __init__(self, *args):
     TrayBase.__init__(self, *args)
     self.default_icon_extension = "ico"
     self.default_icon_name = "xpra.ico"
     self.calculate_offset()
     icon_filename = self.get_tray_icon_filename(self.default_icon_filename)
     self.tray_widget = win32NotifyIcon(self.tooltip, self.move_cb, self.click_cb, self.exit_cb, None, icon_filename)
     get_win32_event_listener().add_event_callback(win32con.WM_DISPLAYCHANGE, self.calculate_offset)
コード例 #3
0
ファイル: webcam.py プロジェクト: TianyouLi/Xpra
def add_video_device_change_callback(callback):
    if not get_win32_event_listener:
        return
    from xpra.platform.webcam import _video_device_change_callbacks
    if len(_video_device_change_callbacks)==0:
        #first callback added, register our handler:
        get_win32_event_listener().add_event_callback(WM_DEVICECHANGE, callback)
    _video_device_change_callbacks.append(_device_change_callback)
コード例 #4
0
ファイル: webcam.py プロジェクト: TianyouLi/Xpra
def remove_video_device_change_callback(callback):
    if not get_win32_event_listener:
        return
    from xpra.platform.webcam import _video_device_change_callbacks
    if callback in _video_device_change_callbacks:
        _video_device_change_callbacks.remove(callback)
    if len(_video_device_change_callbacks)==0:
        #none left, stop listening
        get_win32_event_listener().remove_event_callback(WM_DEVICECHANGE, _device_change_callback)
コード例 #5
0
ファイル: gui.py プロジェクト: rudresh2319/Xpra
 def cleanup(self):
     self.setup_console_event_listener(False)
     log("ClientExtras.cleanup() ended")
     el = get_win32_event_listener(False)
     if el:
         el.cleanup()
     self.client = None
コード例 #6
0
 def __init__(self):
     GTKShadowServerBase.__init__(self)
     self.keycodes = {}
     self.cursor_handle = None
     self.cursor_data = None
     if GetSystemMetrics(win32con.SM_SAMEDISPLAYFORMAT) == 0:
         raise InitException(
             "all the monitors must use the same display format")
     el = get_win32_event_listener()
     from xpra.net.bytestreams import set_continue_wait
     #on win32, we want to wait just a little while,
     #to prevent servers spinning wildly on non-blocking sockets:
     set_continue_wait(5)
     #TODO: deal with those messages?
     el.add_event_callback(win32con.WM_POWERBROADCAST,
                           self.power_broadcast_event)
     #el.add_event_callback(WM_WTSSESSION_CHANGE,         self.session_change_event)
     #these are bound to callbacks in the client,
     #but on the server we just ignore them:
     el.ignore_events.update({
         win32con.WM_ACTIVATEAPP: "WM_ACTIVATEAPP",
         win32con.WM_MOVE: "WM_MOVE",
         win32con.WM_INPUTLANGCHANGE: "WM_INPUTLANGCHANGE",
         win32con.WM_WININICHANGE: "WM_WININICHANGE",
     })
     #non-blocking server sockets (TCP and named pipes):
     from xpra.net.bytestreams import CONTINUE_ERRNO
     import errno
     CONTINUE_ERRNO[
         errno.WSAEWOULDBLOCK] = "WSAEWOULDBLOCK"  #@UndefinedVariable
コード例 #7
0
ファイル: gui.py プロジェクト: rudresh2319/Xpra
 def __init__(self, client, opts):
     self.client = client
     self._kh_warning = False
     self._console_handler_registered = self.setup_console_event_listener(
         True)
     try:
         el = get_win32_event_listener(True)
         if el:
             el.add_event_callback(win32con.WM_ACTIVATEAPP,
                                   self.activateapp)
             el.add_event_callback(win32con.WM_POWERBROADCAST,
                                   self.power_broadcast_event)
             el.add_event_callback(win32con.WM_MOVE, self.wm_move)
             el.add_event_callback(WM_WTSSESSION_CHANGE,
                                   self.session_change_event)
             el.add_event_callback(win32con.WM_INPUTLANGCHANGE,
                                   self.inputlangchange)
             el.add_event_callback(win32con.WM_WININICHANGE, self.inichange)
     except Exception as e:
         log.error("cannot register focus and power callbacks: %s", e)
     self.keyboard_hook_id = None
     if FORWARD_WINDOWS_KEY:
         from xpra.make_thread import make_thread
         make_thread(self.init_keyboard_listener,
                     "keyboard-listener",
                     daemon=True).start()
コード例 #8
0
ファイル: gui.py プロジェクト: svn2github/Xpra
 def cleanup(self):
     self.setup_console_event_listener(False)
     log("ClientExtras.cleanup() ended")
     el = get_win32_event_listener(False)
     if el:
         el.cleanup()
     self.client = None
コード例 #9
0
ファイル: webcam.py プロジェクト: tardyp/Xpra
def remove_video_device_change_callback(callback):
    from xpra.platform.webcam import _video_device_change_callbacks
    if callback in _video_device_change_callbacks:
        _video_device_change_callbacks.remove(callback)
    if len(_video_device_change_callbacks) == 0:
        #none left, stop listening
        el = get_win32_event_listener(False)
        if el:
            el.remove_event_callback(WM_DEVICECHANGE, _device_change_callback)
コード例 #10
0
ファイル: gui.py プロジェクト: svn2github/Xpra
 def cleanup(self):
     log("ClientExtras.cleanup()")
     if self._console_handler_registered:
         self._console_handler_registered = False
         self.setup_console_event_listener(False)
     el = get_win32_event_listener(False)
     if el:
         el.cleanup()
     log("ClientExtras.cleanup() ended")
コード例 #11
0
 def cleanup(self):
     log("ClientExtras.cleanup()")
     if self._console_handler_registered:
         self._console_handler_registered = False
         self.setup_console_event_listener(False)
     el = get_win32_event_listener(False)
     if el:
         el.cleanup()
     log("ClientExtras.cleanup() ended")
コード例 #12
0
ファイル: win32_tray.py プロジェクト: cattaka/Xpra
 def __init__(self, *args):
     TrayBase.__init__(self, *args)
     self.calculate_offset()
     self.default_icon_extension = "ico"
     icon_filename = get_icon_filename(self.default_icon_filename, "ico")
     self.tray_widget = win32NotifyIcon(self.app_id, self.tooltip,
                                        self.move_cb, self.click_cb,
                                        self.exit_cb, icon_filename)
     el = get_win32_event_listener()
     if el:
         el.add_event_callback(win32con.WM_DISPLAYCHANGE,
                               self.calculate_offset)
コード例 #13
0
ファイル: gui.py プロジェクト: svn2github/Xpra
 def __init__(self, client):
     self.client = client
     self._kh_warning = False
     self.setup_console_event_listener()
     try:
         import win32con                 #@Reimport @UnresolvedImport
         el = get_win32_event_listener(True)
         if el:
             el.add_event_callback(win32con.WM_ACTIVATEAPP, self.activateapp)
             el.add_event_callback(win32con.WM_POWERBROADCAST, self.power_broadcast_event)
     except Exception, e:
         log.error("cannot register focus and power callbacks: %s", e)
コード例 #14
0
ファイル: gui.py プロジェクト: rudresh2319/Xpra
 def __init__(self, client, opts):
     self.client = client
     self._kh_warning = False
     self.setup_console_event_listener()
     try:
         import win32con                 #@Reimport @UnresolvedImport
         el = get_win32_event_listener(True)
         if el:
             el.add_event_callback(win32con.WM_ACTIVATEAPP, self.activateapp)
             el.add_event_callback(win32con.WM_POWERBROADCAST, self.power_broadcast_event)
     except Exception, e:
         log.error("cannot register focus and power callbacks: %s", e)
コード例 #15
0
    def __init__(self, client, _opts):
        self.client = client
        self._kh_warning = False
        self._console_handler_added = False
        self._screensaver_state = False
        self._screensaver_timer = 0
        self._exit = False
        if SCREENSAVER_LISTENER_POLL_DELAY > 0:

            def log_screensaver():
                v = bool(
                    GetIntSystemParametersInfo(
                        win32con.SPI_GETSCREENSAVERRUNNING))
                log("SPI_GETSCREENSAVERRUNNING=%s", v)
                if self._screensaver_state != v:
                    self._screensaver_state = v
                    if v:
                        self.client.suspend()
                    else:
                        self.client.resume()
                return True

            self._screensaver_timer = client.timeout_add(
                SCREENSAVER_LISTENER_POLL_DELAY * 1000, log_screensaver)
        if CONSOLE_EVENT_LISTENER:
            self._console_handler_added = setup_console_event_listener(
                self.handle_console_event, True)
        from xpra.platform.win32.win32_events import get_win32_event_listener
        try:
            el = get_win32_event_listener(True)
            self._el = el
            if el:
                el.add_event_callback(win32con.WM_ACTIVATEAPP,
                                      self.activateapp)
                el.add_event_callback(win32con.WM_POWERBROADCAST,
                                      self.power_broadcast_event)
                el.add_event_callback(win32con.WM_MOVE, self.wm_move)
                el.add_event_callback(WM_WTSSESSION_CHANGE,
                                      self.session_change_event)
                el.add_event_callback(win32con.WM_INPUTLANGCHANGE,
                                      self.inputlangchange)
                el.add_event_callback(win32con.WM_WININICHANGE, self.inichange)
                el.add_event_callback(win32con.WM_ENDSESSION, self.end_session)
        except Exception as e:
            log.error("Error: cannot register focus and power callbacks:")
            log.error(" %s", e)
        self.keyboard_hook_id = None
        if FORWARD_WINDOWS_KEY and mixin_features.windows:
            from xpra.make_thread import start_thread
            start_thread(self.init_keyboard_listener,
                         "keyboard-listener",
                         daemon=True)
コード例 #16
0
ファイル: gui.py プロジェクト: svn2github/Xpra
 def cleanup(self):
     log("ClientExtras.cleanup()")
     if self._console_handler_registered:
         self._console_handler_registered = False
         self.setup_console_event_listener(False)
     el = get_win32_event_listener(False)
     if el:
         el.cleanup()
     khid = self.keyboard_hook_id
     if khid:
         self.keyboard_hook_id = None
         windll.user32.UnhookWindowsHookEx(khid)
     log("ClientExtras.cleanup() ended")
コード例 #17
0
ファイル: gui.py プロジェクト: rudresh2319/Xpra
 def cleanup(self):
     log("ClientExtras.cleanup()")
     if self._console_handler_registered:
         self._console_handler_registered = False
         self.setup_console_event_listener(False)
     el = get_win32_event_listener(False)
     if el:
         el.cleanup()
     khid = self.keyboard_hook_id
     if khid:
         self.keyboard_hook_id = None
         windll.user32.UnhookWindowsHookEx(khid)
     log("ClientExtras.cleanup() ended")
コード例 #18
0
ファイル: gui.py プロジェクト: svn2github/Xpra
 def __init__(self, client, opts):
     self.client = client
     self._kh_warning = False
     self._console_handler_registered = self.setup_console_event_listener(True)
     try:
         import win32con                 #@Reimport @UnresolvedImport
         el = get_win32_event_listener(True)
         if el:
             el.add_event_callback(win32con.WM_ACTIVATEAPP,      self.activateapp)
             el.add_event_callback(win32con.WM_POWERBROADCAST,   self.power_broadcast_event)
             el.add_event_callback(win32con.WM_MOVE,             self.wm_move)
             el.add_event_callback(WM_WTSSESSION_CHANGE,         self.session_change_event)
             el.add_event_callback(win32con.WM_INPUTLANGCHANGE,  self.inputlangchange)
             el.add_event_callback(win32con.WM_WININICHANGE,     self.inichange)
     except Exception as e:
         log.error("cannot register focus and power callbacks: %s", e)
コード例 #19
0
ファイル: gui.py プロジェクト: svn2github/Xpra
def remove_window_hooks(window):
    try:
        if hasattr(window, "win32hooks"):
            win32hooks = window.win32hooks
            log("remove_window_hooks(%s) found %s", window, win32hooks)
            if win32hooks:
                win32hooks.cleanup()
                window.win32hooks = None
        if hasattr(window, "activate_app_hook"):
            activate_app_cb = window.activate_app_hook
            if activate_app_cb:
                el = get_win32_event_listener(True)
                el.remove_event_callback(win32con.WM_ACTIVATEAPP, activate_app_cb)
            window.activate_app_hook = None
    except:
        log.error("remove_window_hooks(%s)", exc_info=True)
コード例 #20
0
def remove_window_hooks(window):
    try:
        if hasattr(window, "win32hooks"):
            win32hooks = window.win32hooks
            log("remove_window_hooks(%s) found %s", window, win32hooks)
            if win32hooks:
                win32hooks.cleanup()
                window.win32hooks = None
        if hasattr(window, "activate_app_hook"):
            activate_app_cb = window.activate_app_hook
            if activate_app_cb:
                el = get_win32_event_listener(True)
                el.remove_event_callback(win32con.WM_ACTIVATEAPP,
                                         activate_app_cb)
            window.activate_app_hook = None
    except:
        log.error("remove_window_hooks(%s)", exc_info=True)
コード例 #21
0
ファイル: shadow_server.py プロジェクト: TianyouLi/Xpra
 def __init__(self):
     GTKShadowServerBase.__init__(self)
     self.keycodes = {}
     el = get_win32_event_listener()
     from xpra.net.bytestreams import set_continue_wait
     #on win32, we want to wait just a little while,
     #to prevent servers spinning wildly on non-blocking sockets:
     set_continue_wait(5)
     #TODO: deal with those messages?
     #el.add_event_callback(win32con.WM_POWERBROADCAST,   self.power_broadcast_event)
     #el.add_event_callback(WM_WTSSESSION_CHANGE,         self.session_change_event)
     #these are bound to callbacks in the client,
     #but on the server we just ignore them:
     el.ignore_events.update({
         win32con.WM_ACTIVATEAPP: "WM_ACTIVATEAPP",
         win32con.WM_MOVE: "WM_MOVE",
         win32con.WM_INPUTLANGCHANGE: "WM_INPUTLANGCHANGE",
         win32con.WM_WININICHANGE: "WM_WININICHANGE",
     })
コード例 #22
0
ファイル: gui.py プロジェクト: svn2github/Xpra
 def __init__(self, client, opts):
     self.client = client
     self._kh_warning = False
     self._console_handler_registered = self.setup_console_event_listener(True)
     try:
         el = get_win32_event_listener(True)
         if el:
             el.add_event_callback(win32con.WM_ACTIVATEAPP,      self.activateapp)
             el.add_event_callback(win32con.WM_POWERBROADCAST,   self.power_broadcast_event)
             el.add_event_callback(win32con.WM_MOVE,             self.wm_move)
             el.add_event_callback(WM_WTSSESSION_CHANGE,         self.session_change_event)
             el.add_event_callback(win32con.WM_INPUTLANGCHANGE,  self.inputlangchange)
             el.add_event_callback(win32con.WM_WININICHANGE,     self.inichange)
     except Exception as e:
         log.error("cannot register focus and power callbacks: %s", e)
     self.keyboard_hook_id = None
     if FORWARD_WINDOWS_KEY:
         from xpra.make_thread import make_thread
         make_thread(self.init_keyboard_listener, "keyboard-listener", daemon=True).start()
コード例 #23
0
ファイル: shadow_server.py プロジェクト: TijZwa/xpra
 def __init__(self):
     super().__init__()
     self.keycodes = {}
     self.cursor_handle = None
     self.cursor_data = None
     self.cursor_errors = [0, 0]
     if GetSystemMetrics(win32con.SM_SAMEDISPLAYFORMAT)==0:
         raise InitException("all the monitors must use the same display format")
     el = get_win32_event_listener()
     #TODO: deal with those messages?
     el.add_event_callback(win32con.WM_POWERBROADCAST,   self.power_broadcast_event)
     #el.add_event_callback(WM_WTSSESSION_CHANGE,         self.session_change_event)
     #these are bound to callbacks in the client,
     #but on the server we just ignore them:
     el.ignore_events.update({
                              win32con.WM_ACTIVATEAPP        : "WM_ACTIVATEAPP",
                              win32con.WM_MOVE               : "WM_MOVE",
                              win32con.WM_INPUTLANGCHANGE    : "WM_INPUTLANGCHANGE",
                              win32con.WM_WININICHANGE       : "WM_WININICHANGE",
                              })
コード例 #24
0
 def __init__(self, client, opts):
     self.client = client
     self._kh_warning = False
     self._console_handler_registered = self.setup_console_event_listener(
         True)
     try:
         import win32con  #@Reimport @UnresolvedImport
         el = get_win32_event_listener(True)
         if el:
             el.add_event_callback(win32con.WM_ACTIVATEAPP,
                                   self.activateapp)
             el.add_event_callback(win32con.WM_POWERBROADCAST,
                                   self.power_broadcast_event)
             el.add_event_callback(win32con.WM_MOVE, self.wm_move)
             el.add_event_callback(WM_WTSSESSION_CHANGE,
                                   self.session_change_event)
             el.add_event_callback(win32con.WM_INPUTLANGCHANGE,
                                   self.inputlangchange)
             el.add_event_callback(win32con.WM_WININICHANGE, self.inichange)
     except Exception as e:
         log.error("cannot register focus and power callbacks: %s", e)
コード例 #25
0
ファイル: printing.py プロジェクト: cattaka/Xpra
def init_winspool_listener():
    from xpra.platform.win32.win32_events import get_win32_event_listener
    get_win32_event_listener().add_event_callback(win32con.WM_DEVMODECHANGE,
                                                  on_devmodechange)
コード例 #26
0
ファイル: gui.py プロジェクト: svn2github/Xpra
def add_window_hooks(window):
    if not WINDOW_HOOKS:
        # allows us to disable the win32 hooks for testing
        return
    # win32 cannot use set_group by default:
    try:
        window.get_window().set_group = noop
    except:
        pass
    # gtk2 to window handle:
    try:
        handle = window.get_window().handle
    except:
        return

    if GROUP_LEADER:
        # windows 7 onwards can use AppUserModel to emulate the group leader stuff:
        propsys = get_propsys()
        log("win32 hooks: propsys=%s", propsys)
        if propsys:

            def set_group(leader):
                try:
                    log("win32 hooks: set_group(%#x)", leader.handle)
                    ps = propsys.SHGetPropertyStoreForWindow(handle)
                    key = propsys.PSGetPropertyKeyFromName("System.AppUserModel.ID")
                    value = propsys.PROPVARIANTType(leader.handle)
                    log("win32 hooks: calling %s(%s, %s)", ps.SetValue, key, value)
                    ps.SetValue(key, value)
                except Exception as e:
                    log.error("failed to set group leader: %s", e)

            window.get_window().set_group = set_group
            log("hooked group leader override using %s", propsys)

    if UNDECORATED_STYLE:
        # OR windows never have any decorations or taskbar menu
        readd_window_options = None
        if not window._override_redirect:
            # override set_decorated so we can preserve the taskbar menu for undecorated windows
            window.__set_decorated = window.set_decorated

            def readd_window_options():
                try:
                    cur_style = win32api.GetWindowLong(handle, win32con.GWL_STYLE)
                    # re-add taskbar menu:
                    style = cur_style
                    style |= win32con.WS_SYSMENU
                    style |= win32con.WS_MAXIMIZEBOX
                    # can always minimize:
                    style |= win32con.WS_MINIMIZEBOX
                    log(
                        "readd_window_options() using %s style=%#x on window %#x",
                        ["unchanged", "new"][int(style != cur_style)],
                        style,
                        handle,
                    )
                    if style != cur_style:
                        win32gui.SetWindowLong(handle, win32con.GWL_STYLE, style)
                except:
                    log.warn("failed to override window style", exc_info=True)

            def set_decorated(b):
                window.__set_decorated(b)
                readd_window_options()

            window.set_decorated = set_decorated
            readd_window_options()
            # override after_window_state_updated so we can re-add the missing style options
            # (somehow doing it from on_realize which calls add_window_hooks is not enough)
            window.__after_window_state_updated = window.after_window_state_updated

            def after_window_state_updated(*args):
                log("after_window_state_updated%s", args)
                window.__after_window_state_updated()
                readd_window_options()

            window.after_window_state_updated = after_window_state_updated

            try:
                el = get_win32_event_listener(True)
                log("win32_event_listener=%s", el)
                if el:

                    def activate_cb(*args):
                        log("activate_cb%s", args)
                        readd_window_options()

                    el.add_event_callback(win32con.WM_ACTIVATEAPP, activate_cb)
                    window.activate_app_hook = activate_cb
            except:
                log.warn("failed to add activateapp callback", exc_info=True)

    if MAX_SIZE_HINT:
        # glue code for gtk to win32 APIs:
        # add event hook class:
        win32hooks = Win32Hooks(handle)
        log("add_window_hooks(%s) added hooks for hwnd %#x: %s", window, handle, win32hooks)
        window.win32hooks = win32hooks
        win32hooks.max_size = None
        win32hooks.setup()

        if GEOMETRY:
            # save original geometry function:
            window.__apply_geometry_hints = window.apply_geometry_hints
            # our function for taking gdk window hints and passing them to the win32 hooks class:
            def apply_maxsize_hints(hints):
                workw, workh = 0, 0
                if not window.get_decorated():
                    workarea = get_monitor_workarea_for_window(handle)
                    log("using workarea as window size limit for undecorated window: %s", workarea)
                    if workarea:
                        workw, workh = workarea[2:4]
                maxw = hints.get("max_width", 0)
                maxh = hints.get("max_height", 0)
                if workw > 0 and workh > 0:
                    # clamp to workspace for undecorated windows:
                    if maxw > 0 and maxh > 0:
                        maxw = min(workw, maxw)
                        maxh = min(workh, maxh)
                    else:
                        maxw, maxh = workw, workh
                log("apply_maxsize_hints(%s) for window %s, found max: %sx%s", hints, window, maxw, maxh)
                if (maxw > 0 and maxw < 32767) or (maxh > 0 and maxh < 32767):
                    window.win32hooks.max_size = (maxw or 32000), (maxh or 32000)
                elif window.win32hooks.max_size:
                    # was set, clear it
                    window.win32hooks.max_size = None
                # remove them so GTK doesn't try to set attributes,
                # which would remove the maximize button:
                for x in ("max_width", "max_height"):
                    if x in hints:
                        del hints[x]

            # our monkey patching method, which calls the function above:
            def apply_geometry_hints(hints):
                apply_maxsize_hints(hints)
                return window.__apply_geometry_hints(hints)

            window.apply_geometry_hints = apply_geometry_hints
            # apply current geometry hints, if any:
            if window.geometry_hints:
                apply_maxsize_hints(window.geometry_hints)
コード例 #27
0
ファイル: printing.py プロジェクト: ljmljz/xpra
def init_winspool_listener():
    from xpra.platform.win32.win32_events import get_win32_event_listener
    get_win32_event_listener().add_event_callback(win32con.WM_DEVMODECHANGE, on_devmodechange)
コード例 #28
0
def add_window_hooks(window):
    if not WINDOW_HOOKS:
        #allows us to disable the win32 hooks for testing
        return
    #win32 cannot use set_group by default:
    try:
        window.get_window().set_group = noop
    except:
        pass
    #gtk2 to window handle:
    try:
        handle = window.get_window().handle
    except:
        return

    if GROUP_LEADER:
        #windows 7 onwards can use AppUserModel to emulate the group leader stuff:
        propsys = get_propsys()
        log("win32 hooks: propsys=%s", propsys)
        if propsys:

            def set_group(leader):
                try:
                    log("win32 hooks: set_group(%#x)", leader.handle)
                    ps = propsys.SHGetPropertyStoreForWindow(handle)
                    key = propsys.PSGetPropertyKeyFromName(
                        "System.AppUserModel.ID")
                    value = propsys.PROPVARIANTType(leader.handle)
                    log("win32 hooks: calling %s(%s, %s)", ps.SetValue, key,
                        value)
                    ps.SetValue(key, value)
                except Exception as e:
                    log.error("failed to set group leader: %s", e)

            window.get_window().set_group = set_group
            log("hooked group leader override using %s", propsys)

    if UNDECORATED_STYLE:
        #OR windows never have any decorations or taskbar menu
        readd_window_options = None
        if not window._override_redirect:
            #override set_decorated so we can preserve the taskbar menu for undecorated windows
            window.__set_decorated = window.set_decorated

            def readd_window_options():
                try:
                    cur_style = win32api.GetWindowLong(handle,
                                                       win32con.GWL_STYLE)
                    #re-add taskbar menu:
                    style = cur_style
                    style |= win32con.WS_SYSMENU
                    style |= win32con.WS_MAXIMIZEBOX
                    #can always minimize:
                    style |= win32con.WS_MINIMIZEBOX
                    log(
                        "readd_window_options() using %s style=%#x on window %#x",
                        ["unchanged",
                         "new"][int(style != cur_style)], style, handle)
                    if style != cur_style:
                        win32gui.SetWindowLong(handle, win32con.GWL_STYLE,
                                               style)
                except:
                    log.warn("failed to override window style", exc_info=True)

            def set_decorated(b):
                window.__set_decorated(b)
                readd_window_options()

            window.set_decorated = set_decorated
            readd_window_options()
            #override after_window_state_updated so we can re-add the missing style options
            #(somehow doing it from on_realize which calls add_window_hooks is not enough)
            window.__after_window_state_updated = window.after_window_state_updated

            def after_window_state_updated(*args):
                log("after_window_state_updated%s", args)
                window.__after_window_state_updated()
                readd_window_options()

            window.after_window_state_updated = after_window_state_updated

            try:
                el = get_win32_event_listener(True)
                log("win32_event_listener=%s", el)
                if el:

                    def activate_cb(*args):
                        log("activate_cb%s", args)
                        readd_window_options()

                    el.add_event_callback(win32con.WM_ACTIVATEAPP, activate_cb)
                    window.activate_app_hook = activate_cb
            except:
                log.warn("failed to add activateapp callback", exc_info=True)

    if MAX_SIZE_HINT:
        #glue code for gtk to win32 APIs:
        #add event hook class:
        win32hooks = Win32Hooks(handle)
        log("add_window_hooks(%s) added hooks for hwnd %#x: %s", window,
            handle, win32hooks)
        window.win32hooks = win32hooks
        win32hooks.max_size = None
        win32hooks.setup()

        if GEOMETRY:
            #save original geometry function:
            window.__apply_geometry_hints = window.apply_geometry_hints

            #our function for taking gdk window hints and passing them to the win32 hooks class:
            def apply_maxsize_hints(hints):
                workw, workh = 0, 0
                if not window.get_decorated():
                    workarea = get_monitor_workarea_for_window(handle)
                    log(
                        "using workarea as window size limit for undecorated window: %s",
                        workarea)
                    if workarea:
                        workw, workh = workarea[2:4]
                maxw = hints.get("max_width", 0)
                maxh = hints.get("max_height", 0)
                if workw > 0 and workh > 0:
                    #clamp to workspace for undecorated windows:
                    if maxw > 0 and maxh > 0:
                        maxw = min(workw, maxw)
                        maxh = min(workh, maxh)
                    else:
                        maxw, maxh = workw, workh
                log("apply_maxsize_hints(%s) for window %s, found max: %sx%s",
                    hints, window, maxw, maxh)
                if (maxw > 0 and maxw < 32767) or (maxh > 0 and maxh < 32767):
                    window.win32hooks.max_size = (maxw or 32000), (maxh
                                                                   or 32000)
                elif window.win32hooks.max_size:
                    #was set, clear it
                    window.win32hooks.max_size = None
                #remove them so GTK doesn't try to set attributes,
                #which would remove the maximize button:
                for x in ("max_width", "max_height"):
                    if x in hints:
                        del hints[x]

            #our monkey patching method, which calls the function above:
            def apply_geometry_hints(hints):
                apply_maxsize_hints(hints)
                return window.__apply_geometry_hints(hints)

            window.apply_geometry_hints = apply_geometry_hints
            #apply current geometry hints, if any:
            if window.geometry_hints:
                apply_maxsize_hints(window.geometry_hints)