Ejemplo n.º 1
0
    def _set_wm_state(self, *states):
        # Set property
        net_wm_state = xlib.XInternAtom(self._x_display, '_NET_WM_STATE',
                                        False)
        atoms = []
        for state in states:
            atoms.append(xlib.XInternAtom(self._x_display, state, False))
        atom_type = xlib.XInternAtom(self._x_display, 'ATOM', False)
        if len(atoms):
            atoms_ar = (xlib.Atom * len(atoms))(*atoms)
            xlib.XChangeProperty(self._x_display, self._window, net_wm_state,
                                 atom_type, 32, xlib.PropModePrepend,
                                 cast(pointer(atoms_ar), POINTER(c_ubyte)),
                                 len(atoms))
        else:
            xlib.XDeleteProperty(self._x_display, self._window, net_wm_state)

        # Nudge the WM
        e = xlib.XEvent()
        e.xclient.type = xlib.ClientMessage
        e.xclient.message_type = net_wm_state
        e.xclient.display = cast(self._x_display, POINTER(xlib.Display))
        e.xclient.window = self._window
        e.xclient.format = 32
        e.xclient.data.l[0] = xlib.PropModePrepend
        for i, atom in enumerate(atoms):
            e.xclient.data.l[i + 1] = atom
        xlib.XSendEvent(self._x_display, self._get_root(), False,
                        xlib.SubstructureRedirectMask, byref(e))
Ejemplo n.º 2
0
 def _set_atoms_property(self, name, values, mode=xlib.PropModeReplace):
     name_atom = xlib.XInternAtom(self._x_display, name, False)
     atoms = []
     for value in values:
         atoms.append(xlib.XInternAtom(self._x_display, value, False))
     atom_type = xlib.XInternAtom(self._x_display, 'ATOM', False)
     if len(atoms):
         atoms_ar = (xlib.Atom * len(atoms))(*atoms)
         xlib.XChangeProperty(self._x_display, self._window, name_atom,
                              atom_type, 32, mode,
                              cast(pointer(atoms_ar), POINTER(c_ubyte)),
                              len(atoms))
     else:
         xlib.XDeleteProperty(self._x_display, self._window, net_wm_state)
Ejemplo n.º 3
0
    def set_icon(self, *images):
        # Careful!  XChangeProperty takes an array of long when data type
        # is 32-bit (but long can be 64 bit!), so pad high bytes of format if
        # necessary.

        import sys
        format = {
            ('little', 4): 'BGRA',
            ('little', 8): 'BGRAAAAA',
            ('big', 4): 'ARGB',
            ('big', 8): 'AAAAARGB'
        }[(sys.byteorder, sizeof(c_ulong))]

        data = ''
        for image in images:
            image = image.image_data
            image.format = format
            image.pitch = -(image.width * len(image.format))
            s = c_buffer(sizeof(c_ulong) * 2)
            memmove(
                s,
                cast((c_ulong * 2)(image.width, image.height),
                     POINTER(c_ubyte)), len(s))
            data += s.raw + image.data
        buffer = (c_ubyte * len(data))()
        memmove(buffer, data, len(data))
        atom = xlib.XInternAtom(self._x_display, '_NET_WM_ICON', False)
        XA_CARDINAL = 6  # Xatom.h:14
        xlib.XChangeProperty(self._x_display, self._window, atom, XA_CARDINAL,
                             32, xlib.PropModeReplace, buffer,
                             len(data) / sizeof(c_ulong))
Ejemplo n.º 4
0
 def _set_text_property(self, name, value, allow_utf8=True):
     atom = xlib.XInternAtom(self._x_display, name, False)
     if not atom:
         raise XlibException('Undefined atom "%s"' % name)
     assert type(value) in (str, unicode)
     property = xlib.XTextProperty()
     if _have_utf8 and allow_utf8:
         buf = create_string_buffer(value.encode('utf8'))
         result = xlib.Xutf8TextListToTextProperty(
             self._x_display, cast(pointer(buf), c_char_p), 1,
             xlib.XStdICCTextStyle, byref(property))
         if result < 0:
             raise XlibException('Could not create UTF8 text property')
     else:
         buf = create_string_buffer(value.encode('ascii', 'ignore'))
         result = xlib.XStringListToTextProperty(
             cast(pointer(buf), c_char_p), 1, byref(property))
         if result < 0:
             raise XlibException('Could not create text property')
     xlib.XSetTextProperty(self._x_display, self._window, byref(property),
                           atom)
Ejemplo n.º 5
0
    def _create(self):
        # Unmap existing window if necessary while we fiddle with it.
        if self._window and self._mapped:
            self._unmap()

        self.context.window = self
        self._x_display = self.config._display
        self._x_screen_id = self.screen._x_screen_id
        self._glx_context = self.context._context

        self._glx_1_3 = self.display.info.have_version(1, 3)
        self._have_SGI_video_sync = \
            self.display.info.have_extension('GLX_SGI_video_sync')
        self._have_SGI_swap_control = \
            self.display.info.have_extension('GLX_SGI_swap_control')
        self._have_MESA_swap_control = \
            self.display.info.have_extension('GLX_MESA_swap_control')

        # In order of preference:
        # 1. GLX_MESA_swap_control (more likely to work where video_sync will
        #    not)
        # 2. GLX_SGI_video_sync (does not work on Intel 945GM, but that has
        #    MESA)
        # 3. GLX_SGI_swap_control (cannot be disabled once enabled).
        self._use_video_sync = (self._have_SGI_video_sync
                                and not self._have_MESA_swap_control)

        # Create X window if not already existing.
        if not self._window:
            root = xlib.XRootWindow(self._x_display, self._x_screen_id)

            visual_info = self.config.get_visual_info()

            visual = visual_info.visual
            visual_id = xlib.XVisualIDFromVisual(visual)
            default_visual = xlib.XDefaultVisual(self._x_display,
                                                 self._x_screen_id)
            default_visual_id = xlib.XVisualIDFromVisual(default_visual)
            window_attributes = xlib.XSetWindowAttributes()
            if visual_id != default_visual_id:
                window_attributes.colormap = xlib.XCreateColormap(
                    self._x_display, root, visual, xlib.AllocNone)
            else:
                window_attributes.colormap = xlib.XDefaultColormap(
                    self._x_display, self._x_screen_id)
            self._window = xlib.XCreateWindow(self._x_display, root, 0, 0,
                                              self._width, self._height, 0,
                                              visual_info.depth,
                                              xlib.InputOutput, visual,
                                              xlib.CWColormap,
                                              byref(window_attributes))

            # Setting null background pixmap disables drawing the background,
            # preventing flicker while resizing (in theory).
            xlib.XSetWindowBackgroundPixmap(self._x_display, self._window, 0)

            # Enable WM_DELETE_WINDOW message
            wm_delete_window = xlib.XInternAtom(self._x_display,
                                                'WM_DELETE_WINDOW', False)
            wm_delete_window = c_ulong(wm_delete_window)
            xlib.XSetWMProtocols(self._x_display, self._window,
                                 byref(wm_delete_window), 1)

        # Set window attributes
        attributes = xlib.XSetWindowAttributes()
        attributes_mask = 0

        # Bypass the window manager in fullscreen.  This is the only reliable
        # technique (over _NET_WM_STATE_FULLSCREEN, Motif, KDE and Gnome
        # hints) that is pretty much guaranteed to work.  Unfortunately
        # we run into window activation and focus problems that require
        # attention.  Search for "override_redirect" for all occurences.
        attributes.override_redirect = self._fullscreen
        attributes_mask |= xlib.CWOverrideRedirect

        if self._fullscreen:
            xlib.XMoveResizeWindow(self._x_display, self._window,
                                   self.screen.x, self.screen.y,
                                   self.screen.width, self.screen.height)
        else:
            xlib.XResizeWindow(self._x_display, self._window, self._width,
                               self._height)

        xlib.XChangeWindowAttributes(self._x_display, self._window,
                                     attributes_mask, byref(attributes))

        # Set style
        styles = {
            self.WINDOW_STYLE_DEFAULT: '_NET_WM_WINDOW_TYPE_NORMAL',
            self.WINDOW_STYLE_DIALOG: '_NET_WM_WINDOW_TYPE_DIALOG',
            self.WINDOW_STYLE_TOOL: '_NET_WM_WINDOW_TYPE_UTILITY',
        }
        if self._style in styles:
            self._set_atoms_property('_NET_WM_WINDOW_TYPE',
                                     (styles[self._style], ))
        elif self._style == self.WINDOW_STYLE_BORDERLESS:
            MWM_HINTS_DECORATIONS = 1 << 1
            PROP_MWM_HINTS_ELEMENTS = 5
            mwmhints = mwmhints_t()
            mwmhints.flags = MWM_HINTS_DECORATIONS
            mwmhints.decorations = 0
            name = xlib.XInternAtom(self._x_display, '_MOTIF_WM_HINTS', False)
            xlib.XChangeProperty(self._x_display, self._window, name, name, 32,
                                 xlib.PropModeReplace,
                                 cast(pointer(mwmhints), POINTER(c_ubyte)),
                                 PROP_MWM_HINTS_ELEMENTS)

        # Set resizeable
        if not self._resizable:
            self.set_minimum_size(self._width, self._height)
            self.set_maximum_size(self._width, self._height)

        # Set caption
        self.set_caption(self._caption)

        self.switch_to()
        if self._visible:
            self.set_visible(True)

        # Create input context.  A good but very outdated reference for this
        # is http://www.sbin.org/doc/Xlib/chapt_11.html
        if _have_utf8:
            self._x_im = xlib.XOpenIM(self._x_display, None, None, None)
            # TODO select best input style.
            self._x_ic = xlib.XCreateIC(
                self._x_im, 'inputStyle',
                xlib.XIMPreeditNothing | xlib.XIMStatusNothing, None)
            xlib.XSetICFocus(self._x_ic)
Ejemplo n.º 6
0
 def _event_clientmessage(self, ev):
     wm_delete_window = xlib.XInternAtom(ev.xclient.display,
                                         'WM_DELETE_WINDOW', False)
     if ev.xclient.data.l[0] == wm_delete_window:
         self.dispatch_event('on_close')