Beispiel #1
0
def _get_atom(disp, d):
    unpacked = struct.unpack("@I", d)[0]
    pyatom = get_pyatom(disp, unpacked)
    if not pyatom:
        log.error("invalid atom: %s - %s", repr(d), repr(unpacked))
        return  None
    return str(pyatom)
Beispiel #2
0
def _get_atom(disp, d):
    unpacked = struct.unpack("@I", d)[0]
    pyatom = get_pyatom(disp, unpacked)
    if not pyatom:
        log.error("invalid atom: %s - %s", repr(d), repr(unpacked))
        return None
    return str(pyatom)
Beispiel #3
0
    def process_client_message_event(self, event):
        # FIXME
        # Need to listen for:
        #   _NET_CURRENT_DESKTOP
        #   _NET_WM_PING responses
        # and maybe:
        #   _NET_RESTACK_WINDOW
        #   _NET_WM_STATE (more fully)

        if event.message_type == "_NET_WM_STATE":

            def update_wm_state(prop):
                current = self.get_property(prop)
                mode = event.data[0]
                if mode == _NET_WM_STATE_ADD:
                    v = True
                elif mode == _NET_WM_STATE_REMOVE:
                    v = False
                elif mode == _NET_WM_STATE_TOGGLE:
                    v = not bool(current)
                else:
                    log.warn("Warning: invalid mode for _NET_WM_STATE: %s",
                             mode)
                    return
                log(
                    "process_client_message_event(%s) window %s=%s after %s (current state=%s)",
                    event, prop, v, STATE_STRING.get(mode, mode), current)
                if v != current:
                    self.update_wm_state(prop, v)

            atom1 = get_pyatom(event.window, event.data[1])
            log("_NET_WM_STATE: %s", atom1)
            if atom1 == "_NET_WM_STATE_FULLSCREEN":
                update_wm_state("fullscreen")
            elif atom1 == "_NET_WM_STATE_ABOVE":
                update_wm_state("above")
            elif atom1 == "_NET_WM_STATE_BELOW":
                update_wm_state("below")
            elif atom1 == "_NET_WM_STATE_SHADED":
                update_wm_state("shaded")
            elif atom1 == "_NET_WM_STATE_STICKY":
                update_wm_state("sticky")
            elif atom1 == "_NET_WM_STATE_SKIP_TASKBAR":
                update_wm_state("skip-taskbar")
            elif atom1 == "_NET_WM_STATE_SKIP_PAGER":
                update_wm_state("skip-pager")
                get_pyatom(event.window, event.data[2])
            elif atom1 in ("_NET_WM_STATE_MAXIMIZED_VERT",
                           "_NET_WM_STATE_MAXIMIZED_HORZ"):
                atom2 = get_pyatom(event.window, event.data[2])
                #we only have one state for both, so we require both to be set:
                if atom1 != atom2 and atom2 in (
                        "_NET_WM_STATE_MAXIMIZED_VERT",
                        "_NET_WM_STATE_MAXIMIZED_HORZ"):
                    update_wm_state("maximized")
            elif atom1 == "_NET_WM_STATE_HIDDEN":
                log("ignoring 'HIDDEN' _NET_WM_STATE: %s", event)
                #we don't honour those because they make little sense, see:
                #https://mail.gnome.org/archives/wm-spec-list/2005-May/msg00004.html
            elif atom1 == "_NET_WM_STATE_MODAL":
                update_wm_state("modal")
            elif atom1 == "_NET_WM_STATE_DEMANDS_ATTENTION":
                update_wm_state("attention-requested")
            else:
                log.info("Unhandled _NET_WM_STATE request: '%s'", event, atom1)
                log.info(" event%s", event)
            return True
        if event.message_type == "WM_CHANGE_STATE":
            iconic = event.data[0]
            log("WM_CHANGE_STATE: %s, serial=%s, last unmap serial=%#x",
                ICONIC_STATE_STRING.get(iconic, iconic), event.serial,
                self.last_unmap_serial)
            if (iconic in (IconicState, NormalState)
                    and self.serial_after_last_unmap(event.serial)
                    and not self.is_OR() and not self.is_tray()):
                self._updateprop("iconic", iconic == IconicState)
            return True
        if event.message_type == "_NET_WM_MOVERESIZE":
            log("_NET_WM_MOVERESIZE: %s", event)
            self.emit("initiate-moveresize", event)
            return True
        if event.message_type == "_NET_ACTIVE_WINDOW" and event.data[0] in (0,
                                                                            1):
            log("_NET_ACTIVE_WINDOW: %s", event)
            self.set_active()
            self.emit("raised", event)
            return True
        if event.message_type == "_NET_WM_DESKTOP":
            workspace = int(event.data[0])
            #query the workspace count on the root window
            #since we cannot access Wm from here..
            root = self.client_window.get_screen().get_root_window()
            ndesktops = prop_get(root,
                                 "_NET_NUMBER_OF_DESKTOPS",
                                 "u32",
                                 ignore_errors=True)
            workspacelog(
                "received _NET_WM_DESKTOP: workspace=%s, number of desktops=%s",
                workspacestr(workspace), ndesktops)
            if ndesktops > 0 and (workspace in (WORKSPACE_UNSET, WORKSPACE_ALL)
                                  or 0 <= workspace < ndesktops):
                self.move_to_workspace(workspace)
            else:
                workspacelog.warn(
                    "invalid _NET_WM_DESKTOP request: workspace=%s, number of desktops=%s",
                    workspacestr(workspace), ndesktops)
            return True
        if event.message_type == "_NET_WM_FULLSCREEN_MONITORS":
            log("_NET_WM_FULLSCREEN_MONITORS: %s", event)
            #TODO: we should validate the indexes instead of copying them blindly!
            #TODO: keep track of source indication so we can forward that to the client
            m1, m2, m3, m4 = event.data[0], event.data[1], event.data[
                2], event.data[3]
            N = 16  #FIXME: arbitrary limit
            if m1 < 0 or m1 >= N or m2 < 0 or m2 >= N or m3 < 0 or m3 >= N or m4 < 0 or m4 >= N:
                log.warn(
                    "invalid list of _NET_WM_FULLSCREEN_MONITORS - ignored")
                return False
            monitors = [m1, m2, m3, m4]
            log("_NET_WM_FULLSCREEN_MONITORS: monitors=%s", monitors)
            prop_set(self.client_window, "_NET_WM_FULLSCREEN_MONITORS",
                     ["u32"], monitors)
            return True
        #TODO: maybe we should process _NET_MOVERESIZE_WINDOW here?
        # it may make sense to apply it to the client_window
        # whereas the code in WindowModel assumes there is a corral window
        #not handled:
        return CoreX11WindowModel.process_client_message_event(self, event)