Skip to content

Commit

Permalink
Merge tag 'pullme2'
Browse files Browse the repository at this point in the history
concise cpu usage and headers

# gpg: Signature made Sun Jun 16 08:25:49 2019 CEST
# gpg:                using RSA key E62A8B3E4E5A57D8B9675914721D7426F72E63AC
# gpg: Good signature from "Air Elemental <[email protected]>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: E62A 8B3E 4E5A 57D8 B967  5914 721D 7426 F72E 63AC

* tag 'pullme2':
  fix trailing whitespace, unused imports
  revert arbitrary version string
  remove unused code
  whitespace fixes, better description
  don't show submenu for header; rename memory header
  show headers using update_state(), instead of as initial value
  headers; hide 0% cpu
  fix double-digit cpu percentage interfering with memory display
  Move cpu percentage text to the left of the bar
  • Loading branch information
marmarek committed Jun 16, 2019
2 parents c2c627e + 971d5dd commit 7e6b7ce
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 44 deletions.
38 changes: 25 additions & 13 deletions qui/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
'''
# pylint: disable=wrong-import-position,import-error

import qubesadmin
import gi # isort:skip
gi.require_version('Gtk', '3.0') # isort:skip
from gi.repository import Gtk, Pango # isort:skip
Expand All @@ -31,36 +30,47 @@ def set_margins(self, widget):
class DomainDecorator(PropertiesDecorator):
''' Useful methods for domain data representation '''

def __init__(self, vm: qubesadmin.vm.QubesVM, margins=(5, 5)) -> None:
def __init__(self, vm, margins=(5, 5)) -> None:
super(DomainDecorator, self).__init__(vm, margins)
self.vm = vm

def name(self):
label = Gtk.Label(self.vm.name, xalign=0)
label = Gtk.Label(xalign=0)
label.set_markup('<b>Qube</b>')
self.set_margins(label)
return label

class VMCPU(Gtk.Box):
def __init__(self):
super(DomainDecorator.VMCPU, self).__init__()
self.cpu_bar = Gtk.ProgressBar()
self.cpu_bar.set_show_text(True)
self.cpu_bar.set_text("CPU")
self.pack_start(self.cpu_bar, True, True, 0)

def update_state(self, cpu=0):
self.cpu_bar.set_fraction(cpu/100)
self.cpu_bar.set_text("{}% CPU".format(cpu))
self.cpu_label = Gtk.Label(xalign=1)
self.cpu_label.set_width_chars(6)
self.pack_start(self.cpu_label, True, True, 0)

def update_state(self, cpu=0, header=False):
if header:
markup = '<b>CPU</b>'
elif cpu > 0:
markup = '{:3d}%'.format(cpu)
else:
markup = ''

self.cpu_label.set_markup(markup)

class VMMem(Gtk.Box):
def __init__(self):
super(DomainDecorator.VMMem, self).__init__()
self.mem_label = Gtk.Label(xalign=1)
self.pack_start(self.mem_label, True, True, 0)

def update_state(self, memory=0):
self.mem_label.set_markup(
'{} MB'.format(str(int(memory/1024))))
def update_state(self, memory=0, header=False):
if header:
markup = '<b>RAM</b>'
else:
markup = '{} MB'.format(str(int(memory/1024)))

self.mem_label.set_markup(markup)

def memory(self):
mem_widget = DomainDecorator.VMMem()
Expand All @@ -77,6 +87,8 @@ def cpu(self):

def icon(self) -> Gtk.Image:
''' Returns a `Gtk.Image` containing the colored lock icon '''
if self.vm is None: # should not be called
return None
try:
# this is a temporary, emergency fix for unexecpected conflict with
# qui-devices rewrite
Expand Down
50 changes: 19 additions & 31 deletions qui/tray/domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import qui.decorators
import gi # isort:skip
gi.require_version('Gtk', '3.0') # isort:skip
from gi.repository import Gio, Gtk, Gdk # isort:skip
from gi.repository import Gio, Gtk # isort:skip

import gbulb
gbulb.install()
Expand Down Expand Up @@ -155,7 +155,6 @@ def __init__(self, vm):
def run_terminal(self, _item):
self.vm.run_service('qubes.StartApp+qubes-run-terminal')


class StartedMenu(Gtk.Menu):
''' The sub-menu for a started domain'''

Expand Down Expand Up @@ -219,42 +218,45 @@ def __init__(self):

self.connect('activate', run_manager)


class DomainMenuItem(Gtk.ImageMenuItem):
def __init__(self, vm):
super().__init__()
self.vm = vm
# set vm := None to make this output headers.
# Header menu item reuses the domain menu item code
# so headers are aligned with the columns.

self.decorator = qui.decorators.DomainDecorator(vm)

hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
# hbox.set_homogeneous(True)

namebox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)

self.name = self.decorator.name()
namebox.pack_start(self.name, True, True, 0)

self.spinner = Gtk.Spinner()
namebox.pack_start(self.spinner, False, True, 0)

hbox.pack_start(namebox, True, True, 0)

mem_cpu_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
# mem_cpu_box.set_homogeneous(True)

self.memory = self.decorator.memory()
mem_cpu_box.pack_start(self.memory, False, True, 0)

self.cpu = self.decorator.cpu()
mem_cpu_box.pack_start(self.cpu, False, True, 0)

hbox.pack_start(mem_cpu_box, False, True, 0)

self.add(hbox)

self.update_state(self.vm.get_power_state())
self._set_image()
if self.vm is None: # if header
self.set_reserve_indicator(True) # align with submenu triangles
self.cpu.update_state(header=True)
self.memory.update_state(header=True)
else:
self.update_state(self.vm.get_power_state())
self._set_image()

def _set_image(self):
self.set_image(self.decorator.icon())
Expand Down Expand Up @@ -286,6 +288,10 @@ def hide_spinner(self):
self.spinner.hide()

def update_state(self, state):

if self.vm is None:
return

if state in ['Running', 'Paused']:
self.hide_spinner()
else:
Expand All @@ -296,6 +302,7 @@ def update_state(self, state):
colormap[state], self.vm.name))
else:
self.name.set_label(self.vm.name)

self._set_submenu(state)

def update_stats(self, memory_kb, cpu_usage):
Expand Down Expand Up @@ -327,31 +334,10 @@ def __init__(self, app_name, qapp, dispatcher, stats_dispatcher):
self.add_action(self.unpause_all_action)
self.pause_notification_out = False

self.load_css()

self.register_events()
self.set_application_id(app_name)
self.register() # register Gtk Application

@staticmethod
def load_css():
style_provider = Gtk.CssProvider()
css = b'''
progress {
min-height: 10px;
}
trough {
min-height: 10px;
border: 1px;
}
'''
style_provider.load_from_data(css)

Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

def register_events(self):
self.dispatcher.add_handler('domain-pre-start', self.update_domain_item)
self.dispatcher.add_handler('domain-start', self.update_domain_item)
Expand Down Expand Up @@ -380,6 +366,7 @@ def register_events(self):

def show_menu(self, _, event):
menu = Gtk.Menu()
menu.add(DomainMenuItem(None))
for vm in sorted(self.menu_items):
self.tray_menu.remove(self.menu_items[vm])
menu.add(self.menu_items[vm])
Expand Down Expand Up @@ -467,7 +454,8 @@ def add_domain_item(self, vm, _event, **_kwargs):
domain_item = DomainMenuItem(vm)
position = 0
for i in self.tray_menu: # pylint: disable=not-an-iterable
if not hasattr(i, 'vm') or i.vm.name > vm.name:
if not hasattr(i, 'vm') \
or (i.vm is not None and i.vm.name > vm.name):
break
position += 1
self.tray_menu.insert(domain_item, position)
Expand Down

0 comments on commit 7e6b7ce

Please sign in to comment.