feat: add various system and theme icons, configuration files, and support assets

This commit is contained in:
jschantli committed 2026-10-03 08:14:42 -07:00
1 parent 848dac4264
commit 54baea79f4
15893 files changed
+781426 -2

No files matched your search

@@ -0,0 +1,72 @@
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2010 Simon van der Linden <svdlinden@src.gnome.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
from ..overrides import override
from ..module import get_introspection_module
GIMarshallingTests = get_introspection_module('GIMarshallingTests')
__all__ = []
OVERRIDES_CONSTANT = 7
__all__.append('OVERRIDES_CONSTANT')
class OverridesStruct(GIMarshallingTests.OverridesStruct):
def __new__(cls, long_):
return GIMarshallingTests.OverridesStruct.__new__(cls)
def __init__(self, long_):
GIMarshallingTests.OverridesStruct.__init__(self)
self.long_ = long_
def method(self):
return GIMarshallingTests.OverridesStruct.method(self) / 7
OverridesStruct = override(OverridesStruct)
__all__.append('OverridesStruct')
class OverridesObject(GIMarshallingTests.OverridesObject):
def __new__(cls, long_):
return GIMarshallingTests.OverridesObject.__new__(cls)
def __init__(self, long_):
GIMarshallingTests.OverridesObject.__init__(self)
# FIXME: doesn't work yet
# self.long_ = long_
@classmethod
def new(cls, long_):
self = GIMarshallingTests.OverridesObject.new()
# FIXME: doesn't work yet
# self.long_ = long_
return self
def method(self):
"""Overridden doc string."""
return GIMarshallingTests.OverridesObject.method(self) / 7
OverridesObject = override(OverridesObject)
__all__.append('OverridesObject')
@@ -0,0 +1,884 @@
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2010 Tomeu Vizoso <tomeu.vizoso@collabora.co.uk>
# Copyright (C) 2011, 2012 Canonical Ltd.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
import warnings
import sys
import socket
from .._ossighelper import wakeup_on_signal, register_sigint_fallback
from ..module import get_introspection_module
from .._gi import (variant_type_from_string, source_new,
source_set_callback, io_channel_read)
from ..overrides import override, deprecated, deprecated_attr
from gi import PyGIDeprecationWarning, version_info
GLib = get_introspection_module('GLib')
__all__ = []
from gi import _option as option
option # pyflakes
__all__.append('option')
# Types and functions still needed from static bindings
from gi import _gi
from gi._error import GError
Error = GError
OptionContext = _gi.OptionContext
OptionGroup = _gi.OptionGroup
Pid = _gi.Pid
spawn_async = _gi.spawn_async
def threads_init():
warnings.warn('Since version 3.11, calling threads_init is no longer needed. '
'See: https://wiki.gnome.org/PyGObject/Threading',
PyGIDeprecationWarning, stacklevel=2)
def gerror_matches(self, domain, code):
# Handle cases where self.domain was set to an integer for compatibility
# with the introspected GLib.Error.
if isinstance(self.domain, str):
self_domain_quark = GLib.quark_from_string(self.domain)
else:
self_domain_quark = self.domain
return (self_domain_quark, self.code) == (domain, code)
def gerror_new_literal(domain, message, code):
domain_quark = GLib.quark_to_string(domain)
return GError(message, domain_quark, code)
# Monkey patch methods that rely on GLib introspection to be loaded at runtime.
Error.__name__ = 'Error'
Error.__module__ = 'gi.repository.GLib'
Error.__gtype__ = GLib.Error.__gtype__
Error.matches = gerror_matches
Error.new_literal = staticmethod(gerror_new_literal)
__all__ += ['GError', 'Error', 'OptionContext', 'OptionGroup', 'Pid',
'spawn_async', 'threads_init']
class _VariantCreator(object):
_LEAF_CONSTRUCTORS = {
'b': GLib.Variant.new_boolean,
'y': GLib.Variant.new_byte,
'n': GLib.Variant.new_int16,
'q': GLib.Variant.new_uint16,
'i': GLib.Variant.new_int32,
'u': GLib.Variant.new_uint32,
'x': GLib.Variant.new_int64,
't': GLib.Variant.new_uint64,
'h': GLib.Variant.new_handle,
'd': GLib.Variant.new_double,
's': GLib.Variant.new_string,
'o': GLib.Variant.new_object_path,
'g': GLib.Variant.new_signature,
'v': GLib.Variant.new_variant,
}
def _create(self, format, value):
"""Create a GVariant object from given format and a value that matches
the format.
This method recursively calls itself for complex structures (arrays,
dictionaries, boxed).
Returns the generated GVariant.
If value is None it will generate an empty GVariant container type.
"""
gvtype = GLib.VariantType(format)
if format in self._LEAF_CONSTRUCTORS:
return self._LEAF_CONSTRUCTORS[format](value)
# Since we discarded all leaf types, this must be a container
builder = GLib.VariantBuilder.new(gvtype)
if value is None:
return builder.end()
if gvtype.is_maybe():
builder.add_value(self._create(gvtype.element().dup_string(), value))
return builder.end()
try:
iter(value)
except TypeError:
raise TypeError("Could not create array, tuple or dictionary entry from non iterable value %s %s" %
(format, value))
if gvtype.is_tuple() and gvtype.n_items() != len(value):
raise TypeError("Tuple mismatches value's number of elements %s %s" % (format, value))
if gvtype.is_dict_entry() and len(value) != 2:
raise TypeError("Dictionary entries must have two elements %s %s" % (format, value))
if gvtype.is_array():
element_type = gvtype.element().dup_string()
if isinstance(value, dict):
value = value.items()
for i in value:
builder.add_value(self._create(element_type, i))
else:
remainer_format = format[1:]
for i in value:
dup = variant_type_from_string(remainer_format).dup_string()
builder.add_value(self._create(dup, i))
remainer_format = remainer_format[len(dup):]
return builder.end()
LEAF_ACCESSORS = {
'b': 'get_boolean',
'y': 'get_byte',
'n': 'get_int16',
'q': 'get_uint16',
'i': 'get_int32',
'u': 'get_uint32',
'x': 'get_int64',
't': 'get_uint64',
'h': 'get_handle',
'd': 'get_double',
's': 'get_string',
'o': 'get_string', # object path
'g': 'get_string', # signature
}
class Variant(GLib.Variant):
def __new__(cls, format_string, value):
"""Create a GVariant from a native Python object.
format_string is a standard GVariant type signature, value is a Python
object whose structure has to match the signature.
Examples:
GLib.Variant('i', 1)
GLib.Variant('(is)', (1, 'hello'))
GLib.Variant('(asa{sv})', ([], {'foo': GLib.Variant('b', True),
'bar': GLib.Variant('i', 2)}))
"""
if not GLib.VariantType.string_is_valid(format_string):
raise TypeError("Invalid GVariant format string '%s'", format_string)
creator = _VariantCreator()
v = creator._create(format_string, value)
v.format_string = format_string
return v
@staticmethod
def new_tuple(*elements):
return GLib.Variant.new_tuple(elements)
def __del__(self):
try:
self.unref()
except ImportError:
# Calling unref will cause gi and gi.repository.GLib to be
# imported. However, if the program is exiting, then these
# modules have likely been removed from sys.modules and will
# raise an exception. Assume that's the case for ImportError
# and ignore the exception since everything will be cleaned
# up, anyways.
pass
def __str__(self):
return self.print_(True)
def __repr__(self):
if hasattr(self, 'format_string'):
f = self.format_string
else:
f = self.get_type_string()
return "GLib.Variant('%s', %s)" % (f, self.print_(False))
def __eq__(self, other):
try:
return self.equal(other)
except TypeError:
return False
def __ne__(self, other):
try:
return not self.equal(other)
except TypeError:
return True
def __hash__(self):
# We're not using just hash(self.unpack()) because otherwise we'll have
# hash collisions between the same content in different variant types,
# which will cause a performance issue in set/dict/etc.
return hash((self.get_type_string(), self.unpack()))
def unpack(self):
"""Decompose a GVariant into a native Python object."""
type_string = self.get_type_string()
# simple values
la = LEAF_ACCESSORS.get(type_string)
if la:
return getattr(self, la)()
# tuple
if type_string.startswith('('):
return tuple(self.get_child_value(i).unpack()
for i in range(self.n_children()))
# dictionary
if type_string.startswith('a{'):
res = {}
for i in range(self.n_children()):
v = self.get_child_value(i)
res[v.get_child_value(0).unpack()] = v.get_child_value(1).unpack()
return res
# array
if type_string.startswith('a'):
return [self.get_child_value(i).unpack()
for i in range(self.n_children())]
# variant (just unbox transparently)
if type_string.startswith('v'):
return self.get_variant().unpack()
# maybe
if type_string.startswith('m'):
if not self.n_children():
return None
return self.get_child_value(0).unpack()
raise NotImplementedError('unsupported GVariant type ' + type_string)
@classmethod
def split_signature(klass, signature):
"""Return a list of the element signatures of the topmost signature tuple.
If the signature is not a tuple, it returns one element with the entire
signature. If the signature is an empty tuple, the result is [].
This is useful for e. g. iterating over method parameters which are
passed as a single Variant.
"""
if signature == '()':
return []
if not signature.startswith('('):
return [signature]
result = []
head = ''
tail = signature[1:-1] # eat the surrounding ()
while tail:
c = tail[0]
head += c
tail = tail[1:]
if c in ('m', 'a'):
# prefixes, keep collecting
continue
if c in ('(', '{'):
# consume until corresponding )/}
level = 1
up = c
if up == '(':
down = ')'
else:
down = '}'
while level > 0:
c = tail[0]
head += c
tail = tail[1:]
if c == up:
level += 1
elif c == down:
level -= 1
# otherwise we have a simple type
result.append(head)
head = ''
return result
#
# Pythonic iterators
#
def __len__(self):
if self.get_type_string() in ['s', 'o', 'g']:
return len(self.get_string())
# Array, dict, tuple
if self.get_type_string().startswith('a') or self.get_type_string().startswith('('):
return self.n_children()
raise TypeError('GVariant type %s does not have a length' % self.get_type_string())
def __getitem__(self, key):
# dict
if self.get_type_string().startswith('a{'):
try:
val = self.lookup_value(key, variant_type_from_string('*'))
if val is None:
raise KeyError(key)
return val.unpack()
except TypeError:
# lookup_value() only works for string keys, which is certainly
# the common case; we have to do painful iteration for other
# key types
for i in range(self.n_children()):
v = self.get_child_value(i)
if v.get_child_value(0).unpack() == key:
return v.get_child_value(1).unpack()
raise KeyError(key)
# array/tuple
if self.get_type_string().startswith('a') or self.get_type_string().startswith('('):
key = int(key)
if key < 0:
key = self.n_children() + key
if key < 0 or key >= self.n_children():
raise IndexError('list index out of range')
return self.get_child_value(key).unpack()
# string
if self.get_type_string() in ['s', 'o', 'g']:
return self.get_string().__getitem__(key)
raise TypeError('GVariant type %s is not a container' % self.get_type_string())
#
# Pythonic bool operations
#
def __nonzero__(self):
return self.__bool__()
def __bool__(self):
if self.get_type_string() in ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']:
return self.unpack() != 0
if self.get_type_string() in ['b']:
return self.get_boolean()
if self.get_type_string() in ['s', 'o', 'g']:
return len(self.get_string()) != 0
# Array, dict, tuple
if self.get_type_string().startswith('a') or self.get_type_string().startswith('('):
return self.n_children() != 0
# unpack works recursively, hence bool also works recursively
return bool(self.unpack())
def keys(self):
if not self.get_type_string().startswith('a{'):
raise TypeError('GVariant type %s is not a dictionary' % self.get_type_string())
res = []
for i in range(self.n_children()):
v = self.get_child_value(i)
res.append(v.get_child_value(0).unpack())
return res
def get_string(self):
value, length = GLib.Variant.get_string(self)
return value
setattr(Variant, 'get_string', get_string)
__all__.append('Variant')
def markup_escape_text(text, length=-1):
if isinstance(text, bytes):
return GLib.markup_escape_text(text.decode('UTF-8'), length)
else:
return GLib.markup_escape_text(text, length)
__all__.append('markup_escape_text')
# backwards compatible names from old static bindings
for n in ['DESKTOP', 'DOCUMENTS', 'DOWNLOAD', 'MUSIC', 'PICTURES',
'PUBLIC_SHARE', 'TEMPLATES', 'VIDEOS']:
attr = 'USER_DIRECTORY_' + n
deprecated_attr("GLib", attr, "GLib.UserDirectory.DIRECTORY_" + n)
globals()[attr] = getattr(GLib.UserDirectory, 'DIRECTORY_' + n)
__all__.append(attr)
for n in ['ERR', 'HUP', 'IN', 'NVAL', 'OUT', 'PRI']:
globals()['IO_' + n] = getattr(GLib.IOCondition, n)
__all__.append('IO_' + n)
for n in ['APPEND', 'GET_MASK', 'IS_READABLE', 'IS_SEEKABLE',
'MASK', 'NONBLOCK', 'SET_MASK']:
attr = 'IO_FLAG_' + n
deprecated_attr("GLib", attr, "GLib.IOFlags." + n)
globals()[attr] = getattr(GLib.IOFlags, n)
__all__.append(attr)
# spelling for the win
IO_FLAG_IS_WRITEABLE = GLib.IOFlags.IS_WRITABLE
deprecated_attr("GLib", "IO_FLAG_IS_WRITEABLE", "GLib.IOFlags.IS_WRITABLE")
__all__.append('IO_FLAG_IS_WRITEABLE')
for n in ['AGAIN', 'EOF', 'ERROR', 'NORMAL']:
attr = 'IO_STATUS_' + n
globals()[attr] = getattr(GLib.IOStatus, n)
deprecated_attr("GLib", attr, "GLib.IOStatus." + n)
__all__.append(attr)
for n in ['CHILD_INHERITS_STDIN', 'DO_NOT_REAP_CHILD', 'FILE_AND_ARGV_ZERO',
'LEAVE_DESCRIPTORS_OPEN', 'SEARCH_PATH', 'STDERR_TO_DEV_NULL',
'STDOUT_TO_DEV_NULL']:
attr = 'SPAWN_' + n
globals()[attr] = getattr(GLib.SpawnFlags, n)
deprecated_attr("GLib", attr, "GLib.SpawnFlags." + n)
__all__.append(attr)
for n in ['HIDDEN', 'IN_MAIN', 'REVERSE', 'NO_ARG', 'FILENAME', 'OPTIONAL_ARG',
'NOALIAS']:
attr = 'OPTION_FLAG_' + n
globals()[attr] = getattr(GLib.OptionFlags, n)
deprecated_attr("GLib", attr, "GLib.OptionFlags." + n)
__all__.append(attr)
for n in ['UNKNOWN_OPTION', 'BAD_VALUE', 'FAILED']:
attr = 'OPTION_ERROR_' + n
deprecated_attr("GLib", attr, "GLib.OptionError." + n)
globals()[attr] = getattr(GLib.OptionError, n)
__all__.append(attr)
# these are not currently exported in GLib gir, presumably because they are
# platform dependent; so get them from our static bindings
for name in ['G_MINFLOAT', 'G_MAXFLOAT', 'G_MINDOUBLE', 'G_MAXDOUBLE',
'G_MINSHORT', 'G_MAXSHORT', 'G_MAXUSHORT', 'G_MININT', 'G_MAXINT',
'G_MAXUINT', 'G_MINLONG', 'G_MAXLONG', 'G_MAXULONG', 'G_MAXSIZE',
'G_MINSSIZE', 'G_MAXSSIZE', 'G_MINOFFSET', 'G_MAXOFFSET']:
attr = name.split("_", 1)[-1]
globals()[attr] = getattr(_gi, name)
__all__.append(attr)
class MainLoop(GLib.MainLoop):
# Backwards compatible constructor API
def __new__(cls, context=None):
return GLib.MainLoop.new(context, False)
def __init__(self, context=None):
pass
def run(self):
with register_sigint_fallback(self.quit):
with wakeup_on_signal():
super(MainLoop, self).run()
MainLoop = override(MainLoop)
__all__.append('MainLoop')
class MainContext(GLib.MainContext):
# Backwards compatible API with default value
def iteration(self, may_block=True):
return super(MainContext, self).iteration(may_block)
MainContext = override(MainContext)
__all__.append('MainContext')
class Source(GLib.Source):
def __new__(cls, *args, **kwargs):
# use our custom pygi_source_new() here as g_source_new() is not
# bindable
source = source_new()
source.__class__ = cls
setattr(source, '__pygi_custom_source', True)
return source
def __init__(self, *args, **kwargs):
return super(Source, self).__init__()
def __del__(self):
if hasattr(self, '__pygi_custom_source'):
# We destroy and finalize the box from here, as GLib might hold
# a reference (e.g. while the source is pending), delaying the
# finalize call until a later point.
self.destroy()
self.finalize()
self._clear_boxed()
def finalize(self):
pass
def set_callback(self, fn, user_data=None):
if hasattr(self, '__pygi_custom_source'):
# use our custom pygi_source_set_callback() if for a GSource object
# with custom functions
source_set_callback(self, fn, user_data)
else:
# otherwise, for Idle and Timeout, use the standard method
super(Source, self).set_callback(fn, user_data)
def get_current_time(self):
return GLib.get_real_time() * 0.000001
get_current_time = deprecated(get_current_time,
'GLib.Source.get_time() or GLib.get_real_time()')
# as get/set_priority are introspected, we can't use the static
# property(get_priority, ..) here
def __get_priority(self):
return self.get_priority()
def __set_priority(self, value):
self.set_priority(value)
priority = property(__get_priority, __set_priority)
def __get_can_recurse(self):
return self.get_can_recurse()
def __set_can_recurse(self, value):
self.set_can_recurse(value)
can_recurse = property(__get_can_recurse, __set_can_recurse)
Source = override(Source)
__all__.append('Source')
class Idle(Source):
def __new__(cls, priority=GLib.PRIORITY_DEFAULT):
source = GLib.idle_source_new()
source.__class__ = cls
return source
def __init__(self, priority=GLib.PRIORITY_DEFAULT):
super(Source, self).__init__()
if priority != GLib.PRIORITY_DEFAULT:
self.set_priority(priority)
__all__.append('Idle')
class Timeout(Source):
def __new__(cls, interval=0, priority=GLib.PRIORITY_DEFAULT):
source = GLib.timeout_source_new(interval)
source.__class__ = cls
return source
def __init__(self, interval=0, priority=GLib.PRIORITY_DEFAULT):
if priority != GLib.PRIORITY_DEFAULT:
self.set_priority(priority)
__all__.append('Timeout')
# backwards compatible API
def idle_add(function, *user_data, **kwargs):
priority = kwargs.get('priority', GLib.PRIORITY_DEFAULT_IDLE)
return GLib.idle_add(priority, function, *user_data)
__all__.append('idle_add')
def timeout_add(interval, function, *user_data, **kwargs):
priority = kwargs.get('priority', GLib.PRIORITY_DEFAULT)
return GLib.timeout_add(priority, interval, function, *user_data)
__all__.append('timeout_add')
def timeout_add_seconds(interval, function, *user_data, **kwargs):
priority = kwargs.get('priority', GLib.PRIORITY_DEFAULT)
return GLib.timeout_add_seconds(priority, interval, function, *user_data)
__all__.append('timeout_add_seconds')
# The GI GLib API uses g_io_add_watch_full renamed to g_io_add_watch with
# a signature of (channel, priority, condition, func, user_data).
# Prior to PyGObject 3.8, this function was statically bound with an API closer to the
# non-full version with a signature of: (fd, condition, func, *user_data)
# We need to support this until we are okay with breaking API in a way which is
# not backwards compatible.
#
# This needs to take into account several historical APIs:
# - calling with an fd as first argument
# - calling with a Python file object as first argument (we keep this one as
# it's really convenient and does not change the number of arguments)
# - calling without a priority as second argument
def _io_add_watch_get_args(channel, priority_, condition, *cb_and_user_data, **kwargs):
if not isinstance(priority_, int) or isinstance(priority_, GLib.IOCondition):
warnings.warn('Calling io_add_watch without priority as second argument is deprecated',
PyGIDeprecationWarning)
# shift the arguments around
user_data = cb_and_user_data
callback = condition
condition = priority_
if not callable(callback):
raise TypeError('third argument must be callable')
# backwards compatibility: Call with priority kwarg
if 'priority' in kwargs:
warnings.warn('Calling io_add_watch with priority keyword argument is deprecated, put it as second positional argument',
PyGIDeprecationWarning)
priority_ = kwargs['priority']
else:
priority_ = GLib.PRIORITY_DEFAULT
else:
if len(cb_and_user_data) < 1 or not callable(cb_and_user_data[0]):
raise TypeError('expecting callback as fourth argument')
callback = cb_and_user_data[0]
user_data = cb_and_user_data[1:]
# backwards compatibility: Allow calling with fd
if isinstance(channel, int):
func_fdtransform = lambda _, cond, *data: callback(channel, cond, *data)
real_channel = GLib.IOChannel.unix_new(channel)
elif isinstance(channel, socket.socket) and sys.platform == 'win32':
func_fdtransform = lambda _, cond, *data: callback(channel, cond, *data)
real_channel = GLib.IOChannel.win32_new_socket(channel.fileno())
elif hasattr(channel, 'fileno'):
# backwards compatibility: Allow calling with Python file
func_fdtransform = lambda _, cond, *data: callback(channel, cond, *data)
real_channel = GLib.IOChannel.unix_new(channel.fileno())
else:
assert isinstance(channel, GLib.IOChannel)
func_fdtransform = callback
real_channel = channel
return real_channel, priority_, condition, func_fdtransform, user_data
__all__.append('_io_add_watch_get_args')
def io_add_watch(*args, **kwargs):
"""io_add_watch(channel, priority, condition, func, *user_data) -> event_source_id"""
channel, priority, condition, func, user_data = _io_add_watch_get_args(*args, **kwargs)
return GLib.io_add_watch(channel, priority, condition, func, *user_data)
__all__.append('io_add_watch')
# backwards compatible API
class IOChannel(GLib.IOChannel):
def __new__(cls, filedes=None, filename=None, mode=None, hwnd=None):
if filedes is not None:
return GLib.IOChannel.unix_new(filedes)
if filename is not None:
return GLib.IOChannel.new_file(filename, mode or 'r')
if hwnd is not None:
return GLib.IOChannel.win32_new_fd(hwnd)
raise TypeError('either a valid file descriptor, file name, or window handle must be supplied')
def __init__(self, *args, **kwargs):
return super(IOChannel, self).__init__()
def read(self, max_count=-1):
return io_channel_read(self, max_count)
def readline(self, size_hint=-1):
# note, size_hint is just to maintain backwards compatible API; the
# old static binding did not actually use it
(status, buf, length, terminator_pos) = self.read_line()
if buf is None:
return ''
return buf
def readlines(self, size_hint=-1):
# note, size_hint is just to maintain backwards compatible API;
# the old static binding did not actually use it
lines = []
status = GLib.IOStatus.NORMAL
while status == GLib.IOStatus.NORMAL:
(status, buf, length, terminator_pos) = self.read_line()
# note, this appends an empty line after EOF; this is
# bug-compatible with the old static bindings
if buf is None:
buf = ''
lines.append(buf)
return lines
def write(self, buf, buflen=-1):
if not isinstance(buf, bytes):
buf = buf.encode('UTF-8')
if buflen == -1:
buflen = len(buf)
(status, written) = self.write_chars(buf, buflen)
return written
def writelines(self, lines):
for line in lines:
self.write(line)
_whence_map = {0: GLib.SeekType.SET, 1: GLib.SeekType.CUR, 2: GLib.SeekType.END}
def seek(self, offset, whence=0):
try:
w = self._whence_map[whence]
except KeyError:
raise ValueError("invalid 'whence' value")
return self.seek_position(offset, w)
def add_watch(self, condition, callback, *user_data, **kwargs):
priority = kwargs.get('priority', GLib.PRIORITY_DEFAULT)
return io_add_watch(self, priority, condition, callback, *user_data)
add_watch = deprecated(add_watch, 'GLib.io_add_watch()')
def __iter__(self):
return self
def __next__(self):
(status, buf, length, terminator_pos) = self.read_line()
if status == GLib.IOStatus.NORMAL:
return buf
raise StopIteration
# Python 2.x compatibility
next = __next__
IOChannel = override(IOChannel)
__all__.append('IOChannel')
class PollFD(GLib.PollFD):
def __new__(cls, fd, events):
pollfd = GLib.PollFD()
pollfd.__class__ = cls
return pollfd
def __init__(self, fd, events):
self.fd = fd
self.events = events
PollFD = override(PollFD)
__all__.append('PollFD')
# The GI GLib API uses g_child_watch_add_full renamed to g_child_watch_add with
# a signature of (priority, pid, callback, data).
# Prior to PyGObject 3.8, this function was statically bound with an API closer to the
# non-full version with a signature of: (pid, callback, data=None, priority=GLib.PRIORITY_DEFAULT)
# We need to support this until we are okay with breaking API in a way which is
# not backwards compatible.
def _child_watch_add_get_args(priority_or_pid, pid_or_callback, *args, **kwargs):
user_data = []
if callable(pid_or_callback):
warnings.warn('Calling child_watch_add without priority as first argument is deprecated',
PyGIDeprecationWarning)
pid = priority_or_pid
callback = pid_or_callback
if len(args) == 0:
priority = kwargs.get('priority', GLib.PRIORITY_DEFAULT)
elif len(args) == 1:
user_data = args
priority = kwargs.get('priority', GLib.PRIORITY_DEFAULT)
elif len(args) == 2:
user_data = [args[0]]
priority = args[1]
else:
raise TypeError('expected at most 4 positional arguments')
else:
priority = priority_or_pid
pid = pid_or_callback
if 'function' in kwargs:
callback = kwargs['function']
user_data = args
elif len(args) > 0 and callable(args[0]):
callback = args[0]
user_data = args[1:]
else:
raise TypeError('expected callback as third argument')
if 'data' in kwargs:
if user_data:
raise TypeError('got multiple values for "data" argument')
user_data = (kwargs['data'],)
return priority, pid, callback, user_data
# we need this to be accessible for unit testing
__all__.append('_child_watch_add_get_args')
def child_watch_add(*args, **kwargs):
"""child_watch_add(priority, pid, function, *data)"""
priority, pid, function, data = _child_watch_add_get_args(*args, **kwargs)
return GLib.child_watch_add(priority, pid, function, *data)
__all__.append('child_watch_add')
def get_current_time():
return GLib.get_real_time() * 0.000001
get_current_time = deprecated(get_current_time, 'GLib.get_real_time()')
__all__.append('get_current_time')
# backwards compatible API with default argument, and ignoring bytes_read
# output argument
def filename_from_utf8(utf8string, len=-1):
return GLib.filename_from_utf8(utf8string, len)[0]
__all__.append('filename_from_utf8')
if hasattr(GLib, "unix_signal_add"):
unix_signal_add_full = GLib.unix_signal_add
__all__.append('unix_signal_add_full')
deprecated_attr("GLib", "unix_signal_add_full", "GLib.unix_signal_add")
# obsolete constants for backwards compatibility
glib_version = (GLib.MAJOR_VERSION, GLib.MINOR_VERSION, GLib.MICRO_VERSION)
__all__.append('glib_version')
deprecated_attr("GLib", "glib_version",
"(GLib.MAJOR_VERSION, GLib.MINOR_VERSION, GLib.MICRO_VERSION)")
pyglib_version = version_info
__all__.append('pyglib_version')
deprecated_attr("GLib", "pyglib_version", "gi.version_info")
@@ -0,0 +1,669 @@
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2012 Canonical Ltd.
# Author: Martin Pitt <martin.pitt@ubuntu.com>
# Copyright (C) 2012-2013 Simon Feltman <sfeltman@src.gnome.org>
# Copyright (C) 2012 Bastian Winkler <buz@netbuz.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
import functools
import warnings
from collections import namedtuple
import gi.module
from gi.overrides import override, deprecated_attr
from gi.repository import GLib
from gi import PyGIDeprecationWarning
from gi import _propertyhelper as propertyhelper
from gi import _signalhelper as signalhelper
from gi import _gi
GObjectModule = gi.module.get_introspection_module('GObject')
__all__ = []
from gi import _option as option
option = option
# API aliases for backwards compatibility
for name in ['markup_escape_text', 'get_application_name',
'set_application_name', 'get_prgname', 'set_prgname',
'main_depth', 'filename_display_basename',
'filename_display_name', 'filename_from_utf8',
'uri_list_extract_uris',
'MainLoop', 'MainContext', 'main_context_default',
'source_remove', 'Source', 'Idle', 'Timeout', 'PollFD',
'idle_add', 'timeout_add', 'timeout_add_seconds',
'io_add_watch', 'child_watch_add', 'get_current_time',
'spawn_async']:
globals()[name] = getattr(GLib, name)
deprecated_attr("GObject", name, "GLib." + name)
__all__.append(name)
# deprecated constants
for name in ['PRIORITY_DEFAULT', 'PRIORITY_DEFAULT_IDLE', 'PRIORITY_HIGH',
'PRIORITY_HIGH_IDLE', 'PRIORITY_LOW',
'IO_IN', 'IO_OUT', 'IO_PRI', 'IO_ERR', 'IO_HUP', 'IO_NVAL',
'IO_STATUS_ERROR', 'IO_STATUS_NORMAL', 'IO_STATUS_EOF',
'IO_STATUS_AGAIN', 'IO_FLAG_APPEND', 'IO_FLAG_NONBLOCK',
'IO_FLAG_IS_READABLE', 'IO_FLAG_IS_WRITEABLE',
'IO_FLAG_IS_SEEKABLE', 'IO_FLAG_MASK', 'IO_FLAG_GET_MASK',
'IO_FLAG_SET_MASK',
'SPAWN_LEAVE_DESCRIPTORS_OPEN', 'SPAWN_DO_NOT_REAP_CHILD',
'SPAWN_SEARCH_PATH', 'SPAWN_STDOUT_TO_DEV_NULL',
'SPAWN_STDERR_TO_DEV_NULL', 'SPAWN_CHILD_INHERITS_STDIN',
'SPAWN_FILE_AND_ARGV_ZERO',
'OPTION_FLAG_HIDDEN', 'OPTION_FLAG_IN_MAIN', 'OPTION_FLAG_REVERSE',
'OPTION_FLAG_NO_ARG', 'OPTION_FLAG_FILENAME', 'OPTION_FLAG_OPTIONAL_ARG',
'OPTION_FLAG_NOALIAS', 'OPTION_ERROR_UNKNOWN_OPTION',
'OPTION_ERROR_BAD_VALUE', 'OPTION_ERROR_FAILED', 'OPTION_REMAINING',
'glib_version']:
with warnings.catch_warnings():
# TODO: this uses deprecated Glib attributes, silence for now
warnings.simplefilter('ignore', PyGIDeprecationWarning)
globals()[name] = getattr(GLib, name)
deprecated_attr("GObject", name, "GLib." + name)
__all__.append(name)
for name in ['G_MININT8', 'G_MAXINT8', 'G_MAXUINT8', 'G_MININT16',
'G_MAXINT16', 'G_MAXUINT16', 'G_MININT32', 'G_MAXINT32',
'G_MAXUINT32', 'G_MININT64', 'G_MAXINT64', 'G_MAXUINT64']:
new_name = name.split("_", 1)[-1]
globals()[name] = getattr(GLib, new_name)
deprecated_attr("GObject", name, "GLib." + new_name)
__all__.append(name)
# these are not currently exported in GLib gir, presumably because they are
# platform dependent; so get them from our static bindings
for name in ['G_MINFLOAT', 'G_MAXFLOAT', 'G_MINDOUBLE', 'G_MAXDOUBLE',
'G_MINSHORT', 'G_MAXSHORT', 'G_MAXUSHORT', 'G_MININT', 'G_MAXINT',
'G_MAXUINT', 'G_MINLONG', 'G_MAXLONG', 'G_MAXULONG', 'G_MAXSIZE',
'G_MINSSIZE', 'G_MAXSSIZE', 'G_MINOFFSET', 'G_MAXOFFSET']:
new_name = name.split("_", 1)[-1]
globals()[name] = getattr(GLib, new_name)
deprecated_attr("GObject", name, "GLib." + new_name)
__all__.append(name)
TYPE_INVALID = GObjectModule.type_from_name('invalid')
TYPE_NONE = GObjectModule.type_from_name('void')
TYPE_INTERFACE = GObjectModule.type_from_name('GInterface')
TYPE_CHAR = GObjectModule.type_from_name('gchar')
TYPE_UCHAR = GObjectModule.type_from_name('guchar')
TYPE_BOOLEAN = GObjectModule.type_from_name('gboolean')
TYPE_INT = GObjectModule.type_from_name('gint')
TYPE_UINT = GObjectModule.type_from_name('guint')
TYPE_LONG = GObjectModule.type_from_name('glong')
TYPE_ULONG = GObjectModule.type_from_name('gulong')
TYPE_INT64 = GObjectModule.type_from_name('gint64')
TYPE_UINT64 = GObjectModule.type_from_name('guint64')
TYPE_ENUM = GObjectModule.type_from_name('GEnum')
TYPE_FLAGS = GObjectModule.type_from_name('GFlags')
TYPE_FLOAT = GObjectModule.type_from_name('gfloat')
TYPE_DOUBLE = GObjectModule.type_from_name('gdouble')
TYPE_STRING = GObjectModule.type_from_name('gchararray')
TYPE_POINTER = GObjectModule.type_from_name('gpointer')
TYPE_BOXED = GObjectModule.type_from_name('GBoxed')
TYPE_PARAM = GObjectModule.type_from_name('GParam')
TYPE_OBJECT = GObjectModule.type_from_name('GObject')
TYPE_PYOBJECT = GObjectModule.type_from_name('PyObject')
TYPE_GTYPE = GObjectModule.type_from_name('GType')
TYPE_STRV = GObjectModule.type_from_name('GStrv')
TYPE_VARIANT = GObjectModule.type_from_name('GVariant')
TYPE_GSTRING = GObjectModule.type_from_name('GString')
TYPE_VALUE = GObjectModule.Value.__gtype__
TYPE_UNICHAR = TYPE_UINT
__all__ += ['TYPE_INVALID', 'TYPE_NONE', 'TYPE_INTERFACE', 'TYPE_CHAR',
'TYPE_UCHAR', 'TYPE_BOOLEAN', 'TYPE_INT', 'TYPE_UINT', 'TYPE_LONG',
'TYPE_ULONG', 'TYPE_INT64', 'TYPE_UINT64', 'TYPE_ENUM', 'TYPE_FLAGS',
'TYPE_FLOAT', 'TYPE_DOUBLE', 'TYPE_STRING', 'TYPE_POINTER',
'TYPE_BOXED', 'TYPE_PARAM', 'TYPE_OBJECT', 'TYPE_PYOBJECT',
'TYPE_GTYPE', 'TYPE_STRV', 'TYPE_VARIANT', 'TYPE_GSTRING',
'TYPE_UNICHAR', 'TYPE_VALUE']
# Deprecated, use GLib directly
for name in ['Pid', 'GError', 'OptionGroup', 'OptionContext']:
globals()[name] = getattr(GLib, name)
deprecated_attr("GObject", name, "GLib." + name)
__all__.append(name)
# Deprecated, use: GObject.ParamFlags.* directly
for name in ['PARAM_CONSTRUCT', 'PARAM_CONSTRUCT_ONLY', 'PARAM_LAX_VALIDATION',
'PARAM_READABLE', 'PARAM_WRITABLE']:
new_name = name.split("_", 1)[-1]
globals()[name] = getattr(GObjectModule.ParamFlags, new_name)
deprecated_attr("GObject", name, "GObject.ParamFlags." + new_name)
__all__.append(name)
# PARAM_READWRITE should come from the gi module but cannot due to:
# https://gitlab.gnome.org/GNOME/gobject-introspection/issues/75
PARAM_READWRITE = GObjectModule.ParamFlags.READABLE | \
GObjectModule.ParamFlags.WRITABLE
deprecated_attr("GObject", "PARAM_READWRITE", "GObject.ParamFlags.READWRITE")
__all__.append("PARAM_READWRITE")
# Deprecated, use: GObject.SignalFlags.* directly
for name in ['SIGNAL_ACTION', 'SIGNAL_DETAILED', 'SIGNAL_NO_HOOKS',
'SIGNAL_NO_RECURSE', 'SIGNAL_RUN_CLEANUP', 'SIGNAL_RUN_FIRST',
'SIGNAL_RUN_LAST']:
new_name = name.split("_", 1)[-1]
globals()[name] = getattr(GObjectModule.SignalFlags, new_name)
deprecated_attr("GObject", name, "GObject.SignalFlags." + new_name)
__all__.append(name)
# Static types
GBoxed = _gi.GBoxed
GEnum = _gi.GEnum
GFlags = _gi.GFlags
GInterface = _gi.GInterface
GObject = _gi.GObject
GObjectWeakRef = _gi.GObjectWeakRef
GParamSpec = _gi.GParamSpec
GPointer = _gi.GPointer
GType = _gi.GType
Warning = _gi.Warning
__all__ += ['GBoxed', 'GEnum', 'GFlags', 'GInterface', 'GObject',
'GObjectWeakRef', 'GParamSpec', 'GPointer', 'GType',
'Warning']
features = {'generic-c-marshaller': True}
list_properties = _gi.list_properties
new = _gi.new
pygobject_version = _gi.pygobject_version
threads_init = GLib.threads_init
type_register = _gi.type_register
__all__ += ['features', 'list_properties', 'new',
'pygobject_version', 'threads_init', 'type_register']
class Value(GObjectModule.Value):
def __init__(self, value_type=None, py_value=None):
GObjectModule.Value.__init__(self)
if value_type is not None:
self.init(value_type)
if py_value is not None:
self.set_value(py_value)
@property
def __g_type(self):
# XXX: This is the same as self.g_type, but the field marshalling
# code is currently very slow.
return _gi._gvalue_get_type(self)
def set_boxed(self, boxed):
if not self.__g_type.is_a(TYPE_BOXED):
warnings.warn('Calling set_boxed() on a non-boxed type deprecated',
PyGIDeprecationWarning, stacklevel=2)
# Workaround the introspection marshalers inability to know
# these methods should be marshaling boxed types. This is because
# the type information is stored on the GValue.
_gi._gvalue_set(self, boxed)
def get_boxed(self):
if not self.__g_type.is_a(TYPE_BOXED):
warnings.warn('Calling get_boxed() on a non-boxed type deprecated',
PyGIDeprecationWarning, stacklevel=2)
return _gi._gvalue_get(self)
def set_value(self, py_value):
gtype = self.__g_type
if gtype == TYPE_CHAR:
self.set_char(py_value)
elif gtype == TYPE_UCHAR:
self.set_uchar(py_value)
elif gtype == TYPE_STRING:
if not isinstance(py_value, str) and py_value is not None:
raise TypeError("Expected string but got %s%s" %
(py_value, type(py_value)))
_gi._gvalue_set(self, py_value)
elif gtype == TYPE_PARAM:
self.set_param(py_value)
elif gtype.is_a(TYPE_FLAGS):
self.set_flags(py_value)
elif gtype == TYPE_POINTER:
self.set_pointer(py_value)
elif gtype == TYPE_GTYPE:
self.set_gtype(py_value)
elif gtype == TYPE_VARIANT:
self.set_variant(py_value)
else:
# Fall back to _gvalue_set which handles some more cases
# like fundamentals for which a converter is registered
try:
_gi._gvalue_set(self, py_value)
except TypeError:
if gtype == TYPE_INVALID:
raise TypeError("GObject.Value needs to be initialized first")
raise
def get_value(self):
gtype = self.__g_type
if gtype == TYPE_CHAR:
return self.get_char()
elif gtype == TYPE_UCHAR:
return self.get_uchar()
elif gtype == TYPE_PARAM:
return self.get_param()
elif gtype.is_a(TYPE_ENUM):
return self.get_enum()
elif gtype.is_a(TYPE_FLAGS):
return self.get_flags()
elif gtype == TYPE_POINTER:
return self.get_pointer()
elif gtype == TYPE_GTYPE:
return self.get_gtype()
elif gtype == TYPE_VARIANT:
# get_variant was missing annotations
# https://gitlab.gnome.org/GNOME/glib/merge_requests/492
return self.dup_variant()
else:
try:
return _gi._gvalue_get(self)
except TypeError:
if gtype == TYPE_INVALID:
return None
raise
def __repr__(self):
return '<Value (%s) %s>' % (self.__g_type.name, self.get_value())
Value = override(Value)
__all__.append('Value')
def type_from_name(name):
type_ = GObjectModule.type_from_name(name)
if type_ == TYPE_INVALID:
raise RuntimeError('unknown type name: %s' % name)
return type_
__all__.append('type_from_name')
def type_parent(type_):
parent = GObjectModule.type_parent(type_)
if parent == TYPE_INVALID:
raise RuntimeError('no parent for type')
return parent
__all__.append('type_parent')
def _validate_type_for_signal_method(type_):
if hasattr(type_, '__gtype__'):
type_ = type_.__gtype__
if not type_.is_instantiatable() and not type_.is_interface():
raise TypeError('type must be instantiable or an interface, got %s' % type_)
def signal_list_ids(type_):
_validate_type_for_signal_method(type_)
return GObjectModule.signal_list_ids(type_)
__all__.append('signal_list_ids')
def signal_list_names(type_):
ids = signal_list_ids(type_)
return tuple(GObjectModule.signal_name(i) for i in ids)
__all__.append('signal_list_names')
def signal_lookup(name, type_):
_validate_type_for_signal_method(type_)
return GObjectModule.signal_lookup(name, type_)
__all__.append('signal_lookup')
SignalQuery = namedtuple('SignalQuery',
['signal_id',
'signal_name',
'itype',
'signal_flags',
'return_type',
# n_params',
'param_types'])
def signal_query(id_or_name, type_=None):
if type_ is not None:
id_or_name = signal_lookup(id_or_name, type_)
res = GObjectModule.signal_query(id_or_name)
assert res is not None
if res.signal_id == 0:
return None
# Return a named tuple to allows indexing which is compatible with the
# static bindings along with field like access of the gi struct.
# Note however that the n_params was not returned from the static bindings
# so we must skip over it.
return SignalQuery(res.signal_id, res.signal_name, res.itype,
res.signal_flags, res.return_type,
tuple(res.param_types))
__all__.append('signal_query')
class _HandlerBlockManager(object):
def __init__(self, obj, handler_id):
self.obj = obj
self.handler_id = handler_id
def __enter__(self):
pass
def __exit__(self, exc_type, exc_value, traceback):
GObjectModule.signal_handler_unblock(self.obj, self.handler_id)
def signal_handler_block(obj, handler_id):
"""Blocks the signal handler from being invoked until
handler_unblock() is called.
:param GObject.Object obj:
Object instance to block handlers for.
:param int handler_id:
Id of signal to block.
:returns:
A context manager which optionally can be used to
automatically unblock the handler:
.. code-block:: python
with GObject.signal_handler_block(obj, id):
pass
"""
GObjectModule.signal_handler_block(obj, handler_id)
return _HandlerBlockManager(obj, handler_id)
__all__.append('signal_handler_block')
def signal_parse_name(detailed_signal, itype, force_detail_quark):
"""Parse a detailed signal name into (signal_id, detail).
:param str detailed_signal:
Signal name which can include detail.
For example: "notify:prop_name"
:returns:
Tuple of (signal_id, detail)
:raises ValueError:
If the given signal is unknown.
"""
res, signal_id, detail = GObjectModule.signal_parse_name(detailed_signal, itype,
force_detail_quark)
if res:
return signal_id, detail
else:
raise ValueError('%s: unknown signal name: %s' % (itype, detailed_signal))
__all__.append('signal_parse_name')
def remove_emission_hook(obj, detailed_signal, hook_id):
signal_id, detail = signal_parse_name(detailed_signal, obj, True)
GObjectModule.signal_remove_emission_hook(signal_id, hook_id)
__all__.append('remove_emission_hook')
# GObject accumulators with pure Python implementations
# These return a tuple of (continue_emission, accumulation_result)
def signal_accumulator_first_wins(ihint, return_accu, handler_return, user_data=None):
# Stop emission but return the result of the last handler
return (False, handler_return)
__all__.append('signal_accumulator_first_wins')
def signal_accumulator_true_handled(ihint, return_accu, handler_return, user_data=None):
# Stop emission if the last handler returns True
return (not handler_return, handler_return)
__all__.append('signal_accumulator_true_handled')
# Statically bound signal functions which need to clobber GI (for now)
add_emission_hook = _gi.add_emission_hook
signal_new = _gi.signal_new
__all__ += ['add_emission_hook', 'signal_new']
class _FreezeNotifyManager(object):
def __init__(self, obj):
self.obj = obj
def __enter__(self):
pass
def __exit__(self, exc_type, exc_value, traceback):
self.obj.thaw_notify()
def _signalmethod(func):
# Function wrapper for signal functions used as instance methods.
# This is needed when the signal functions come directly from GI.
# (they are not already wrapped)
@functools.wraps(func)
def meth(*args, **kwargs):
return func(*args, **kwargs)
return meth
class Object(GObjectModule.Object):
def _unsupported_method(self, *args, **kargs):
raise RuntimeError('This method is currently unsupported.')
def _unsupported_data_method(self, *args, **kargs):
raise RuntimeError('Data access methods are unsupported. '
'Use normal Python attributes instead')
# Generic data methods are not needed in python as it can be handled
# with standard attribute access: https://bugzilla.gnome.org/show_bug.cgi?id=641944
get_data = _unsupported_data_method
get_qdata = _unsupported_data_method
set_data = _unsupported_data_method
steal_data = _unsupported_data_method
steal_qdata = _unsupported_data_method
replace_data = _unsupported_data_method
replace_qdata = _unsupported_data_method
# The following methods as unsupported until we verify
# they work as gi methods.
bind_property_full = _unsupported_method
compat_control = _unsupported_method
interface_find_property = _unsupported_method
interface_install_property = _unsupported_method
interface_list_properties = _unsupported_method
notify_by_pspec = _unsupported_method
watch_closure = _unsupported_method
# Make all reference management methods private but still accessible.
_ref = GObjectModule.Object.ref
_ref_sink = GObjectModule.Object.ref_sink
_unref = GObjectModule.Object.unref
_force_floating = GObjectModule.Object.force_floating
ref = _unsupported_method
ref_sink = _unsupported_method
unref = _unsupported_method
force_floating = _unsupported_method
# The following methods are static APIs which need to leap frog the
# gi methods until we verify the gi methods can replace them.
get_property = _gi.GObject.get_property
get_properties = _gi.GObject.get_properties
set_property = _gi.GObject.set_property
set_properties = _gi.GObject.set_properties
bind_property = _gi.GObject.bind_property
connect = _gi.GObject.connect
connect_after = _gi.GObject.connect_after
connect_object = _gi.GObject.connect_object
connect_object_after = _gi.GObject.connect_object_after
disconnect_by_func = _gi.GObject.disconnect_by_func
handler_block_by_func = _gi.GObject.handler_block_by_func
handler_unblock_by_func = _gi.GObject.handler_unblock_by_func
emit = _gi.GObject.emit
chain = _gi.GObject.chain
weak_ref = _gi.GObject.weak_ref
__copy__ = _gi.GObject.__copy__
__deepcopy__ = _gi.GObject.__deepcopy__
def freeze_notify(self):
"""Freezes the object's property-changed notification queue.
:returns:
A context manager which optionally can be used to
automatically thaw notifications.
This will freeze the object so that "notify" signals are blocked until
the thaw_notify() method is called.
.. code-block:: python
with obj.freeze_notify():
pass
"""
super(Object, self).freeze_notify()
return _FreezeNotifyManager(self)
def connect_data(self, detailed_signal, handler, *data, **kwargs):
"""Connect a callback to the given signal with optional user data.
:param str detailed_signal:
A detailed signal to connect to.
:param callable handler:
Callback handler to connect to the signal.
:param *data:
Variable data which is passed through to the signal handler.
:param GObject.ConnectFlags connect_flags:
Flags used for connection options.
:returns:
A signal id which can be used with disconnect.
"""
flags = kwargs.get('connect_flags', 0)
if flags & GObjectModule.ConnectFlags.AFTER:
connect_func = _gi.GObject.connect_after
else:
connect_func = _gi.GObject.connect
if flags & GObjectModule.ConnectFlags.SWAPPED:
if len(data) != 1:
raise ValueError('Using GObject.ConnectFlags.SWAPPED requires exactly '
'one argument for user data, got: %s' % [data])
def new_handler(obj, *args):
# Swap obj with the last element in args which will be the user
# data passed to the connect function.
args = list(args)
swap = args.pop()
args = args + [obj]
return handler(swap, *args)
else:
new_handler = handler
return connect_func(self, detailed_signal, new_handler, *data)
#
# Aliases
#
handler_block = signal_handler_block
handler_unblock = _signalmethod(GObjectModule.signal_handler_unblock)
disconnect = _signalmethod(GObjectModule.signal_handler_disconnect)
handler_disconnect = _signalmethod(GObjectModule.signal_handler_disconnect)
handler_is_connected = _signalmethod(GObjectModule.signal_handler_is_connected)
stop_emission_by_name = _signalmethod(GObjectModule.signal_stop_emission_by_name)
#
# Deprecated Methods
#
def stop_emission(self, detailed_signal):
"""Deprecated, please use stop_emission_by_name."""
warnings.warn(self.stop_emission.__doc__, PyGIDeprecationWarning, stacklevel=2)
return self.stop_emission_by_name(detailed_signal)
emit_stop_by_name = stop_emission
Object = override(Object)
GObject = Object
__all__ += ['Object', 'GObject']
class Binding(GObjectModule.Binding):
def __call__(self):
warnings.warn('Using parentheses (binding()) to retrieve the Binding object is no '
'longer needed because the binding is returned directly from "bind_property.',
PyGIDeprecationWarning, stacklevel=2)
return self
def unbind(self):
# Fixed in newer glib
if (GLib.MAJOR_VERSION, GLib.MINOR_VERSION, GLib.MICRO_VERSION) >= (2, 57, 3):
return super(Binding, self).unbind()
if hasattr(self, '_unbound'):
raise ValueError('binding has already been cleared out')
else:
setattr(self, '_unbound', True)
super(Binding, self).unbind()
Binding = override(Binding)
__all__.append('Binding')
Property = propertyhelper.Property
Signal = signalhelper.Signal
SignalOverride = signalhelper.SignalOverride
# Deprecated naming "property" available for backwards compatibility.
# Keep this at the end of the file to avoid clobbering the builtin.
property = Property
deprecated_attr("GObject", "property", "GObject.Property")
__all__ += ['Property', 'Signal', 'SignalOverride', 'property']
@@ -0,0 +1,484 @@
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2009 Johan Dahlin <johan@gnome.org>
# 2010 Simon van der Linden <svdlinden@src.gnome.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
import sys
import warnings
from ..overrides import override, strip_boolean_result
from ..module import get_introspection_module
from gi import PyGIDeprecationWarning, require_version
Gdk = get_introspection_module('Gdk')
GDK2 = Gdk._version == '2.0'
GDK3 = Gdk._version == '3.0'
GDK4 = Gdk._version == '4.0'
__all__ = []
# https://bugzilla.gnome.org/show_bug.cgi?id=673396
try:
require_version("GdkX11", Gdk._version)
from gi.repository import GdkX11
GdkX11 # pyflakes
except (ValueError, ImportError):
pass
if GDK2 or GDK3:
# Gdk.Color was deprecated since 3.14 and dropped in Gtk-4.0
class Color(Gdk.Color):
MAX_VALUE = 65535
def __init__(self, red, green, blue):
Gdk.Color.__init__(self)
self.red = red
self.green = green
self.blue = blue
def __eq__(self, other):
if not isinstance(other, Gdk.Color):
return False
return self.equal(other)
# This is required (even when __eq__ is defined) in order
# for != operator to work as expected
def __ne__(self, other):
return not self == other
def __repr__(self):
return 'Gdk.Color(red=%d, green=%d, blue=%d)' % (self.red, self.green, self.blue)
red_float = property(fget=lambda self: self.red / float(self.MAX_VALUE),
fset=lambda self, v: setattr(self, 'red', int(v * self.MAX_VALUE)))
green_float = property(fget=lambda self: self.green / float(self.MAX_VALUE),
fset=lambda self, v: setattr(self, 'green', int(v * self.MAX_VALUE)))
blue_float = property(fget=lambda self: self.blue / float(self.MAX_VALUE),
fset=lambda self, v: setattr(self, 'blue', int(v * self.MAX_VALUE)))
def to_floats(self):
"""Return (red_float, green_float, blue_float) triple."""
return (self.red_float, self.green_float, self.blue_float)
@staticmethod
def from_floats(red, green, blue):
"""Return a new Color object from red/green/blue values from 0.0 to 1.0."""
return Color(int(red * Color.MAX_VALUE),
int(green * Color.MAX_VALUE),
int(blue * Color.MAX_VALUE))
Color = override(Color)
__all__.append('Color')
if GDK3:
# Introduced since Gtk-3.0
class RGBA(Gdk.RGBA):
def __init__(self, red=1.0, green=1.0, blue=1.0, alpha=1.0):
Gdk.RGBA.__init__(self)
self.red = red
self.green = green
self.blue = blue
self.alpha = alpha
def __eq__(self, other):
if not isinstance(other, Gdk.RGBA):
return False
return self.equal(other)
# This is required (even when __eq__ is defined) in order
# for != operator to work as expected
def __ne__(self, other):
return not self == other
def __repr__(self):
return 'Gdk.RGBA(red=%f, green=%f, blue=%f, alpha=%f)' % (self.red, self.green, self.blue, self.alpha)
def __iter__(self):
"""Iterator which allows easy conversion to tuple and list types."""
yield self.red
yield self.green
yield self.blue
yield self.alpha
def to_color(self):
"""Converts this RGBA into a Color instance which excludes alpha."""
return Color(int(self.red * Color.MAX_VALUE),
int(self.green * Color.MAX_VALUE),
int(self.blue * Color.MAX_VALUE))
@classmethod
def from_color(cls, color):
"""Returns a new RGBA instance given a Color instance."""
return cls(color.red_float, color.green_float, color.blue_float)
RGBA = override(RGBA)
__all__.append('RGBA')
if GDK2:
class Rectangle(Gdk.Rectangle):
def __init__(self, x, y, width, height):
Gdk.Rectangle.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
def __repr__(self):
return 'Gdk.Rectangle(x=%d, y=%d, width=%d, height=%d)' % (self.x, self.y, self.height, self.width)
Rectangle = override(Rectangle)
__all__.append('Rectangle')
elif GDK3:
# Newer GTK/gobject-introspection (3.17.x) include GdkRectangle in the
# typelib. See https://bugzilla.gnome.org/show_bug.cgi?id=748832 and
# https://bugzilla.gnome.org/show_bug.cgi?id=748833
if not hasattr(Gdk, 'Rectangle'):
from gi.repository import cairo as _cairo
Rectangle = _cairo.RectangleInt
__all__.append('Rectangle')
else:
# https://bugzilla.gnome.org/show_bug.cgi?id=756364
# These methods used to be functions, keep aliases for backwards compat
rectangle_intersect = Gdk.Rectangle.intersect
rectangle_union = Gdk.Rectangle.union
__all__.append('rectangle_intersect')
__all__.append('rectangle_union')
if GDK2:
class Drawable(Gdk.Drawable):
def cairo_create(self):
return Gdk.cairo_create(self)
Drawable = override(Drawable)
__all__.append('Drawable')
elif GDK3:
class Window(Gdk.Window):
def __new__(cls, parent, attributes, attributes_mask):
# Gdk.Window had to be made abstract,
# this override allows using the standard constructor
return Gdk.Window.new(parent, attributes, attributes_mask)
def __init__(self, parent, attributes, attributes_mask):
pass
def cairo_create(self):
return Gdk.cairo_create(self)
Window = override(Window)
__all__.append('Window')
if GDK2 or GDK3:
Gdk.EventType._2BUTTON_PRESS = getattr(Gdk.EventType, "2BUTTON_PRESS")
Gdk.EventType._3BUTTON_PRESS = getattr(Gdk.EventType, "3BUTTON_PRESS")
class Event(Gdk.Event):
_UNION_MEMBERS = {
Gdk.EventType.DELETE: 'any',
Gdk.EventType.DESTROY: 'any',
Gdk.EventType.MOTION_NOTIFY: 'motion',
Gdk.EventType.BUTTON_PRESS: 'button',
Gdk.EventType.BUTTON_RELEASE: 'button',
Gdk.EventType.KEY_PRESS: 'key',
Gdk.EventType.KEY_RELEASE: 'key',
Gdk.EventType.ENTER_NOTIFY: 'crossing',
Gdk.EventType.LEAVE_NOTIFY: 'crossing',
Gdk.EventType.FOCUS_CHANGE: 'focus_change',
Gdk.EventType.CONFIGURE: 'configure',
Gdk.EventType.PROXIMITY_IN: 'proximity',
Gdk.EventType.PROXIMITY_OUT: 'proximity',
Gdk.EventType.DRAG_ENTER: 'dnd',
Gdk.EventType.DRAG_LEAVE: 'dnd',
Gdk.EventType.DRAG_MOTION: 'dnd',
Gdk.EventType.DROP_START: 'dnd',
Gdk.EventType._2BUTTON_PRESS: 'button',
Gdk.EventType._3BUTTON_PRESS: 'button',
Gdk.EventType.PROPERTY_NOTIFY: 'property',
Gdk.EventType.SELECTION_CLEAR: 'selection',
Gdk.EventType.SELECTION_REQUEST: 'selection',
Gdk.EventType.SELECTION_NOTIFY: 'selection',
Gdk.EventType.DRAG_STATUS: 'dnd',
Gdk.EventType.DROP_FINISHED: 'dnd',
Gdk.EventType.CLIENT_EVENT: 'client',
Gdk.EventType.VISIBILITY_NOTIFY: 'visibility',
Gdk.EventType.SCROLL: 'scroll',
Gdk.EventType.EXPOSE: 'expose',
Gdk.EventType.MAP: 'any',
Gdk.EventType.UNMAP: 'any',
}
if GDK2:
_UNION_MEMBERS[Gdk.EventType.NO_EXPOSE] = 'no_expose'
if hasattr(Gdk.EventType, 'TOUCH_BEGIN'):
_UNION_MEMBERS.update(
{
Gdk.EventType.TOUCH_BEGIN: 'touch',
Gdk.EventType.TOUCH_UPDATE: 'touch',
Gdk.EventType.TOUCH_END: 'touch',
Gdk.EventType.TOUCH_CANCEL: 'touch',
})
def __getattr__(self, name):
real_event = getattr(self, '_UNION_MEMBERS').get(self.type)
if real_event:
return getattr(getattr(self, real_event), name)
else:
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
def __setattr__(self, name, value):
real_event = getattr(self, '_UNION_MEMBERS').get(self.type)
if real_event:
setattr(getattr(self, real_event), name, value)
else:
Gdk.Event.__setattr__(self, name, value)
def __repr__(self):
base_repr = Gdk.Event.__repr__(self).strip("><")
return "<%s type=%r>" % (base_repr, self.type)
Event = override(Event)
__all__.append('Event')
# manually bind GdkEvent members to GdkEvent
modname = globals()['__name__']
module = sys.modules[modname]
# right now we can't get the type_info from the
# field info so manually list the class names
event_member_classes = ['EventAny',
'EventExpose',
'EventMotion',
'EventButton',
'EventScroll',
'EventKey',
'EventCrossing',
'EventFocus',
'EventConfigure',
'EventProximity',
'EventDND',
'EventSetting',
'EventGrabBroken',
'EventVisibility',
'EventProperty',
'EventSelection',
'EventOwnerChange',
'EventWindowState',
'EventVisibility']
if GDK2:
event_member_classes.append('EventNoExpose')
if hasattr(Gdk, 'EventTouch'):
event_member_classes.append('EventTouch')
# whitelist all methods that have a success return we want to mask
gsuccess_mask_funcs = ['get_state',
'get_axis',
'get_coords',
'get_root_coords']
for event_class in event_member_classes:
override_class = type(event_class, (getattr(Gdk, event_class),), {})
# add the event methods
for method_info in Gdk.Event.__info__.get_methods():
name = method_info.get_name()
event_method = getattr(Gdk.Event, name)
# use the _gsuccess_mask decorator if this method is whitelisted
if name in gsuccess_mask_funcs:
event_method = strip_boolean_result(event_method)
setattr(override_class, name, event_method)
setattr(module, event_class, override_class)
__all__.append(event_class)
# end GdkEvent overrides
class DragContext(Gdk.DragContext):
def finish(self, success, del_, time):
Gtk = get_introspection_module('Gtk')
Gtk.drag_finish(self, success, del_, time)
DragContext = override(DragContext)
__all__.append('DragContext')
class Cursor(Gdk.Cursor):
def __new__(cls, *args, **kwds):
arg_len = len(args)
kwd_len = len(kwds)
total_len = arg_len + kwd_len
if total_len == 1:
# Since g_object_newv (super.__new__) does not seem valid for
# direct use with GdkCursor, we must assume usage of at least
# one of the C constructors to be valid.
return cls.new(*args, **kwds)
elif total_len == 2:
warnings.warn('Calling "Gdk.Cursor(display, cursor_type)" has been deprecated. '
'Please use Gdk.Cursor.new_for_display(display, cursor_type). '
'See: https://wiki.gnome.org/PyGObject/InitializerDeprecations',
PyGIDeprecationWarning)
return cls.new_for_display(*args, **kwds)
elif total_len == 4:
warnings.warn('Calling "Gdk.Cursor(display, pixbuf, x, y)" has been deprecated. '
'Please use Gdk.Cursor.new_from_pixbuf(display, pixbuf, x, y). '
'See: https://wiki.gnome.org/PyGObject/InitializerDeprecations',
PyGIDeprecationWarning)
return cls.new_from_pixbuf(*args, **kwds)
elif total_len == 6:
if not GDK2:
# pixmaps don't exist in Gdk 3.0
raise ValueError("Wrong number of parameters")
warnings.warn('Calling "Gdk.Cursor(source, mask, fg, bg, x, y)" has been deprecated. '
'Please use Gdk.Cursor.new_from_pixmap(source, mask, fg, bg, x, y). '
'See: https://wiki.gnome.org/PyGObject/InitializerDeprecations',
PyGIDeprecationWarning)
return cls.new_from_pixmap(*args, **kwds)
else:
raise ValueError("Wrong number of parameters")
Cursor = override(Cursor)
__all__.append('Cursor')
# Gdk.Color was deprecated since 3.14 and dropped in Gtk-4.0
color_parse = strip_boolean_result(Gdk.color_parse)
__all__.append('color_parse')
# Note, we cannot override the entire class as Gdk.Atom has no gtype, so just
# hack some individual methods
def _gdk_atom_str(atom):
n = atom.name()
if n:
return n
# fall back to atom index
return 'Gdk.Atom<%i>' % hash(atom)
def _gdk_atom_repr(atom):
n = atom.name()
if n:
return 'Gdk.Atom.intern("%s", False)' % n
# fall back to atom index
return '<Gdk.Atom(%i)>' % hash(atom)
Gdk.Atom.__str__ = _gdk_atom_str
Gdk.Atom.__repr__ = _gdk_atom_repr
if GDK4:
from gi.repository import Gio
class FileList(Gdk.FileList):
if hasattr(Gdk.FileList, "new_from_list"):
def __new__(cls, files):
files_list = []
if isinstance(files, (tuple, list)):
for f in files:
if isinstance(f, Gio.File):
files_list.append(f)
else:
raise TypeError('Constructor requires a list or tuple of Gio.File instances')
else:
raise TypeError('Constructor requires a list or tuple of Gio.File instances')
return Gdk.FileList.new_from_list(files)
def __iter__(self):
return iter(self.get_files())
def __len__(self):
return len(self.get_files())
def __getitem__(self, index):
return self.get_files()[index]
FileList = override(FileList)
__all__.append('FileList')
# constants
if GDK3:
SELECTION_PRIMARY = Gdk.atom_intern('PRIMARY', True)
__all__.append('SELECTION_PRIMARY')
SELECTION_SECONDARY = Gdk.atom_intern('SECONDARY', True)
__all__.append('SELECTION_SECONDARY')
SELECTION_CLIPBOARD = Gdk.atom_intern('CLIPBOARD', True)
__all__.append('SELECTION_CLIPBOARD')
TARGET_BITMAP = Gdk.atom_intern('BITMAP', True)
__all__.append('TARGET_BITMAP')
TARGET_COLORMAP = Gdk.atom_intern('COLORMAP', True)
__all__.append('TARGET_COLORMAP')
TARGET_DRAWABLE = Gdk.atom_intern('DRAWABLE', True)
__all__.append('TARGET_DRAWABLE')
TARGET_PIXMAP = Gdk.atom_intern('PIXMAP', True)
__all__.append('TARGET_PIXMAP')
TARGET_STRING = Gdk.atom_intern('STRING', True)
__all__.append('TARGET_STRING')
SELECTION_TYPE_ATOM = Gdk.atom_intern('ATOM', True)
__all__.append('SELECTION_TYPE_ATOM')
SELECTION_TYPE_BITMAP = Gdk.atom_intern('BITMAP', True)
__all__.append('SELECTION_TYPE_BITMAP')
SELECTION_TYPE_COLORMAP = Gdk.atom_intern('COLORMAP', True)
__all__.append('SELECTION_TYPE_COLORMAP')
SELECTION_TYPE_DRAWABLE = Gdk.atom_intern('DRAWABLE', True)
__all__.append('SELECTION_TYPE_DRAWABLE')
SELECTION_TYPE_INTEGER = Gdk.atom_intern('INTEGER', True)
__all__.append('SELECTION_TYPE_INTEGER')
SELECTION_TYPE_PIXMAP = Gdk.atom_intern('PIXMAP', True)
__all__.append('SELECTION_TYPE_PIXMAP')
SELECTION_TYPE_WINDOW = Gdk.atom_intern('WINDOW', True)
__all__.append('SELECTION_TYPE_WINDOW')
SELECTION_TYPE_STRING = Gdk.atom_intern('STRING', True)
__all__.append('SELECTION_TYPE_STRING')
if GDK2 or GDK3:
import sys
initialized, argv = Gdk.init_check(sys.argv)
@@ -0,0 +1,53 @@
# Copyright 2018 Christoph Reiter <reiter.christoph@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
import warnings
from gi import PyGIDeprecationWarning
from gi.repository import GLib
from ..overrides import override
from ..module import get_introspection_module
GdkPixbuf = get_introspection_module('GdkPixbuf')
__all__ = []
@override
class Pixbuf(GdkPixbuf.Pixbuf):
@classmethod
def new_from_data(
cls, data, colorspace, has_alpha, bits_per_sample,
width, height, rowstride,
destroy_fn=None, *destroy_fn_data):
if destroy_fn is not None:
w = PyGIDeprecationWarning("destroy_fn argument deprecated")
warnings.warn(w)
if destroy_fn_data:
w = PyGIDeprecationWarning("destroy_fn_data argument deprecated")
warnings.warn(w)
data = GLib.Bytes.new(data)
return cls.new_from_bytes(
data, colorspace, has_alpha, bits_per_sample,
width, height, rowstride)
__all__.append('Pixbuf')
@@ -0,0 +1,550 @@
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2010 Ignacio Casal Quinteiro <icq@gnome.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
import warnings
from .._ossighelper import wakeup_on_signal, register_sigint_fallback
from ..overrides import override, deprecated_init, wrap_list_store_sort_func
from ..module import get_introspection_module
from gi import PyGIWarning
from gi.repository import GLib
import sys
Gio = get_introspection_module('Gio')
__all__ = []
class Application(Gio.Application):
def run(self, *args, **kwargs):
with register_sigint_fallback(self.quit):
with wakeup_on_signal():
return Gio.Application.run(self, *args, **kwargs)
Application = override(Application)
__all__.append('Application')
def _warn_init(cls, instead=None):
def new_init(self, *args, **kwargs):
super(cls, self).__init__(*args, **kwargs)
name = cls.__module__.rsplit(".", 1)[-1] + "." + cls.__name__
if instead:
warnings.warn(
("%s shouldn't be instantiated directly, "
"use %s instead." % (name, instead)),
PyGIWarning, stacklevel=2)
else:
warnings.warn(
"%s shouldn't be instantiated directly." % (name,),
PyGIWarning, stacklevel=2)
return new_init
@override
class VolumeMonitor(Gio.VolumeMonitor):
# https://bugzilla.gnome.org/show_bug.cgi?id=744690
__init__ = _warn_init(Gio.VolumeMonitor, "Gio.VolumeMonitor.get()")
__all__.append('VolumeMonitor')
@override
class DBusAnnotationInfo(Gio.DBusAnnotationInfo):
__init__ = _warn_init(Gio.DBusAnnotationInfo)
__all__.append('DBusAnnotationInfo')
@override
class DBusArgInfo(Gio.DBusArgInfo):
__init__ = _warn_init(Gio.DBusArgInfo)
__all__.append('DBusArgInfo')
@override
class DBusMethodInfo(Gio.DBusMethodInfo):
__init__ = _warn_init(Gio.DBusMethodInfo)
__all__.append('DBusMethodInfo')
@override
class DBusSignalInfo(Gio.DBusSignalInfo):
__init__ = _warn_init(Gio.DBusSignalInfo)
__all__.append('DBusSignalInfo')
@override
class DBusInterfaceInfo(Gio.DBusInterfaceInfo):
__init__ = _warn_init(Gio.DBusInterfaceInfo)
__all__.append('DBusInterfaceInfo')
@override
class DBusNodeInfo(Gio.DBusNodeInfo):
__init__ = _warn_init(Gio.DBusNodeInfo)
__all__.append('DBusNodeInfo')
class ActionMap(Gio.ActionMap):
def add_action_entries(self, entries, user_data=None):
"""
The add_action_entries() method is a convenience function for creating
multiple Gio.SimpleAction instances and adding them to a Gio.ActionMap.
Each action is constructed as per one entry.
:param list entries:
List of entry tuples for add_action() method. The entry tuple can
vary in size with the following information:
* The name of the action. Must be specified.
* The callback to connect to the "activate" signal of the
action. Since GLib 2.40, this can be None for stateful
actions, in which case the default handler is used. For
boolean-stated actions with no parameter, this is a toggle.
For other state types (and parameter type equal to the state
type) this will be a function that just calls change_state
(which you should provide).
* The type of the parameter that must be passed to the activate
function for this action, given as a single GLib.Variant type
string (or None for no parameter)
* The initial state for this action, given in GLib.Variant text
format. The state is parsed with no extra type information, so
type tags must be added to the string if they are necessary.
Stateless actions should give None here.
* The callback to connect to the "change-state" signal of the
action. All stateful actions should provide a handler here;
stateless actions should not.
:param user_data:
The user data for signal connections, or None
"""
try:
iter(entries)
except (TypeError):
raise TypeError('entries must be iterable')
def _process_action(name, activate=None, parameter_type=None,
state=None, change_state=None):
if parameter_type:
if not GLib.VariantType.string_is_valid(parameter_type):
raise TypeError("The type string '%s' given as the "
"parameter type for action '%s' is "
"not a valid GVariant type string. " %
(parameter_type, name))
variant_parameter = GLib.VariantType.new(parameter_type)
else:
variant_parameter = None
if state is not None:
# stateful action
variant_state = GLib.Variant.parse(None, state, None, None)
action = Gio.SimpleAction.new_stateful(name, variant_parameter,
variant_state)
if change_state is not None:
action.connect('change-state', change_state, user_data)
else:
# stateless action
if change_state is not None:
raise ValueError("Stateless action '%s' should give "
"None for 'change_state', not '%s'." %
(name, change_state))
action = Gio.SimpleAction(name=name, parameter_type=variant_parameter)
if activate is not None:
action.connect('activate', activate, user_data)
self.add_action(action)
for entry in entries:
# using inner function above since entries can leave out optional arguments
_process_action(*entry)
ActionMap = override(ActionMap)
__all__.append('ActionMap')
class FileEnumerator(Gio.FileEnumerator):
def __iter__(self):
return self
def __next__(self):
file_info = self.next_file(None)
if file_info is not None:
return file_info
else:
raise StopIteration
# python 2 compat for the iter protocol
next = __next__
FileEnumerator = override(FileEnumerator)
__all__.append('FileEnumerator')
class MenuItem(Gio.MenuItem):
def set_attribute(self, attributes):
for (name, format_string, value) in attributes:
self.set_attribute_value(name, GLib.Variant(format_string, value))
MenuItem = override(MenuItem)
__all__.append('MenuItem')
class Settings(Gio.Settings):
'''Provide dictionary-like access to GLib.Settings.'''
__init__ = deprecated_init(Gio.Settings.__init__,
arg_names=('schema', 'path', 'backend'))
def __contains__(self, key):
return key in self.list_keys()
def __len__(self):
return len(self.list_keys())
def __iter__(self):
for key in self.list_keys():
yield key
def __bool__(self):
# for "if mysettings" we don't want a dictionary-like test here, just
# if the object isn't None
return True
# alias for Python 2.x object protocol
__nonzero__ = __bool__
def __getitem__(self, key):
# get_value() aborts the program on an unknown key
if key not in self:
raise KeyError('unknown key: %r' % (key,))
return self.get_value(key).unpack()
def __setitem__(self, key, value):
# set_value() aborts the program on an unknown key
if key not in self:
raise KeyError('unknown key: %r' % (key,))
# determine type string of this key
range = self.get_range(key)
type_ = range.get_child_value(0).get_string()
v = range.get_child_value(1)
if type_ == 'type':
# v is boxed empty array, type of its elements is the allowed value type
type_str = v.get_child_value(0).get_type_string()
assert type_str.startswith('a')
type_str = type_str[1:]
elif type_ == 'enum':
# v is an array with the allowed values
assert v.get_child_value(0).get_type_string().startswith('a')
type_str = v.get_child_value(0).get_child_value(0).get_type_string()
allowed = v.unpack()
if value not in allowed:
raise ValueError('value %s is not an allowed enum (%s)' % (value, allowed))
elif type_ == 'range':
tuple_ = v.get_child_value(0)
type_str = tuple_.get_child_value(0).get_type_string()
min_, max_ = tuple_.unpack()
if value < min_ or value > max_:
raise ValueError(
'value %s not in range (%s - %s)' % (value, min_, max_))
else:
raise NotImplementedError('Cannot handle allowed type range class ' + str(type_))
self.set_value(key, GLib.Variant(type_str, value))
def keys(self):
return self.list_keys()
Settings = override(Settings)
__all__.append('Settings')
class _DBusProxyMethodCall:
'''Helper class to implement DBusProxy method calls.'''
def __init__(self, dbus_proxy, method_name):
self.dbus_proxy = dbus_proxy
self.method_name = method_name
def __async_result_handler(self, obj, result, user_data):
(result_callback, error_callback, real_user_data) = user_data
try:
ret = obj.call_finish(result)
except Exception:
etype, e = sys.exc_info()[:2]
# return exception as value
if error_callback:
error_callback(obj, e, real_user_data)
else:
result_callback(obj, e, real_user_data)
return
result_callback(obj, self._unpack_result(ret), real_user_data)
def __call__(self, *args, **kwargs):
# the first positional argument is the signature, unless we are calling
# a method without arguments; then signature is implied to be '()'.
if args:
signature = args[0]
args = args[1:]
if not isinstance(signature, str):
raise TypeError('first argument must be the method signature string: %r' % signature)
else:
signature = '()'
arg_variant = GLib.Variant(signature, tuple(args))
if 'result_handler' in kwargs:
# asynchronous call
user_data = (kwargs['result_handler'],
kwargs.get('error_handler'),
kwargs.get('user_data'))
self.dbus_proxy.call(self.method_name, arg_variant,
kwargs.get('flags', 0), kwargs.get('timeout', -1), None,
self.__async_result_handler, user_data)
else:
# synchronous call
result = self.dbus_proxy.call_sync(self.method_name, arg_variant,
kwargs.get('flags', 0),
kwargs.get('timeout', -1),
None)
return self._unpack_result(result)
@classmethod
def _unpack_result(klass, result):
'''Convert a D-BUS return variant into an appropriate return value'''
result = result.unpack()
# to be compatible with standard Python behaviour, unbox
# single-element tuples and return None for empty result tuples
if len(result) == 1:
result = result[0]
elif len(result) == 0:
result = None
return result
class DBusProxy(Gio.DBusProxy):
'''Provide comfortable and pythonic method calls.
This marshalls the method arguments into a GVariant, invokes the
call_sync() method on the DBusProxy object, and unmarshalls the result
GVariant back into a Python tuple.
The first argument always needs to be the D-Bus signature tuple of the
method call. Example:
proxy = Gio.DBusProxy.new_sync(...)
result = proxy.MyMethod('(is)', 42, 'hello')
The exception are methods which take no arguments, like
proxy.MyMethod('()'). For these you can omit the signature and just write
proxy.MyMethod().
Optional keyword arguments:
- timeout: timeout for the call in milliseconds (default to D-Bus timeout)
- flags: Combination of Gio.DBusCallFlags.*
- result_handler: Do an asynchronous method call and invoke
result_handler(proxy_object, result, user_data) when it finishes.
- error_handler: If the asynchronous call raises an exception,
error_handler(proxy_object, exception, user_data) is called when it
finishes. If error_handler is not given, result_handler is called with
the exception object as result instead.
- user_data: Optional user data to pass to result_handler for
asynchronous calls.
Example for asynchronous calls:
def mymethod_done(proxy, result, user_data):
if isinstance(result, Exception):
# handle error
else:
# do something with result
proxy.MyMethod('(is)', 42, 'hello',
result_handler=mymethod_done, user_data='data')
'''
def __getattr__(self, name):
return _DBusProxyMethodCall(self, name)
DBusProxy = override(DBusProxy)
__all__.append('DBusProxy')
class ListModel(Gio.ListModel):
def __getitem__(self, key):
if isinstance(key, slice):
return [self.get_item(i) for i in range(*key.indices(len(self)))]
elif isinstance(key, int):
if key < 0:
key += len(self)
if key < 0:
raise IndexError
ret = self.get_item(key)
if ret is None:
raise IndexError
return ret
else:
raise TypeError
def __contains__(self, item):
pytype = self.get_item_type().pytype
if not isinstance(item, pytype):
raise TypeError(
"Expected type %s.%s" % (pytype.__module__, pytype.__name__))
for i in self:
if i == item:
return True
return False
def __len__(self):
return self.get_n_items()
def __iter__(self):
for i in range(len(self)):
yield self.get_item(i)
ListModel = override(ListModel)
__all__.append('ListModel')
if (GLib.MAJOR_VERSION, GLib.MINOR_VERSION, GLib.MICRO_VERSION) < (2, 57, 1):
# The "additions" functionality in splice() was broken in older glib
# https://bugzilla.gnome.org/show_bug.cgi?id=795307
# This is a slower fallback which emits a signal per added item
def _list_store_splice(self, position, n_removals, additions):
self.splice(position, n_removals, [])
for v in reversed(additions):
self.insert(position, v)
else:
def _list_store_splice(self, position, n_removals, additions):
self.splice(position, n_removals, additions)
class ListStore(Gio.ListStore):
def sort(self, compare_func, *user_data):
compare_func = wrap_list_store_sort_func(compare_func)
return super(ListStore, self).sort(compare_func, *user_data)
def insert_sorted(self, item, compare_func, *user_data):
compare_func = wrap_list_store_sort_func(compare_func)
return super(ListStore, self).insert_sorted(
item, compare_func, *user_data)
def __delitem__(self, key):
if isinstance(key, slice):
start, stop, step = key.indices(len(self))
if step == 1:
_list_store_splice(self, start, max(stop - start, 0), [])
elif step == -1:
_list_store_splice(self, stop + 1, max(start - stop, 0), [])
else:
for i in sorted(range(start, stop, step), reverse=True):
self.remove(i)
elif isinstance(key, int):
if key < 0:
key += len(self)
if key < 0 or key >= len(self):
raise IndexError
self.remove(key)
else:
raise TypeError
def __setitem__(self, key, value):
if isinstance(key, slice):
pytype = self.get_item_type().pytype
valuelist = []
for v in value:
if not isinstance(v, pytype):
raise TypeError(
"Expected type %s.%s" % (
pytype.__module__, pytype.__name__))
valuelist.append(v)
start, stop, step = key.indices(len(self))
if step == 1:
_list_store_splice(
self, start, max(stop - start, 0), valuelist)
else:
indices = list(range(start, stop, step))
if len(indices) != len(valuelist):
raise ValueError
if step == -1:
_list_store_splice(
self, stop + 1, max(start - stop, 0), valuelist[::-1])
else:
for i, v in zip(indices, valuelist):
_list_store_splice(self, i, 1, [v])
elif isinstance(key, int):
if key < 0:
key += len(self)
if key < 0 or key >= len(self):
raise IndexError
pytype = self.get_item_type().pytype
if not isinstance(value, pytype):
raise TypeError(
"Expected type %s.%s" % (
pytype.__module__, pytype.__name__))
_list_store_splice(self, key, 1, [value])
else:
raise TypeError
ListStore = override(ListStore)
__all__.append('ListStore')
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,58 @@
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2010 Paolo Borelli <pborelli@gnome.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
from ..overrides import override
from ..module import get_introspection_module
Pango = get_introspection_module('Pango')
__all__ = []
class FontDescription(Pango.FontDescription):
def __new__(cls, string=None):
if string is not None:
return Pango.font_description_from_string(string)
else:
return Pango.FontDescription.__new__(cls)
def __init__(self, *args, **kwargs):
return super(FontDescription, self).__init__()
FontDescription = override(FontDescription)
__all__.append('FontDescription')
class Layout(Pango.Layout):
def __new__(cls, context):
return Pango.Layout.new(context)
def set_markup(self, text, length=-1):
super(Layout, self).set_markup(text, length)
def set_text(self, text, length=-1):
super(Layout, self).set_text(text, length)
Layout = override(Layout)
__all__.append('Layout')
@@ -0,0 +1,347 @@
import functools
import types
import warnings
import importlib
import sys
from gi import PyGIDeprecationWarning
from gi._gi import CallableInfo, pygobject_new_full
from gi._constants import \
TYPE_NONE, \
TYPE_INVALID
# support overrides in different directories than our gi module
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
# namespace -> (attr, replacement)
_deprecated_attrs = {}
class OverridesProxyModule(types.ModuleType):
"""Wraps a introspection module and contains all overrides"""
def __init__(self, introspection_module):
super(OverridesProxyModule, self).__init__(
introspection_module.__name__)
self._introspection_module = introspection_module
def __getattr__(self, name):
return getattr(self._introspection_module, name)
def __dir__(self):
result = set(dir(self.__class__))
result.update(self.__dict__.keys())
result.update(dir(self._introspection_module))
return sorted(result)
def __repr__(self):
return "<%s %r>" % (type(self).__name__, self._introspection_module)
class _DeprecatedAttribute(object):
"""A deprecation descriptor for OverridesProxyModule subclasses.
Emits a PyGIDeprecationWarning on every access and tries to act as a
normal instance attribute (can be replaced and deleted).
"""
def __init__(self, namespace, attr, value, replacement):
self._attr = attr
self._value = value
self._warning = PyGIDeprecationWarning(
'%s.%s is deprecated; use %s instead' % (
namespace, attr, replacement))
def __get__(self, instance, owner):
if instance is None:
raise AttributeError(self._attr)
warnings.warn(self._warning, stacklevel=2)
return self._value
def __set__(self, instance, value):
attr = self._attr
# delete the descriptor, then set the instance value
delattr(type(instance), attr)
setattr(instance, attr, value)
def __delete__(self, instance):
# delete the descriptor
delattr(type(instance), self._attr)
def load_overrides(introspection_module):
"""Loads overrides for an introspection module.
Either returns the same module again in case there are no overrides or a
proxy module including overrides. Doesn't cache the result.
"""
namespace = introspection_module.__name__.rsplit(".", 1)[-1]
module_key = 'gi.repository.' + namespace
# We use sys.modules so overrides can import from gi.repository
# but restore everything at the end so this doesn't have any side effects
has_old = module_key in sys.modules
old_module = sys.modules.get(module_key)
# Create a new sub type, so we can separate descriptors like
# _DeprecatedAttribute for each namespace.
proxy_type = type(namespace + "ProxyModule", (OverridesProxyModule, ), {})
proxy = proxy_type(introspection_module)
sys.modules[module_key] = proxy
# backwards compat:
# gedit uses gi.importer.modules['Gedit']._introspection_module
from ..importer import modules
assert hasattr(proxy, "_introspection_module")
modules[namespace] = proxy
try:
override_package_name = 'gi.overrides.' + namespace
spec = importlib.util.find_spec(override_package_name)
override_loader = spec.loader if spec is not None else None
# Avoid checking for an ImportError, an override might
# depend on a missing module thus causing an ImportError
if override_loader is None:
return introspection_module
override_mod = importlib.import_module(override_package_name)
finally:
del modules[namespace]
del sys.modules[module_key]
if has_old:
sys.modules[module_key] = old_module
# backwards compat: for gst-python/gstmodule.c,
# which tries to access Gst.Fraction through
# Gst._overrides_module.Fraction. We assign the proxy instead as that
# contains all overridden classes like Fraction during import anyway and
# there is no need to keep the real override module alive.
proxy._overrides_module = proxy
override_all = []
if hasattr(override_mod, "__all__"):
override_all = override_mod.__all__
for var in override_all:
try:
item = getattr(override_mod, var)
except (AttributeError, TypeError):
# Gedit puts a non-string in __all__, so catch TypeError here
continue
setattr(proxy, var, item)
# Replace deprecated module level attributes with a descriptor
# which emits a warning when accessed.
for attr, replacement in _deprecated_attrs.pop(namespace, []):
try:
value = getattr(proxy, attr)
except AttributeError:
raise AssertionError(
"%s was set deprecated but wasn't added to __all__" % attr)
delattr(proxy, attr)
deprecated_attr = _DeprecatedAttribute(
namespace, attr, value, replacement)
setattr(proxy_type, attr, deprecated_attr)
return proxy
def override(type_):
"""Decorator for registering an override.
Other than objects added to __all__, these can get referenced in the same
override module via the gi.repository module (get_parent_for_object() does
for example), so they have to be added to the module immediately.
"""
if isinstance(type_, CallableInfo):
func = type_
namespace = func.__module__.rsplit('.', 1)[-1]
module = sys.modules["gi.repository." + namespace]
def wrapper(func):
setattr(module, func.__name__, func)
return func
return wrapper
elif isinstance(type_, types.FunctionType):
raise TypeError("func must be a gi function, got %s" % type_)
else:
try:
info = getattr(type_, '__info__')
except AttributeError:
raise TypeError(
'Can not override a type %s, which is not in a gobject '
'introspection typelib' % type_.__name__)
if not type_.__module__.startswith('gi.overrides'):
raise KeyError(
'You have tried override outside of the overrides module. '
'This is not allowed (%s, %s)' % (type_, type_.__module__))
g_type = info.get_g_type()
assert g_type != TYPE_NONE
if g_type != TYPE_INVALID:
g_type.pytype = type_
namespace = type_.__module__.rsplit(".", 1)[-1]
module = sys.modules["gi.repository." + namespace]
setattr(module, type_.__name__, type_)
return type_
overridefunc = override
"""Deprecated"""
def deprecated(fn, replacement):
"""Decorator for marking methods and classes as deprecated"""
@functools.wraps(fn)
def wrapped(*args, **kwargs):
warnings.warn('%s is deprecated; use %s instead' % (fn.__name__, replacement),
PyGIDeprecationWarning, stacklevel=2)
return fn(*args, **kwargs)
return wrapped
def deprecated_attr(namespace, attr, replacement):
"""Marks a module level attribute as deprecated. Accessing it will emit
a PyGIDeprecationWarning warning.
e.g. for ``deprecated_attr("GObject", "STATUS_FOO", "GLib.Status.FOO")``
accessing GObject.STATUS_FOO will emit:
"GObject.STATUS_FOO is deprecated; use GLib.Status.FOO instead"
:param str namespace:
The namespace of the override this is called in.
:param str namespace:
The attribute name (which gets added to __all__).
:param str replacement:
The replacement text which will be included in the warning.
"""
_deprecated_attrs.setdefault(namespace, []).append((attr, replacement))
def deprecated_init(super_init_func, arg_names, ignore=tuple(),
deprecated_aliases={}, deprecated_defaults={},
category=PyGIDeprecationWarning,
stacklevel=2):
"""Wrapper for deprecating GObject based __init__ methods which specify
defaults already available or non-standard defaults.
:param callable super_init_func:
Initializer to wrap.
:param list arg_names:
Ordered argument name list.
:param list ignore:
List of argument names to ignore when calling the wrapped function.
This is useful for function which take a non-standard keyword that is munged elsewhere.
:param dict deprecated_aliases:
Dictionary mapping a keyword alias to the actual g_object_newv keyword.
:param dict deprecated_defaults:
Dictionary of non-standard defaults that will be used when the
keyword is not explicitly passed.
:param Exception category:
Exception category of the error.
:param int stacklevel:
Stack level for the deprecation passed on to warnings.warn
:returns: Wrapped version of ``super_init_func`` which gives a deprecation
warning when non-keyword args or aliases are used.
:rtype: callable
"""
# We use a list of argument names to maintain order of the arguments
# being deprecated. This allows calls with positional arguments to
# continue working but with a deprecation message.
def new_init(self, *args, **kwargs):
"""Initializer for a GObject based classes with support for property
sets through the use of explicit keyword arguments.
"""
# Print warnings for calls with positional arguments.
if args:
warnings.warn('Using positional arguments with the GObject constructor has been deprecated. '
'Please specify keyword(s) for "%s" or use a class specific constructor. '
'See: https://wiki.gnome.org/PyGObject/InitializerDeprecations' %
', '.join(arg_names[:len(args)]),
category, stacklevel=stacklevel)
new_kwargs = dict(zip(arg_names, args))
else:
new_kwargs = {}
new_kwargs.update(kwargs)
# Print warnings for alias usage and transfer them into the new key.
aliases_used = []
for key, alias in deprecated_aliases.items():
if alias in new_kwargs:
new_kwargs[key] = new_kwargs.pop(alias)
aliases_used.append(key)
if aliases_used:
warnings.warn('The keyword(s) "%s" have been deprecated in favor of "%s" respectively. '
'See: https://wiki.gnome.org/PyGObject/InitializerDeprecations' %
(', '.join(deprecated_aliases[k] for k in sorted(aliases_used)),
', '.join(sorted(aliases_used))),
category, stacklevel=stacklevel)
# Print warnings for defaults different than what is already provided by the property
defaults_used = []
for key, value in deprecated_defaults.items():
if key not in new_kwargs:
new_kwargs[key] = deprecated_defaults[key]
defaults_used.append(key)
if defaults_used:
warnings.warn('Initializer is relying on deprecated non-standard '
'defaults. Please update to explicitly use: %s '
'See: https://wiki.gnome.org/PyGObject/InitializerDeprecations' %
', '.join('%s=%s' % (k, deprecated_defaults[k]) for k in sorted(defaults_used)),
category, stacklevel=stacklevel)
# Remove keywords that should be ignored.
for key in ignore:
if key in new_kwargs:
new_kwargs.pop(key)
return super_init_func(self, **new_kwargs)
return new_init
def strip_boolean_result(method, exc_type=None, exc_str=None, fail_ret=None):
"""Translate method's return value for stripping off success flag.
There are a lot of methods which return a "success" boolean and have
several out arguments. Translate such a method to return the out arguments
on success and None on failure.
"""
@functools.wraps(method)
def wrapped(*args, **kwargs):
ret = method(*args, **kwargs)
if ret[0]:
if len(ret) == 2:
return ret[1]
else:
return ret[1:]
else:
if exc_type:
raise exc_type(exc_str or 'call failed')
return fail_ret
return wrapped
def wrap_list_store_sort_func(func):
def wrap(a, b, *user_data):
a = pygobject_new_full(a, False)
b = pygobject_new_full(b, False)
return func(a, b, *user_data)
return wrap
@@ -0,0 +1,53 @@
# -*- Mode: Python; py-indent-offset: 4 -*-
# pygtk - Python bindings for the GTK toolkit.
# Copyright (C) 1998-2003 James Henstridge
#
# gtk/keysyms.py: list of keysyms.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, see <http://www.gnu.org/licenses/>.
import sys
import warnings
from ..module import get_introspection_module
Gdk = get_introspection_module('Gdk')
warnings.warn('keysyms has been deprecated. Please use Gdk.KEY_<name> instead.',
RuntimeWarning)
_modname = globals()['__name__']
_keysyms = sys.modules[_modname]
for name in dir(Gdk):
if name.startswith('KEY_'):
target = name[4:]
if target[0] in '0123456789':
target = '_' + target
value = getattr(Gdk, name)
setattr(_keysyms, target, value)
# Not found in Gdk but left for compatibility.
Armenian_eternity = 0x14a1
Armenian_section_sign = 0x14a2
Armenian_parenleft = 0x14a5
Armenian_guillemotright = 0x14a6
Armenian_guillemotleft = 0x14a7
Armenian_em_dash = 0x14a8
Armenian_dot = 0x14a9
Armenian_mijaket = 0x14a9
Armenian_comma = 0x14ab
Armenian_en_dash = 0x14ac
Armenian_ellipsis = 0x14ae