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))
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.get_image_data() pitch = -(image.width * len(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.get_data(format, pitch) buffer = (c_ubyte * len(data))() memmove(buffer, data, len(data)) atom = xlib.XInternAtom(self._x_display, '_NET_WM_ICON', False) xlib.XChangeProperty(self._x_display, self._window, atom, XA_CARDINAL, 32, xlib.PropModeReplace, buffer, len(data)/sizeof(c_ulong))
def _set_atoms_property(self, name, values, mode=xlib.PropModeReplace): name_atom = xlib.XInternAtom(self._x_display, asbytes(name), False) atoms = [] for value in values: atoms.append(xlib.XInternAtom(self._x_display, asbytes(value), False)) atom_type = xlib.XInternAtom(self._x_display, asbytes('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)
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()