Exemplo n.º 1
0
 def _event_clientmessage(self, ev):
     atom = ev.xclient.data.l[0]
     if atom == xlib.XInternAtom(ev.xclient.display,
                                 asbytes('WM_DELETE_WINDOW'), False):
         self.dispatch_event('on_close')
     elif (self._enable_xsync and atom == xlib.XInternAtom(
             ev.xclient.display, asbytes('_NET_WM_SYNC_REQUEST'), False)):
         lo = ev.xclient.data.l[2]
         hi = ev.xclient.data.l[3]
         self._current_sync_value = xsync.XSyncValue(hi, lo)
Exemplo n.º 2
0
    def _create(self):
        # Unmap existing window if necessary while we fiddle with it.
        if self._window and self._mapped:
            self._unmap()

        self._x_display = self.display._display
        self._x_screen_id = self.display.x_screen


        # 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)
            window_attributes.bit_gravity = xlib.StaticGravity

            # Issue 287: Compiz on Intel/Mesa doesn't draw window decoration
            #            unless CWBackPixel is given in mask.  Should have
            #            no effect on other systems, so it's set
            #            unconditionally.
            mask = xlib.CWColormap | xlib.CWBitGravity | xlib.CWBackPixel

            if self._fullscreen:
                width, height = self.screen.width, self.screen.height
                self._view_x = (width - self._width) // 2
                self._view_y = (height - self._height) // 2
            else:
                width, height = self._width, self._height
                self._view_x = self._view_y = 0

            self._window = xlib.XCreateWindow(self._x_display, root,
                0, 0, width, height, 0, visual_info.depth,
                xlib.InputOutput, visual, mask,
                byref(window_attributes))
            self._view = xlib.XCreateWindow(self._x_display, 
                self._window, self._view_x, self._view_y, 
                self._width, self._height, 0, visual_info.depth, 
                xlib.InputOutput, visual, mask, 
                byref(window_attributes));
            xlib.XMapWindow(self._x_display, self._view)
            xlib.XSelectInput(
                self._x_display, self._view, self._default_event_mask)

            self.display._window_map[self._window] = \
                self.dispatch_platform_event
            self.display._window_map[self._view] = \
                self.dispatch_platform_event_view

            self.canvas = XlibCanvas(self.display, self._view)

            self.context.attach(self.canvas)
            self.context.set_vsync(self._vsync) # XXX ?

            # Setting null background pixmap disables drawing the background,
            # preventing flicker while resizing (in theory).
            #
            # Issue 287: Compiz on Intel/Mesa doesn't draw window decoration if
            #            this is called.  As it doesn't seem to have any
            #            effect anyway, it's just commented out.
            #xlib.XSetWindowBackgroundPixmap(self._x_display, self._window, 0)

            self._enable_xsync = (pyglet.options['xsync'] and
                                  self.display._enable_xsync and
                                  self.config.double_buffer)

            # Set supported protocols
            protocols = []
            protocols.append(xlib.XInternAtom(self._x_display,
                                              asbytes('WM_DELETE_WINDOW'), False))
            if self._enable_xsync:
                protocols.append(xlib.XInternAtom(self._x_display,
                                                  asbytes('_NET_WM_SYNC_REQUEST'),
                                                  False))
            protocols = (c_ulong * len(protocols))(*protocols)
            xlib.XSetWMProtocols(self._x_display, self._window,
                                 protocols, len(protocols))

            # Create window resize sync counter
            if self._enable_xsync:
                value = xsync.XSyncValue()
                self._sync_counter = xlib.XID(
                    xsync.XSyncCreateCounter(self._x_display, value))
                atom = xlib.XInternAtom(self._x_display,
                                        asbytes('_NET_WM_SYNC_REQUEST_COUNTER'), False)
                ptr = pointer(self._sync_counter)

                xlib.XChangeProperty(self._x_display, self._window,
                                     atom, XA_CARDINAL, 32,
                                     xlib.PropModeReplace,
                                     cast(ptr, POINTER(c_ubyte)), 1)
        # Set window attributes
        attributes = xlib.XSetWindowAttributes()
        attributes_mask = 0

        self._override_redirect = False
        if self._fullscreen:
            if pyglet.options['xlib_fullscreen_override_redirect']:
                # Try not to use this any more, it causes problems; disabled
                # by default in favour of _NET_WM_STATE_FULLSCREEN.
                attributes.override_redirect = self._fullscreen
                attributes_mask |= xlib.CWOverrideRedirect
                self._override_redirect = True
            else:
                self._set_wm_state('_NET_WM_STATE_FULLSCREEN')

        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 and not self._fullscreen:
            self.set_minimum_size(self._width, self._height)
            self.set_maximum_size(self._width, self._height)

        # Set caption
        self.set_caption(self._caption)

        # Create input context.  A good but very outdated reference for this
        # is http://www.sbin.org/doc/Xlib/chapt_11.html
        if _have_utf8 and not self._x_ic:
            if not self.display._x_im:
                xlib.XSetLocaleModifiers(asbytes('@im=none'))
                self.display._x_im = \
                    xlib.XOpenIM(self._x_display, None, None, None)

            xlib.XFlush(self._x_display);

            # Need to set argtypes on this function because it's vararg,
            # and ctypes guesses wrong.
            xlib.XCreateIC.argtypes = [xlib.XIM,    
                                       c_char_p, c_int,
                                       c_char_p, xlib.Window,
                                       c_char_p, xlib.Window,
                                       c_void_p]
            self._x_ic = xlib.XCreateIC(self.display._x_im, 
                asbytes('inputStyle'), xlib.XIMPreeditNothing|xlib.XIMStatusNothing,
                asbytes('clientWindow'), self._window,
                asbytes('focusWindow'), self._window,
                None)

            filter_events = c_ulong()
            xlib.XGetICValues(self._x_ic,
                              'filterEvents', byref(filter_events),
                              None)
            self._default_event_mask |= filter_events.value
            xlib.XSetICFocus(self._x_ic)

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

        self.set_mouse_platform_visible()
        self._applied_mouse_exclusive = None
        self._update_exclusivity()