get-state: Use native Gio APIs to get the current config
Also provide multiple readers into a class that can be expanded to also configure mutter. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2448>
This commit is contained in:
parent
b02d746512
commit
3553af257e
1 changed files with 82 additions and 33 deletions
|
@ -5,12 +5,12 @@ import enum
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib, Gio
|
||||||
|
|
||||||
|
|
||||||
class Source(enum.Enum):
|
NAME = 'org.gnome.Mutter.DisplayConfig'
|
||||||
DBUS = 1
|
INTERFACE = 'org.gnome.Mutter.DisplayConfig'
|
||||||
FILE = 2
|
OBJECT_PATH = '/org/gnome/Mutter/DisplayConfig'
|
||||||
|
|
||||||
TRANSFORM_STRINGS = {
|
TRANSFORM_STRINGS = {
|
||||||
0: 'normal',
|
0: 'normal',
|
||||||
|
@ -23,6 +23,69 @@ TRANSFORM_STRINGS = {
|
||||||
7: 'flipped-270',
|
7: 'flipped-270',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Source(enum.Enum):
|
||||||
|
DBUS = 1
|
||||||
|
COMMAND_LINE = 2
|
||||||
|
FILE = 3
|
||||||
|
|
||||||
|
|
||||||
|
class MonitorConfig:
|
||||||
|
CONFIG_VARIANT_TYPE = GLib.VariantType.new(
|
||||||
|
'(ua((ssss)a(siiddada{sv})a{sv})a(iiduba(ssss)a{sv})a{sv})')
|
||||||
|
|
||||||
|
def get_current_state(self) -> GLib.Variant:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
class MonitorConfigDBus(MonitorConfig):
|
||||||
|
def __init__(self):
|
||||||
|
self._proxy = Gio.DBusProxy.new_for_bus_sync(
|
||||||
|
bus_type=Gio.BusType.SESSION,
|
||||||
|
flags=Gio.DBusProxyFlags.NONE,
|
||||||
|
info=None,
|
||||||
|
name=NAME,
|
||||||
|
object_path=OBJECT_PATH,
|
||||||
|
interface_name=INTERFACE,
|
||||||
|
cancellable=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_current_state(self) -> GLib.Variant:
|
||||||
|
variant = self._proxy.call_sync(
|
||||||
|
method_name='GetCurrentState',
|
||||||
|
parameters=None,
|
||||||
|
flags=Gio.DBusCallFlags.NO_AUTO_START,
|
||||||
|
timeout_msec=-1,
|
||||||
|
cancellable=None
|
||||||
|
)
|
||||||
|
assert variant.get_type().equal(self.CONFIG_VARIANT_TYPE)
|
||||||
|
return variant
|
||||||
|
|
||||||
|
|
||||||
|
class MonitorConfigCommandLine(MonitorConfig):
|
||||||
|
def get_current_state(self) -> GLib.Variant:
|
||||||
|
command = ('gdbus call -e '
|
||||||
|
f'-d {NAME} '
|
||||||
|
f'-o {OBJECT_PATH} '
|
||||||
|
f'-m {INTERFACE}.GetCurrentState')
|
||||||
|
|
||||||
|
result = subprocess.run(command, shell=True,
|
||||||
|
check=True, capture_output=True, text=True)
|
||||||
|
return GLib.variant_parse(self.CONFIG_VARIANT_TYPE, result.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
class MonitorConfigFile(MonitorConfig):
|
||||||
|
def __init__(self, file_path):
|
||||||
|
if file_path == '-':
|
||||||
|
self._data = sys.stdin.read()
|
||||||
|
else:
|
||||||
|
with open(file_path) as file:
|
||||||
|
self._data = file.read()
|
||||||
|
|
||||||
|
def get_current_state(self) -> GLib.Variant:
|
||||||
|
return GLib.variant_parse(self.CONFIG_VARIANT_TYPE, self._data)
|
||||||
|
|
||||||
|
|
||||||
def print_data(level, is_last, lines, data):
|
def print_data(level, is_last, lines, data):
|
||||||
if is_last:
|
if is_last:
|
||||||
link = '└'
|
link = '└'
|
||||||
|
@ -61,34 +124,9 @@ def print_properties(level, lines, properties):
|
||||||
print_data(level + 1, is_last, lines,
|
print_data(level + 1, is_last, lines,
|
||||||
f'{property} ⇒ {properties[property]}')
|
f'{property} ⇒ {properties[property]}')
|
||||||
|
|
||||||
def print_current_state(args):
|
|
||||||
if args.file:
|
|
||||||
source = Source.FILE
|
|
||||||
path = args.file
|
|
||||||
else:
|
|
||||||
source = Source.DBUS
|
|
||||||
|
|
||||||
short = args.short
|
def print_current_state(monitor_config, short):
|
||||||
|
variant = monitor_config.get_current_state()
|
||||||
type_signature = '(ua((ssss)a(siiddada{sv})a{sv})a(iiduba(ssss)a{sv})a{sv})'
|
|
||||||
variant_type = GLib.VariantType.new(type_signature)
|
|
||||||
|
|
||||||
if source == Source.DBUS:
|
|
||||||
command = 'gdbus call -e '\
|
|
||||||
'-d org.gnome.Mutter.DisplayConfig '\
|
|
||||||
'-o /org/gnome/Mutter/DisplayConfig '\
|
|
||||||
'-m org.gnome.Mutter.DisplayConfig.GetCurrentState'
|
|
||||||
result = subprocess.run(command,
|
|
||||||
shell=True, check=True, capture_output=True, text=True)
|
|
||||||
data = result.stdout
|
|
||||||
else:
|
|
||||||
if path == '-':
|
|
||||||
data = sys.stdin.read()
|
|
||||||
else:
|
|
||||||
with open(path) as file:
|
|
||||||
data = file.read()
|
|
||||||
|
|
||||||
variant = GLib.variant_parse(variant_type, data)
|
|
||||||
|
|
||||||
print('Serial: {}'.format(variant[0]))
|
print('Serial: {}'.format(variant[0]))
|
||||||
print()
|
print()
|
||||||
|
@ -162,10 +200,21 @@ def print_current_state(args):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description='Get display state')
|
parser = argparse.ArgumentParser(description='Get display state')
|
||||||
parser.add_argument('file', metavar='FILE', type=str, nargs='?',
|
parser.add_argument('--file', metavar='FILE', type=str, nargs='?',
|
||||||
help='Read the output from gdbus call instead of calling D-Bus')
|
help='Read the output from gdbus call instead of calling D-Bus')
|
||||||
|
parser.add_argument('--gdbus', action='store_true')
|
||||||
parser.add_argument('--short', action='store_true')
|
parser.add_argument('--short', action='store_true')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
print_current_state(args)
|
if args.file and args.gdbus:
|
||||||
|
raise argparse.ArgumentTypeError('Incompatible arguments')
|
||||||
|
|
||||||
|
if args.file:
|
||||||
|
monitor_config = MonitorConfigFile(args.file)
|
||||||
|
elif args.gdbus:
|
||||||
|
monitor_config = MonitorConfigCommandLine()
|
||||||
|
else:
|
||||||
|
monitor_config = MonitorConfigDBus()
|
||||||
|
|
||||||
|
print_current_state(monitor_config, short=args.short)
|
||||||
|
|
Loading…
Reference in a new issue