xapp-2.8.2/ 0000775 0001750 0001750 00000000000 14545562517 011435 5 ustar fabio fabio xapp-2.8.2/schemas/ 0000775 0001750 0001750 00000000000 14545562517 013060 5 ustar fabio fabio xapp-2.8.2/schemas/meson.build 0000664 0001750 0001750 00000000251 14545562517 015220 0 ustar fabio fabio install_data('org.x.apps.gschema.xml',
install_dir: join_paths(get_option('datadir'), 'glib-2.0', 'schemas')
)
meson.add_install_script('meson_install_schemas.py')
xapp-2.8.2/schemas/org.x.apps.gschema.xml 0000664 0001750 0001750 00000007745 14545562517 017224 0 ustar fabio fabio
[]
List of favorites, stored in display order, with the format of uri::mimetype
[]
List of gvfs metadata for the favorites:/// root (for remembering sort order in nemo, etc).
["onboard"]
A list of appindicator-based apps where left-click should trigger the 'secondary activation' action, rather than open the menu.
The name to be put here will be the icon's "Name" (not icon name). You can see what name to use by running xapp-sn-watcher from a terminal (or in .xsession-properties in some DEs).
["Cinnamon", "X-Cinnamon"]
List of desktops to run the XApp StatusNotifierWatcher service on..
The name in the session's XDG_CURRENT_DESKTOP environment variable is checked against this list. If the name is here, the service is started to allow XApp status applets to support the StatusNotifer spec (this includes appindicator).
false
Print debug messages for the xapp-sn-watcher service
"SnWatcher,StatusIcon"
Debug flags for sn-watcher debugging
["qbittorrent"]
Use the Title property in place of the Tooltip for programs with these IDs.
true
Whether to invite true StatusNotifierItem implementations to connect.
StatusNotifierItem implementations (like kde's) check for StatusNotifierWather::IsStatusNotifierHostRegistered to be true before attempting to connect with us. Appindicator implementations only look to see if StatusNotifierWatcher is owned on the bus. Setting IsStatusNotifierHostRegistered to false effectively disabled StatusNotifier support while still handling appindicator icons.
8
Pixels smaller than the panel height to make symbolic icons
8
Pixels smaller than the panel height to make color icons
'default'
Color scheme
The preferred color scheme for the user interface. Valid values are “default”, “prefer-dark”, “prefer-light”.
xapp-2.8.2/schemas/meson_install_schemas.py 0000664 0001750 0001750 00000000426 14545562517 020006 0 ustar fabio fabio #!/usr/bin/python3
import os
import subprocess
schemadir = os.path.join(os.environ['MESON_INSTALL_PREFIX'], 'share', 'glib-2.0', 'schemas')
if not os.environ.get('DESTDIR'):
print('Compiling gsettings schemas...')
subprocess.call(['glib-compile-schemas', schemadir])
xapp-2.8.2/test-scripts/ 0000775 0001750 0001750 00000000000 14545562517 014101 5 ustar fabio fabio xapp-2.8.2/test-scripts/xapp-icon-chooser-dialog 0000775 0001750 0001750 00000004006 14545562517 020622 0 ustar fabio fabio #!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('XApp', '1.0')
from gi.repository import Gtk, XApp, Gdk
import argparse
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
# if there are no arguments supplied, we should create a new launcher in the default location (usually ~/.local/share/applications/)
group.add_argument('-c', '--category', dest='category', metavar='CATEGORY',
help='The category to select when the dialog is opened.')
group.add_argument('-i', '--icon-string', dest='icon', metavar='ICON_STRING',
help='The icon to select when the dialog is opened. This can be an icon name or a path. '
'If the icon doesn\'t exist, it will not cause an error, but there may not be an icon '
'selected.')
parser.add_argument('-b', '--clipboard', dest='clipboard', action='store_true',
help='If this option is supplied, the result will be copied to the clipboard when an icon is '
'selected and the dialog closed.')
parser.add_argument('-p', '--disallow-paths', dest='paths', action='store_false',
help='causes the path.')
args = parser.parse_args()
dialog = XApp.IconChooserDialog(allow_paths=args.paths, default_icon='folder')
dialog.set_skip_taskbar_hint(False)
if args.category:
response = dialog.run_with_category(args.category)
elif args.icon:
response = dialog.run_with_icon(args.icon)
else:
response = dialog.run()
if response == Gtk.ResponseType.OK:
string = dialog.get_icon_string()
print(string)
if args.clipboard:
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clipboard.set_text(string, -1)
clipboard.store()
else:
print('Dialog canceled')
xapp-2.8.2/test-scripts/xapp-kbd-layout-controller 0000775 0001750 0001750 00000012735 14545562517 021241 0 ustar fabio fabio #! /usr/bin/python3
"""
A demo/test script for the XAppKbdLayoutController class
"""
import sys, os
import signal
import gettext
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('XApp', '1.0')
from gi.repository import Gtk, XApp, GObject
import cairo
signal.signal(signal.SIGINT, signal.SIG_DFL)
class Main:
def __init__(self):
win = Gtk.Window()
win.set_default_size(320, 200)
frame = Gtk.Frame()
frame.set_margin_start(2)
frame.set_margin_end(2)
frame.set_margin_top(2)
frame.set_margin_bottom(2)
win.add(frame)
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
box.set_margin_start(2)
box.set_margin_end(2)
box.set_margin_top(2)
box.set_margin_bottom(2)
frame.add(box)
self.use_caps = False
self.controller = XApp.KbdLayoutController()
self.controller.connect("layout-changed", self.on_layout_changed)
self.controller.connect("config-changed", self.on_config_changed)
self.label = Gtk.Label()
self.label.set_text(self.controller.get_current_name())
box.pack_start(self.label, True, True, 4)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
box.pack_start(hbox, True, True, 4)
self.flag_button = Gtk.Button()
hbox.pack_start(self.flag_button, True, True, 4)
self.flag_button.connect("clicked", self.on_button_clicked)
self.group_button = Gtk.Button()
hbox.pack_start(self.group_button, True, True, 4)
self.group_button.connect("clicked", self.on_button_clicked)
self.variant_button = Gtk.Button()
hbox.pack_start(self.variant_button, True, True, 4)
self.variant_button.connect("clicked", self.on_button_clicked)
check = Gtk.CheckButton.new_with_label("Use caps")
check.connect("toggled", self.on_caps_toggled)
box.pack_start(check, True, True, 4)
frame.show_all()
win.connect("delete-event", lambda w, e: Gtk.main_quit())
self.on_layout_changed(self.controller)
win.present()
Gtk.main()
def on_caps_toggled(self, widget):
self.use_caps = widget.get_active()
self.on_layout_changed(self.controller)
def on_button_clicked(self, widget, data=None):
self.controller.next_group()
def on_layout_changed(self, controller, group=None):
handled = False
name = self.controller.get_current_icon_name()
if name != None:
filename = "/usr/share/iso-flag-png/%s.png" % name
if os.path.exists(filename):
valid, width, height = Gtk.IconSize.lookup(Gtk.IconSize.LARGE_TOOLBAR)
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
flag_surface = cairo.ImageSurface.create_from_png(filename)
cr = cairo.Context(surface)
cr.save()
factor = width / flag_surface.get_width()
true_width = flag_surface.get_width() * factor
true_height = flag_surface.get_height() * factor
x_offset = y_offset = 0
if flag_surface.get_width() >= flag_surface.get_height():
x_offset = 0
y_offset = ((height * (1 / factor)) - flag_surface.get_height()) / 2
else:
x_offset = ((width * (1 / factor)) - flag_surface.get_width()) / 2
y_offset = 0
true_x_offset = (width - true_width) / 2;
true_y_offset = (height - true_height) / 2;
cr.scale(factor, factor);
cr.set_source_surface(flag_surface, x_offset, y_offset);
cr.get_source().set_filter(cairo.FILTER_BEST);
cr.set_operator(cairo.OPERATOR_SOURCE);
cr.paint();
cr.restore()
XApp.KbdLayoutController.render_cairo_subscript(cr,
true_x_offset + (true_width / 2),
true_y_offset + (true_height / 2),
true_width / 2,
true_height / 2,
self.controller.get_current_flag_id())
image = Gtk.Image.new_from_surface(cr.get_target())
self.flag_button.set_image(image)
handled = True
else:
print("Missing /usr/share/iso-flag-png flag image - text only")
if not handled:
name = self.controller.get_current_short_group_label()
if self.use_caps:
self.flag_button.set_label(name.upper())
else:
self.flag_button.set_label(name)
self.flag_button.set_image(None)
self.label.set_text(self.controller.get_current_name())
group_label = self.controller.get_current_short_group_label()
variant_label = self.controller.get_current_variant_label()
if self.use_caps:
group_label = group_label.upper()
variant_label = variant_label.upper()
self.group_button.set_label(group_label)
self.variant_button.set_label(variant_label)
def on_config_changed(self, controller):
GObject.idle_add(self.on_layout_changed, controller)
if __name__ == "__main__":
main = Main()
xapp-2.8.2/test-scripts/xapp-status-applet 0000775 0001750 0001750 00000015463 14545562517 017614 0 ustar fabio fabio #!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('XApp', '1.0')
from gi.repository import Gio, GLib, GObject, Gtk, XApp, Gdk
import os
import sys
import json
DBUS_NAME = "org.x.StatusIcon"
DBUS_PATH = "/org/x/StatusIcon"
class StatusWidget(Gtk.ToggleButton):
__gsignals__ = {
"re-sort": (GObject.SignalFlags.RUN_LAST, None, ())
}
def __init__(self, icon):
super(Gtk.ToggleButton, self).__init__()
self.proxy = icon
self.name = self.proxy.get_name()
self.add_events(Gdk.EventMask.SCROLL_MASK)
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.image = Gtk.Image()
self.label = Gtk.Label()
box.pack_start(self.image, False, False, 6)
box.add(self.label)
self.add(box)
flags = GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE
self.image.props.icon_size = Gtk.IconSize.DIALOG
self.set_icon(self.proxy.props.icon_name)
self.show_all()
self.proxy.bind_property("label", self.label, "label", flags)
self.proxy.bind_property("tooltip-text", self, "tooltip-markup", flags)
self.proxy.bind_property("visible", self, "visible", flags)
self.proxy.bind_property("primary-menu-is-open", self, "active", flags)
self.proxy.bind_property("secondary-menu-is-open", self, "active", flags)
self.proxy.connect("notify::icon-name", self.on_icon_name_changed)
self.proxy.connect("notify::name", self.on_name_changed)
self.connect("button-press-event", self.on_button_press)
self.connect("button-release-event", self.on_button_release)
self.connect("scroll-event", self.on_scroll)
def on_icon_name_changed(self, proxy, gparamspec, data=None):
string = self.proxy.props.icon_name
self.set_icon(string)
def on_name_changed(self, proxy, gparamspec, data=None):
self.emit("re-sort")
def set_icon(self, string):
if string:
if string and os.path.exists(string):
self.image.set_from_file(string)
else:
self.image.set_from_icon_name(string, Gtk.IconSize.DIALOG)
else:
self.image.set_from_icon_name("image-missing", Gtk.IconSize.DIALOG)
def on_button_press(self, widget, event):
# We're simulating a top panel here
alloc = widget.get_allocation()
ignore, x, y = widget.get_window().get_origin()
x += alloc.x
y += alloc.y + alloc.height
time = event.time
print ("Button press : %d:%d" % (x, y))
self.proxy.call_button_press_sync(x, y, event.button, event.time, Gtk.PositionType.TOP, None)
def on_button_release(self, widget, event):
# We're simulating a top panel here
alloc = widget.get_allocation()
ignore, x, y = widget.get_window().get_origin()
x += alloc.x
y += alloc.y + alloc.height
time = event.time
print ("Button release : %d:%d" % (x, y))
self.proxy.call_button_release_sync(x, y, event.button, event.time, Gtk.PositionType.TOP, None)
def on_scroll(self, widget, event):
has, direction = event.get_scroll_direction()
x_dir = XApp.ScrollDirection.UP
delta = 0
if direction != Gdk.ScrollDirection.SMOOTH:
x_dir = XApp.ScrollDirection(int(direction))
if direction == Gdk.ScrollDirection.UP:
delta = -1
elif direction == Gdk.ScrollDirection.DOWN:
delta = 1
elif direction == Gdk.ScrollDirection.LEFT:
delta = -1
elif direction == Gdk.ScrollDirection.RIGHT:
delta = 1
print ("Scroll : delta: %d, orientation: %d" % (delta, x_dir))
self.proxy.call_scroll_sync(delta, x_dir, event.time, None)
class StatusApplet(GObject.Object):
def __init__(self):
super(StatusApplet, self).__init__()
self.window = Gtk.Window()
self.window.set_accept_focus (False)
self.window.connect("destroy", self.on_window_destroy)
self.main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
margin=6,
spacing=6)
self.window.add(self.main_box)
self.disco_button = Gtk.Button()
self.main_box.pack_start(self.disco_button, False, False, 0)
self.disco_button.connect("clicked", self.on_disco_button_clicked)
self.indicator_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,
spacing=6)
self.main_box.pack_start(self.indicator_box, False, False, 0)
self.indicators = {}
self.monitor = None
self.setup_monitor()
self.window.show_all()
def on_window_destroy(self, widget, data=None):
self.destroy_monitor()
Gtk.main_quit()
def on_disco_button_clicked(self, widget, data=None):
if self.monitor == None:
self.setup_monitor ()
else:
self.destroy_monitor()
def setup_monitor (self):
self.monitor = XApp.StatusIconMonitor()
self.monitor.connect("icon-added", self.on_icon_added)
self.monitor.connect("icon-removed", self.on_icon_removed)
self.disco_button.set_label("Disconnect monitor")
def destroy_monitor (self):
for key in self.indicators.keys():
self.indicator_box.remove(self.indicators[key])
self.monitor = None
self.indicators = {}
self.disco_button.set_label("Connect monitor")
def on_icon_added(self, monitor, proxy):
name = proxy.get_name() + proxy.get_object_path()
self.indicators[name] = StatusWidget(proxy)
self.indicator_box.add(self.indicators[name])
self.indicators[name].connect("re-sort", self.sort_icons)
self.sort_icons()
def on_icon_removed(self, monitor, proxy):
name = proxy.get_name() + proxy.get_object_path()
self.indicator_box.remove(self.indicators[name])
self.indicators[name].disconnect_by_func(self.sort_icons)
del(self.indicators[name])
self.sort_icons()
def sort_icons(self, status_icon=None):
icon_list = list(self.indicators.values())
# for i in icon_list:
# print("before: ", i.proxy.props.icon_name, i.proxy.props.name.lower())
icon_list.sort(key=lambda icon: icon.proxy.props.name.replace("org.x.StatusIcon.", "").lower())
icon_list.sort(key=lambda icon: icon.proxy.props.icon_name.lower().endswith("symbolic"))
# for i in icon_list:
# print("after: ", i.proxy.props.icon_name, i.proxy.props.name.lower())
icon_list.reverse()
for icon in icon_list:
self.indicator_box.reorder_child(icon, 0)
if __name__ == '__main__':
applet = StatusApplet()
Gtk.main()
sys.exit(0) xapp-2.8.2/test-scripts/xapp-favorites 0000775 0001750 0001750 00000011667 14545562517 017012 0 ustar fabio fabio #!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('XApp', '1.0')
from gi.repository import Gio, GLib, GObject, Gtk, XApp, Pango
import sys
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
DBUS_NAME = "org.x.StatusIcon"
DBUS_PATH = "/org/x/StatusIcon"
class ListItem(Gtk.ListBoxRow):
def __init__(self, favinfo, mgr):
super(Gtk.ListBoxRow, self).__init__()
self.favinfo = favinfo
self.mgr = mgr
self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.add(self.box)
label = Gtk.Label(label=self.favinfo.display_name, xalign=0)
self.box.pack_start(label, False, False, 6)
delete = Gtk.Button.new_from_icon_name("edit-delete-symbolic", Gtk.IconSize.BUTTON)
delete.set_relief(Gtk.ReliefStyle.NONE)
self.box.pack_end(delete, False, False, 6)
delete.connect("clicked", self.on_delete_clicked)
self.show_all()
def on_delete_clicked(self, widget, data=None):
self.mgr.remove(self.favinfo.uri)
class FavoriteList(GObject.Object):
def __init__(self):
super(FavoriteList, self).__init__()
self.window = None
self.manager = XApp.Favorites.get_default()
self.manager.connect("changed", self.on_manager_changed)
self.window = Gtk.Window()
self.window.set_default_size(600, 400)
self.window.connect("destroy", self.on_window_destroy)
self.window_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.main_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,
margin=6,
spacing=0)
bar = Gtk.MenuBar()
menu_item = Gtk.MenuItem.new_with_label("Favorites")
favorites = self.manager.create_menu(None, self.favorite_menu_item_activated)
menu_item.set_submenu(favorites)
bar.append(menu_item)
self.window_box.pack_start(bar, False, False, 0)
self.window_box.pack_start(self.main_box, True, True, 0)
# list stuff
sw_frame = Gtk.Frame()
sw = Gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
sw_frame.add(sw)
self.list_box = Gtk.ListBox(activate_on_single_click=False)
self.list_box.connect("selected-rows-changed", self.on_selection_changed)
self.list_box.connect("row-activated", self.on_row_activated)
sw.add(self.list_box)
self.main_box.pack_start(sw_frame, True, True, 6)
self.window.add(self.window_box)
# controls
control_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.add_button = Gtk.Button.new_from_icon_name("list-add-symbolic", Gtk.IconSize.BUTTON)
self.add_button.connect("clicked", self.on_add_clicked)
control_box.pack_start(self.add_button, False, False, 6)
self.main_box.pack_start(control_box, False, False, 6)
self.window.show_all()
self.selected_uri = None
self.loading = False
self.load_favorites()
def favorite_menu_item_activated(self, manager, uri, data=None):
print("activated", uri)
self.manager.launch(uri, Gtk.get_current_event_time())
def load_favorites(self):
self.loading = True # this will preserve the last selection
for child in self.list_box.get_children():
self.list_box.remove(child)
previously_selected = None
favorites = self.manager.get_favorites(None)
for info in favorites:
row = ListItem(info, self.manager)
self.list_box.insert(row, -1)
if self.selected_uri == info.uri:
previously_selected = row
self.loading = False
if previously_selected:
self.list_box.select_row(previously_selected)
def on_row_activated(self, box, row, data=None):
self.manager.launch(row.favinfo.uri, Gtk.get_current_event_time())
def on_selection_changed(self, box, data=None):
if self.loading:
return
row = self.list_box.get_selected_row()
if row:
self.selected_uri = row.favinfo.uri
else:
self.selected_uri = None
def on_add_clicked(self, widget, data=None):
dialog = Gtk.FileChooserDialog(title="Add file to favorites",
parent=self.window,
action=Gtk.FileChooserAction.OPEN)
dialog.add_buttons("Add", Gtk.ResponseType.OK,
"Cancel", Gtk.ResponseType.CANCEL)
# dialog.add_shortcut_folder_uri ("favorites:///")
res = dialog.run()
if res == Gtk.ResponseType.OK:
uri = dialog.get_uri()
self.manager.add(uri)
dialog.destroy()
def on_manager_changed(self, manager, data=None):
self.load_favorites()
def on_window_destroy(self, widget, data=None):
Gtk.main_quit()
if __name__ == '__main__':
test = FavoriteList()
Gtk.main()
xapp-2.8.2/test-scripts/xapp-gtk-window 0000775 0001750 0001750 00000010675 14545562517 017100 0 ustar fabio fabio #! /usr/bin/python3
"""
A demo/test script for the XAppAppGtkWindow class
"""
import sys, os
import signal
import gettext
import time
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('XApp', '1.0')
from gi.repository import GLib, Gtk, XApp, GObject
signal.signal(signal.SIGINT, signal.SIG_DFL)
class Main:
def __init__(self):
self.win = XApp.GtkWindow()
self._animate_progress = 0
self.win.set_default_size(320, 200)
frame = Gtk.Frame()
frame.set_margin_start(2)
frame.set_margin_end(2)
frame.set_margin_top(2)
frame.set_margin_bottom(2)
self.win.add(frame)
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
box.set_margin_start(2)
box.set_margin_end(2)
box.set_margin_top(2)
box.set_margin_bottom(2)
frame.add(box)
heading = Gtk.Label()
heading.set_markup("Use 'xprop -spy' to monitor changes")
box.pack_start(heading, True, True, 4)
hbox = Gtk.HBox()
self.icon_name_entry = Gtk.Entry()
self.icon_name_setter = Gtk.Button("Set icon name")
self.icon_name_setter.connect("clicked", self.on_icon_name_setter_clicked)
hbox.pack_start(self.icon_name_entry, True, True, 4)
hbox.pack_start(self.icon_name_setter, False, False, 4)
box.pack_start(hbox, True, True, 4)
hbox = Gtk.HBox()
self.icon_path_entry = Gtk.Entry()
self.icon_path_setter = Gtk.Button("Set icon path")
self.icon_path_setter.connect("clicked", self.on_icon_path_setter_clicked)
hbox.pack_start(self.icon_path_entry, True, True, 4)
hbox.pack_start(self.icon_path_setter, False, False, 4)
box.pack_start(hbox, True, True, 4)
hbox = Gtk.HBox()
self.progress_label = Gtk.Label("Progress:")
self.progress = Gtk.Scale()
self.progress.connect("value-changed", self.on_progress_value_changed)
self.progress.set_draw_value(True)
self.progress.set_digits(0)
self.progress.set_range(0, 100)
hbox.pack_start(self.progress_label, False, False, 4)
hbox.pack_start(self.progress, True, True, 4)
box.pack_start(hbox, True, True, 4)
hbox = Gtk.HBox()
self.pulse_label = Gtk.Label("Progress pulse:")
self.pulse_switch = Gtk.Switch()
self.pulse_switch.set_halign(Gtk.Align.CENTER)
self.pulse_switch.connect("notify::active", self.on_pulse_switch_changed)
hbox.pack_start(self.pulse_label, False, False, 4)
hbox.pack_start(self.pulse_switch, True, True, 4)
box.pack_start(hbox, True, True, 4)
hbox = Gtk.HBox()
self.animate_button = Gtk.Button("Simulate progress over time")
self.animate_button.connect("clicked", self.on_animate_progress_clicked)
hbox.pack_start(self.animate_button, True, True, 4)
box.pack_start(hbox, True, True, 4)
frame.show_all()
self.win.connect("delete-event", lambda w, e: Gtk.main_quit())
self.win.present()
Gtk.main()
def on_animate_progress_clicked(self, button, data=None):
self.progress.set_sensitive(False)
self.pulse_switch.set_sensitive(False)
self._animate_progress = 0
self.win.set_progress(0)
GObject.timeout_add(500, self.on_progress_tick)
def on_progress_tick(self):
self.win.set_progress(self._animate_progress)
if self._animate_progress == 100:
self.on_animate_complete()
return False
else:
self._animate_progress += 1
return True
def on_animate_complete(self):
self.progress.set_sensitive(True)
self.pulse_switch.set_sensitive(True)
self.progress.set_value(100)
def on_icon_name_setter_clicked(self, button, data=None):
self.win.set_icon_name(self.icon_name_entry.get_text())
def on_icon_path_setter_clicked(self, button, data=None):
try:
self.win.set_icon_from_file(self.icon_path_entry.get_text())
except GLib.Error as e:
print(e.message)
def on_progress_value_changed(self, range, data=None):
self.win.set_progress(int(self.progress.get_value()))
self.pulse_switch.set_active(False)
def on_pulse_switch_changed(self, switch, pspec, data=None):
self.win.set_progress_pulse(self.pulse_switch.get_active())
if __name__ == "__main__":
main = Main()
xapp-2.8.2/test-scripts/xapp-status-icon-variants/ 0000775 0001750 0001750 00000000000 14545562517 021145 5 ustar fabio fabio xapp-2.8.2/test-scripts/xapp-status-icon-variants/dialog-error.png 0000664 0001750 0001750 00000001151 14545562517 024237 0 ustar fabio fabio PNG
IHDR w= sBIT|d pHYs
B(x tEXtSoftware www.inkscape.org< IDATHŕka?ϛ6ЦvrR CRMKAH<2t`/E)NiF C.`c+~yUl
N%YAa/=8I|J?UԐM6SodkPAsmZ!Ө %UZY Q+FR5MG&Ikvq>䀠z>7&IIwZL .]ln ' gEVAp TFz+n(7p}Wp7z981EqG T]aAF=O X'*~$cH0],~X
j }1+yGF%obX; Ip-|JX[*1?[*\}%Ptn]<}ug3Ωh2R¾ v/
Şw IENDB` xapp-2.8.2/test-scripts/xapp-status-icon-variants/xapp-status-icon-ai 0000775 0001750 0001750 00000006201 14545562517 024700 0 ustar fabio fabio #!/usr/bin/python3
import gi
gi.require_version('AppIndicator3', '0.1')
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, AppIndicator3
from gi.repository import GLib, GObject
import sys
"""
This variant tests behavior of a program using mint-patched AppIndicator, which will fall
back to XAppStatusIcon if there is no AppIndicator support in the desktop environment.
AppIndicator expects both left- and right-click to display the menu, so internally, AppIndicator
sets both primary and secondary menus on the XAppStatusIcon.
"""
class App(GObject.Object):
def __init__(self):
super(App, self).__init__()
self.window = None
self.indicator = AppIndicator3.Indicator.new("xapp-status-icon-via-libappindicator",
"info",
AppIndicator3.IndicatorCategory.SYSTEM_SERVICES)
self.indicator.set_icon_full("info", "Everything is fine.")
self.indicator.set_label("AppIndicator3 1", "AppIndicator3 1000")
self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
self.indicator.set_title("Testing patched appindicator fallback to XApp.StatusIcon")
self.counter = 1
self.menu = Gtk.Menu()
secondary_activation_item = Gtk.MenuItem.new_with_label("Activate target (middle click)")
secondary_activation_item.connect("activate", self.activate_window)
self.indicator.set_secondary_activate_target(secondary_activation_item)
self.menu.append(secondary_activation_item)
self.menu.append(Gtk.MenuItem.new_with_label("Engage the hyperdrive"))
self.menu.append(Gtk.SeparatorMenuItem())
self.menu.append(Gtk.MenuItem.new_with_label("It's a trap!"))
self.menu.show_all()
self.indicator.set_menu(self.menu)
self.indicator.connect("scroll-event", self.handle_scroll_event)
GLib.timeout_add_seconds(2, self.on_timeout_cb)
def activate_window(self, item, data=None):
w = Gtk.Window(default_width=300, default_height=130)
b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
w.add(b)
self.label = Gtk.Label("How can I help you?")
b.pack_start(self.label, True, True, 0)
self.window = w
w.show_all()
def handle_scroll_event(self, icon, amount, direction, data=None):
if self.window == None:
self.activate_window(None)
if direction == Gdk.ScrollDirection.UP:
self.label.set_text("Scrolled Up!")
elif direction == Gdk.ScrollDirection.DOWN:
self.label.set_text("Scrolled Down!")
elif direction == Gdk.ScrollDirection.LEFT:
self.label.set_text("Scrolled Left!")
else:
self.label.set_text("Scrolled Right!")
def on_timeout_cb(self):
self.counter += 1
self.indicator.set_label("AppIndicator3 %d" % self.counter, "AppIndicator3 1000")
return True
if __name__ == '__main__':
GLib.setenv ("G_MESSAGES_DEBUG", "all", True)
app = App()
try:
GLib.MainLoop().run()
except KeyboardInterrupt:
pass
sys.exit(0)
xapp-2.8.2/test-scripts/xapp-status-icon-variants/dialog-warning.png 0000664 0001750 0001750 00000001646 14545562517 024564 0 ustar fabio fabio PNG
IHDR w= sBIT|d pHYs
B(x tEXtSoftware www.inkscape.org< #IDATHՔOQƿ;3w3}L)JjJVLA
b#jcB/411иӥ;ݸѕ1ƸM|-0Q#Fhg\hXG
,9>[iaʙ%6&~L _(=бl 3Vȉ۷QKTTnY(R[+yD .dTIp, X-T)jA{Pi7zTay@U|.H)X]dy8;Fy$kj`҂5]c06Уgσr+t^ (ږPպ% M4
ܷEe{0mހO{4`_d u,9/@:X#J@4Q<!Ml2<Y1'YH3nKA8hݹ"@Jj|DŲ,2i"F`
uNEU B~ 6Y BAG~7YY"xM\UnR@* dDDޟ@o .K4Ja}M[Eko\.#iG5ςek/~0'.9ޖT{x=~ qClf(0%z
<쳙 }ǥpkdM֙%&yt v;n?xj<8/HI7(g\k5Sl6Aµ^<j\j*F
:t4뚎Bqz@^9:s78
zĕ_~B IENDB` xapp-2.8.2/test-scripts/xapp-status-icon-variants/xapp-status-icon-all-menus 0000775 0001750 0001750 00000005567 14545562517 026222 0 ustar fabio fabio #!/usr/bin/python3
import gi
gi.require_version('XApp', '1.0')
from gi.repository import XApp, Gtk, Gdk
from gi.repository import GLib, GObject
import sys
"""
This variant tests behavior of giving primary and secondary menus to the StatusIcon instance.
The instance handles all menu-related things internally. There is no activation signal.
"""
class App(GObject.Object):
def __init__(self):
super(App, self).__init__()
self.status_icon = XApp.StatusIcon()
self.status_icon.connect("state-changed", self.on_icon_state_changed)
self.status_icon.set_icon_name("folder-symbolic")
self.status_icon.set_tooltip_text("Testing primary and secondary menus")
self.status_icon.set_label("label 1")
self.status_icon.set_visible(True)
self.status_icon.set_metadata(' { "highlight-both-menus": true } ')
self.status_icon.connect("scroll-event", self.handle_scroll_event)
self.counter = 1
self.label = None
self.window = None
menu = Gtk.Menu()
menu.append(Gtk.MenuItem.new_with_label("Engage the hyperdrive"))
menu.append(Gtk.SeparatorMenuItem())
menu.append(Gtk.MenuItem.new_with_label("It's a trap!"))
menu.show_all()
self.status_icon.set_primary_menu(menu)
menu = Gtk.Menu()
menu.append(Gtk.MenuItem.new_with_label("Hi, secondary menu here!"))
menu.append(Gtk.SeparatorMenuItem())
menu.append(Gtk.MenuItem.new_with_label("Help me!"))
menu.show_all()
self.status_icon.set_secondary_menu(menu)
GLib.timeout_add_seconds(2, self.on_timeout_cb)
def on_icon_state_changed(self, icon, new_state):
print("Icon state changed - the state is now: %s" % new_state)
def on_timeout_cb(self):
self.counter += 1
self.status_icon.set_label("label %d" % self.counter)
return True
def make_window(self):
w = Gtk.Window(default_width=300, default_height=130)
b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
w.add(b)
self.label = Gtk.Label("How can I help you?")
b.pack_start(self.label, True, True, 0)
self.window = w
w.show_all()
def handle_scroll_event(self, icon, amount, orientation, time, data=None):
if self.window == None:
self.make_window()
if orientation == XApp.ScrollDirection.UP:
self.label.set_text("Scrolled Up !")
elif orientation == XApp.ScrollDirection.DOWN:
self.label.set_text("Scrolled Down!")
elif orientation == XApp.ScrollDirection.LEFT:
self.label.set_text("Scrolled Left!")
else:
self.label.set_text("Scrolled Right!")
if __name__ == '__main__':
GLib.setenv ("G_MESSAGES_DEBUG", "all", True)
app = App()
try:
GLib.MainLoop().run()
except KeyboardInterrupt:
pass
sys.exit(0)
xapp-2.8.2/test-scripts/xapp-status-icon-variants/xapp-status-icon-raw-events 0000775 0001750 0001750 00000005227 14545562517 026411 0 ustar fabio fabio #!/usr/bin/python3
import gi
gi.require_version('XApp', '1.0')
from gi.repository import XApp, Gtk, Gdk
from gi.repository import GLib, GObject
import sys
"""
This variant tests button-press-event and button-release-event with no menus assigned -
it must do all menu handling itself.
"""
class App(GObject.Object):
def __init__(self):
super(App, self).__init__()
self.status_icon = XApp.StatusIcon()
self.status_icon.connect("state-changed", self.on_icon_state_changed)
self.status_icon.set_icon_name("folder-symbolic")
self.status_icon.set_tooltip_text("Testing raw button press and release events")
self.status_icon.set_label("label 1")
self.status_icon.set_visible(True)
self.counter = 1
self.menu = Gtk.Menu()
self.menu.append(Gtk.MenuItem.new_with_label("Engage the hyperdrive"))
self.menu.append(Gtk.SeparatorMenuItem())
self.menu.append(Gtk.MenuItem.new_with_label("It's a trap!"))
self.menu.show_all()
self.status_icon.connect("button-press-event", self.on_button_press)
self.status_icon.connect("button-release-event", self.on_button_release)
GLib.timeout_add_seconds(2, self.on_timeout_cb)
def on_icon_state_changed(self, icon, new_state):
print("Icon state changed - the state is now: %s" % new_state)
def on_timeout_cb(self):
self.counter += 1
self.status_icon.set_label("label %d" % self.counter)
return True
def on_button_press(self, status_icon, x, y, button, time, position_type):
print("Mouse button %d was pressed at %d %d" % (button, x, y))
self.counter = 0
self.status_icon.set_label("label %d" % self.counter)
def on_button_release(self, status_icon, x, y, button, time, position_type):
print("Mouse button %d was released at %d %d" % (button, x, y))
if button == 3:
def position_menu_cb(menu, pointer_x, pointer_y, user_data):
[x, y, position] = user_data;
if (position_type == Gtk.PositionType.BOTTOM):
y = y - menu.get_allocation().height;
if (position_type == Gtk.PositionType.RIGHT):
x = x - menu.get_allocation().width;
return (x, y, False)
device = Gdk.Display.get_default().get_device_manager().get_client_pointer()
self.menu.popup_for_device(device, None, None, position_menu_cb, [x, y, position_type], button, 0)
if __name__ == '__main__':
GLib.setenv ("G_MESSAGES_DEBUG", "all", True)
app = App()
try:
GLib.MainLoop().run()
except KeyboardInterrupt:
pass
sys.exit(0)
xapp-2.8.2/test-scripts/xapp-status-icon-variants/xapp-status-icon-no-menus 0000775 0001750 0001750 00000005002 14545562517 026046 0 ustar fabio fabio #!/usr/bin/python3
import gi
gi.require_version('XApp', '1.0')
from gi.repository import XApp, Gtk, Gdk
from gi.repository import GLib, GObject
import sys
"""
This variant tests behavior of providing no menus to the StatusIcon instance.
This results in 'activate' signals being sent for all button presses.
"""
class App(GObject.Object):
def __init__(self):
super(App, self).__init__()
self.status_icon = XApp.StatusIcon()
self.status_icon.connect("state-changed", self.on_icon_state_changed)
self.status_icon.set_icon_name("folder-symbolic")
self.status_icon.set_tooltip_text("Testing primary activate and secondary menu")
self.status_icon.set_label("label 1")
self.status_icon.set_visible(True)
self.label = None
self.window = None
self.counter = 1
self.status_icon.connect("activate", self.on_status_icon_activate)
self.status_icon.connect("scroll-event", self.handle_scroll_event)
GLib.timeout_add_seconds(2, self.on_timeout_cb)
def on_icon_state_changed(self, icon, new_state):
print("Icon state changed - the state is now: %s" % new_state)
def on_timeout_cb(self):
self.counter += 1
self.status_icon.set_label("label %d" % self.counter)
return True
def on_status_icon_activate(self, icon, button, time):
print("Activated via button %d" % button)
self.counter = 0
self.status_icon.set_label("label %d" % self.counter)
self.make_window()
def make_window(self):
w = Gtk.Window(default_width=300, default_height=130)
b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
w.add(b)
self.label = Gtk.Label("How can I help you?")
b.pack_start(self.label, True, True, 0)
self.window = w
w.show_all()
def handle_scroll_event(self, icon, amount, orientation, time, data=None):
if self.window == None:
self.make_window()
if orientation == XApp.ScrollDirection.UP:
self.label.set_text("Scrolled Up !")
elif orientation == XApp.ScrollDirection.DOWN:
self.label.set_text("Scrolled Down!")
elif orientation == XApp.ScrollDirection.LEFT:
self.label.set_text("Scrolled Left!")
else:
self.label.set_text("Scrolled Right!")
if __name__ == '__main__':
GLib.setenv ("G_MESSAGES_DEBUG", "all", True)
app = App()
try:
GLib.MainLoop().run()
except KeyboardInterrupt:
pass
sys.exit(0)
xapp-2.8.2/test-scripts/xapp-status-icon-variants/xapp-status-icon-activate-and-menu 0000775 0001750 0001750 00000005454 14545562517 027622 0 ustar fabio fabio #!/usr/bin/python3
import gi
gi.require_version('XApp', '1.0')
from gi.repository import XApp, Gtk, Gdk
from gi.repository import GLib, GObject
import sys
"""
This variant tests behavior of giving a only a secondary menu to the StatusIcon instance.
This results in 'activate' signals being sent for primary clicks only.
"""
class App(GObject.Object):
def __init__(self):
super(App, self).__init__()
self.status_icon = XApp.StatusIcon()
self.status_icon.connect("state-changed", self.on_icon_state_changed)
self.status_icon.set_icon_name("folder-symbolic")
self.status_icon.set_tooltip_text("Testing primary activate and secondary menu")
self.status_icon.set_label("label 1")
self.status_icon.set_visible(True)
self.status_icon.connect("scroll-event", self.handle_scroll_event)
self.label = None
self.window = None
self.counter = 1
menu = Gtk.Menu()
menu.append(Gtk.MenuItem.new_with_label("Hi, secondary menu here!"))
menu.append(Gtk.SeparatorMenuItem())
menu.append(Gtk.MenuItem.new_with_label("Help me!"))
menu.show_all()
self.status_icon.set_secondary_menu(menu)
self.status_icon.connect("activate", self.on_status_icon_activate)
GLib.timeout_add_seconds(2, self.on_timeout_cb)
def on_icon_state_changed(self, icon, new_state):
print("Icon state changed - the state is now: %s" % new_state)
def on_timeout_cb(self):
self.counter += 1
self.status_icon.set_label("label %d" % self.counter)
return True
def on_status_icon_activate(self, icon, button, time):
print("Activated via button %d" % button)
self.counter = 0
self.status_icon.set_label("label %d" % self.counter)
self.make_window()
def make_window(self):
w = Gtk.Window(default_width=300, default_height=130)
b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
w.add(b)
self.label = Gtk.Label("How can I help you?")
b.pack_start(self.label, True, True, 0)
self.window = w
w.show_all()
def handle_scroll_event(self, icon, amount, orientation, time, data=None):
if self.window == None:
self.make_window()
if orientation == XApp.ScrollDirection.UP:
self.label.set_text("Scrolled Up !")
elif orientation == XApp.ScrollDirection.DOWN:
self.label.set_text("Scrolled Down!")
elif orientation == XApp.ScrollDirection.LEFT:
self.label.set_text("Scrolled Left!")
else:
self.label.set_text("Scrolled Right!")
if __name__ == '__main__':
GLib.setenv ("G_MESSAGES_DEBUG", "all", True)
app = App()
try:
GLib.MainLoop().run()
except KeyboardInterrupt:
pass
sys.exit(0)
xapp-2.8.2/test-scripts/xapp-status-icon-variants/xapp-status-icon-activate-and-menu-popup 0000775 0001750 0001750 00000006473 14545562517 030765 0 ustar fabio fabio #!/usr/bin/python3
import gi
gi.require_version('XApp', '1.0')
from gi.repository import XApp, Gtk, Gdk
from gi.repository import GLib, GObject
import sys
"""
This variant tests behavior of giving a only a secondary menu to the StatusIcon instance.
This results in 'activate' signals being sent for primary clicks only.
"""
class App(GObject.Object):
def __init__(self):
super(App, self).__init__()
self.status_icon = XApp.StatusIcon()
self.status_icon.connect("state-changed", self.on_icon_state_changed)
self.status_icon.set_icon_name("folder-symbolic")
self.status_icon.set_tooltip_text("Testing primary activate and secondary menu")
self.status_icon.set_label("label 1")
self.status_icon.set_visible(True)
self.status_icon.connect("scroll-event", self.handle_scroll_event)
self.label = None
self.window = None
self.counter = 1
self.menu = Gtk.Menu()
self.menu.append(Gtk.MenuItem.new_with_label("Hi, secondary menu here!"))
self.menu.append(Gtk.SeparatorMenuItem())
self.menu.append(Gtk.MenuItem.new_with_label("Help me!"))
self.menu.show_all()
self.status_icon.connect("activate", self.on_status_icon_activate)
self.status_icon.connect("button-release-event", self.on_status_icon_button_release)
GLib.timeout_add_seconds(2, self.on_timeout_cb)
def on_icon_state_changed(self, icon, new_state):
print("Icon state changed - the state is now: %s" % new_state)
def on_timeout_cb(self):
self.counter += 1
self.status_icon.set_label("label %d" % self.counter)
return True
def on_status_icon_activate(self, icon, button, time):
print("Activated via button %d" % button)
if button not in (Gdk.BUTTON_PRIMARY, Gdk.BUTTON_MIDDLE):
return
self.counter = 0
self.status_icon.set_label("label %d" % self.counter)
self.make_window()
def make_window(self):
w = Gtk.Window(default_width=300, default_height=130)
b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
w.add(b)
self.label = Gtk.Label("How can I help you?")
b.pack_start(self.label, True, True, 0)
self.window = w
w.show_all()
def on_status_icon_button_release(self, icon, x, y, button, time, position, data=None):
if button in (Gdk.BUTTON_PRIMARY, Gdk.BUTTON_MIDDLE):
return
self.menu.append(Gtk.MenuItem.new_with_label("Added new menu %d" % self.counter))
self.menu.show_all()
self.status_icon.popup_menu(self.menu, x, y, button, time, position)
def handle_scroll_event(self, icon, amount, orientation, time, data=None):
if self.window == None:
self.make_window()
if orientation == XApp.ScrollDirection.UP:
self.label.set_text("Scrolled Up !")
elif orientation == XApp.ScrollDirection.DOWN:
self.label.set_text("Scrolled Down!")
elif orientation == XApp.ScrollDirection.LEFT:
self.label.set_text("Scrolled Left!")
else:
self.label.set_text("Scrolled Right!")
if __name__ == '__main__':
GLib.setenv ("G_MESSAGES_DEBUG", "all", True)
app = App()
try:
GLib.MainLoop().run()
except KeyboardInterrupt:
pass
sys.exit(0)
xapp-2.8.2/test-scripts/xapp-status-icon-variants/qt-system-tray.py 0000775 0001750 0001750 00000004247 14545562517 024454 0 ustar fabio fabio #!/usr/bin/env python3
# install python3-pyside2.qtgui, .qtwidgets
from PySide2.QtWidgets import QApplication, QSystemTrayIcon, QMenu, QAction
from PySide2.QtGui import QIcon, QPixmap
class App(QApplication):
def __init__(self):
super(App, self).__init__([])
self.icon_type = "theme"
self.tic_toc = False
self.setQuitOnLastWindowClosed(False)
self.tray = QSystemTrayIcon()
self.tray.setIcon(QIcon.fromTheme("dialog-warning"))
self.tray.setVisible(True)
self.menu = QMenu()
entry = "Use icon name"
action = QAction(entry)
action.triggered.connect(self.use_icon_theme)
self.menu.addAction(action)
entry = "Use icon file"
action2 = QAction(entry)
action2.triggered.connect(self.use_icon_file)
self.menu.addAction(action2)
entry = "Use icon pixels"
action3 = QAction(entry)
action3.triggered.connect(self.use_icon_pixels)
self.menu.addAction(action3)
entry = "Quit"
action4 = QAction(entry)
action4.triggered.connect(self.quit)
self.menu.addAction(action4)
self.tray.setContextMenu(self.menu)
self.tray.activated.connect(self.icon_activated)
self.exec_()
def use_icon_theme(self, item):
self.icon_type = "theme"
def use_icon_file(self, item):
self.icon_type = "file"
def use_icon_pixels(self, item):
self.icon_type = "pixels"
def icon_activated(self, reason):
if self.icon_type == "theme":
icon = QIcon.fromTheme("dialog-warning" if self.tic_toc else "dialog-error")
self.tray.setIcon(icon)
self.tic_toc = not self.tic_toc
elif self.icon_type == "file":
icon = QIcon("./dialog-warning.png" if self.tic_toc else "./dialog-error.png")
self.tray.setIcon(icon)
self.tic_toc = not self.tic_toc
else:
pixmap = QPixmap("./dialog-warning.png" if self.tic_toc else "./dialog-error.png")
icon = QIcon(pixmap)
self.tray.setIcon(icon)
self.tic_toc = not self.tic_toc
if __name__ == '__main__':
app = App()
xapp-2.8.2/test-scripts/xapp-gpu-offload-helper 0000775 0001750 0001750 00000002201 14545562517 020450 0 ustar fabio fabio #! /usr/bin/python3
"""
A demo/test script for the XAppAppGtkWindow class
"""
import sys, os
import signal
import gi
gi.require_version('XApp', '1.0')
from gi.repository import GLib, Gio, XApp, GObject
signal.signal(signal.SIGINT, signal.SIG_DFL)
class Main:
def __init__(self):
if len(sys.argv) > 1 and sys.argv[1] == "sync":
self.helper = XApp.GpuOffloadHelper.get_sync()
self.on_helper_ready(self.helper, self.helper.is_ready())
else:
self.helper = XApp.GpuOffloadHelper.get()
self.helper.connect("ready", self.on_helper_ready)
def on_helper_ready(self, helper, success):
print("Success:", success);
print("Number of GPUS:", helper.get_n_gpus())
info = helper.get_default_info()
print("%d - %s -- '%s'" % (info.id, info.display_name, info.get_shell_env_prefix()))
for info in helper.get_offload_infos():
print("%d - %s -- '%s'" % (info.id, info.display_name, info.get_shell_env_prefix()))
if __name__ == "__main__":
main = Main()
if len(sys.argv) == 1:
GLib.MainLoop.new(None, True).run()
exit(0)
xapp-2.8.2/debian/ 0000775 0001750 0001750 00000000000 14545562517 012657 5 ustar fabio fabio xapp-2.8.2/meson.build 0000664 0001750 0001750 00000002772 14545562517 013607 0 ustar fabio fabio project('xapp',
'c',
version : '2.8.2',
default_options : [ 'buildtype=debugoptimized' ],
meson_version : '>=0.56.0'
)
gnome = import('gnome')
pkg = import('pkgconfig')
i18n = import('i18n')
dbus_services_dir = dependency('dbus-1').get_variable(pkgconfig: 'session_bus_services_dir',
pkgconfig_define: ['datadir', get_option('datadir')])
sn_watcher_dir = join_paths(get_option('prefix'), get_option('libdir'), 'xapps')
cdata = configuration_data()
cdata.set_quoted('GETTEXT_PACKAGE', 'xapp')
cdata.set_quoted('XAPP_SN_WATCHER_PATH', join_paths([sn_watcher_dir, 'xapp-sn-watcher']))
cdata.set('ENABLE_DEBUG', get_option('buildtype') in ['debug', 'debugoptimized'])
add_global_arguments([
'-Wunused',
'-Wimplicit-function-declaration'
],
language: 'c'
)
if not get_option('deprecated_warnings')
add_global_arguments([
'-Wno-deprecated-declarations',
'-Wno-deprecated',
'-Wno-declaration-after-statement',
],
language: 'c',
)
endif
app_lib_only = get_option('app-lib-only')
c = configure_file(output : 'config.h',
configuration : cdata
)
top_inc = include_directories('.')
subdir('libxapp')
subdir('po')
subdir('schemas')
subdir('pygobject')
if not app_lib_only
subdir('icons')
subdir('status-applets')
subdir('scripts')
subdir('data')
endif
if get_option('status-notifier') and not app_lib_only
subdir('xapp-sn-watcher')
endif
if get_option('docs')
subdir('docs')
endif
xapp-2.8.2/icons/ 0000775 0001750 0001750 00000000000 14545562517 012550 5 ustar fabio fabio xapp-2.8.2/icons/meson.build 0000664 0001750 0001750 00000000157 14545562517 014715 0 ustar fabio fabio install_subdir('hicolor',
install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'icons'),
)
xapp-2.8.2/icons/hicolor/ 0000775 0001750 0001750 00000000000 14545562517 014207 5 ustar fabio fabio xapp-2.8.2/icons/hicolor/scalable/ 0000775 0001750 0001750 00000000000 14545562517 015755 5 ustar fabio fabio xapp-2.8.2/icons/hicolor/scalable/places/ 0000775 0001750 0001750 00000000000 14545562517 017224 5 ustar fabio fabio xapp-2.8.2/icons/hicolor/scalable/places/xapp-user-favorites-symbolic.svg 0000664 0001750 0001750 00000004774 14545562517 025524 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/places/xapp-user-favorites.svg 0000664 0001750 0001750 00000005456 14545562517 023703 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/emblems/ 0000775 0001750 0001750 00000000000 14545562517 017401 5 ustar fabio fabio xapp-2.8.2/icons/hicolor/scalable/emblems/emblem-xapp-favorite.svg 0000664 0001750 0001750 00000004237 14545562517 024154 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/ 0000775 0001750 0001750 00000000000 14545562517 017415 5 ustar fabio fabio xapp-2.8.2/icons/hicolor/scalable/actions/xapp-favorite-symbolic.svg 0000664 0001750 0001750 00000007003 14545562517 024542 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-search-wrap-symbolic.svg 0000664 0001750 0001750 00000005063 14545562517 025143 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/view-right-pane-symbolic-rtl.svg 0000664 0001750 0001750 00000011314 14545562517 025562 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/view-right-pane-symbolic.svg 0000664 0001750 0001750 00000011333 14545562517 024764 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-annotations-text-symbolic.svg 0000664 0001750 0001750 00000002416 14545562517 026245 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-edit-symbolic.svg 0000664 0001750 0001750 00000006204 14545562517 023652 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-diaporama-symbolic.svg 0000664 0001750 0001750 00000005034 14545562517 024662 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/view-bottom-pane-symbolic.svg 0000664 0001750 0001750 00000011220 14545562517 025146 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-unfavorite-symbolic.svg 0000664 0001750 0001750 00000005757 14545562517 025123 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/view-left-pane-symbolic.svg 0000664 0001750 0001750 00000011314 14545562517 024600 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-view-fit-height-symbolic.svg 0000664 0001750 0001750 00000006260 14545562517 025727 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-annotations-squiggly-symbolic.svg 0000664 0001750 0001750 00000006173 14545562517 027131 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-search-entire-word-symbolic.svg 0000664 0001750 0001750 00000011415 14545562517 026427 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-go-history-previous-symbolic.svg 0000664 0001750 0001750 00000013542 14545562517 026706 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-text-case-symbolic.svg 0000664 0001750 0001750 00000010413 14545562517 024617 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/view-left-pane-symbolic-rtl.svg 0000664 0001750 0001750 00000011336 14545562517 025403 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-view-fit-width-symbolic.svg 0000664 0001750 0001750 00000006747 14545562517 025610 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/extract-archive-symbolic.svg 0000664 0001750 0001750 00000006442 14545562517 025054 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-use-regex-symbolic.svg 0000664 0001750 0001750 00000006334 14545562517 024635 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-go-history-next-symbolic.svg 0000664 0001750 0001750 00000013542 14545562517 026010 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/media-mount-symbolic.svg 0000664 0001750 0001750 00000007452 14545562517 024204 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-go-history-previous-symbolic-rtl.svg 0000664 0001750 0001750 00000013542 14545562517 027505 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/category-search-symbolic.svg 0000664 0001750 0001750 00000010353 14545562517 025037 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-pin-symbolic.svg 0000664 0001750 0001750 00000004652 14545562517 023520 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-unpin-symbolic.svg 0000664 0001750 0001750 00000004635 14545562517 024064 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/view-top-pane-symbolic.svg 0000664 0001750 0001750 00000011256 14545562517 024455 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-go-history-next-symbolic-rtl.svg 0000664 0001750 0001750 00000013542 14545562517 026607 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/add-files-to-archive-symbolic.svg 0000664 0001750 0001750 00000014400 14545562517 025643 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/actions/xapp-format-text-highlight-symbolic.svg 0000664 0001750 0001750 00000016350 14545562517 027147 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/apps/ 0000775 0001750 0001750 00000000000 14545562517 016720 5 ustar fabio fabio xapp-2.8.2/icons/hicolor/scalable/apps/xapp-favorites-app-symbolic.svg 0000664 0001750 0001750 00000004773 14545562517 025021 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/apps/xapp-favorites-app.svg 0000664 0001750 0001750 00000005456 14545562517 023201 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/apps/xapp-mate-status-applet.svg 0000664 0001750 0001750 00000020233 14545562517 024141 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/categories/ 0000775 0001750 0001750 00000000000 14545562517 020102 5 ustar fabio fabio xapp-2.8.2/icons/hicolor/scalable/categories/xapp-prefs-plugins-symbolic.svg 0000664 0001750 0001750 00000004500 14545562517 026205 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/categories/xapp-prefs-preview-symbolic.svg 0000664 0001750 0001750 00000003642 14545562517 026213 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/categories/xapp-prefs-display-symbolic.svg 0000664 0001750 0001750 00000005126 14545562517 026176 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/categories/xapp-prefs-behavior-symbolic.svg 0000664 0001750 0001750 00000004641 14545562517 026331 0 ustar fabio fabio
xapp-2.8.2/icons/hicolor/scalable/categories/xapp-prefs-toolbar-symbolic.svg 0000664 0001750 0001750 00000002303 14545562517 026165 0 ustar fabio fabio
xapp-2.8.2/libxapp/ 0000775 0001750 0001750 00000000000 14545562517 013074 5 ustar fabio fabio xapp-2.8.2/libxapp/xapp-glade-catalog.c 0000664 0001750 0001750 00000000616 14545562517 016675 0 ustar fabio fabio #include "config.h"
#include
#include "xapp-gtk-window.h"
#include "xapp-icon-chooser-button.h"
#include "xapp-stack-sidebar.h"
void
xapp_glade_catalog_init (const gchar *catalog_name);
void
xapp_glade_catalog_init (const gchar *catalog_name)
{
g_type_ensure (XAPP_TYPE_GTK_WINDOW);
g_type_ensure (XAPP_TYPE_ICON_CHOOSER_BUTTON);
g_type_ensure (XAPP_TYPE_STACK_SIDEBAR);
}
xapp-2.8.2/libxapp/xapp-status-icon-monitor.c 0000664 0001750 0001750 00000042155 14545562517 020153 0 ustar fabio fabio
#include
#include
#include
#include
#include
#include
#include
#include
#include "xapp-status-icon.h"
#include "xapp-status-icon-monitor.h"
#include "xapp-statusicon-interface.h"
#define DEBUG_FLAG XAPP_DEBUG_STATUS_ICON
#include "xapp-debug.h"
#define MONITOR_NAME "org.x.StatusIconMonitor"
#define STATUS_ICON_MATCH "org.x.StatusIcon."
#define STATUS_ICON_INTERFACE "org.x.StatusIcon"
#define STATUS_ICON_PATH "/org/x/StatusIcon"
#define STATUS_ICON_PATH_PREFIX STATUS_ICON_PATH "/"
#define WATCHER_MAX_RESTARTS 2
enum
{
ICON_ADDED,
ICON_REMOVED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = {0, };
/**
* SECTION:xapp-status-icon-monitor
* @Short_description: Looks for XAppStatusIcons on DBUS and communicates
* info to an applet to represent the icons.
* @Title: XAppStatusIconMonitor
*
* The XAppStatusIconMonitor is intended to be utilized by some status applet
* to display info about an app.
*
* The simplest way to use is to make a new instance of this monitor, and connect
* to the #XAppStatusIconMonitor::icon-added and #XAppStatusIconMonitor::icon-removed signals.
* The received object for both of these signals is an #XAppStatusIconInterfaceProxy.
* It represents an application's #XAppStatusIcon, and has properties available for
* describing the icon name, tooltip, label and visibility.
*
* The proxy also provides methods to handle clicks, which can be called by the applet,
* to request that the app display its menu.
*/
typedef struct
{
GDBusConnection *connection;
GHashTable *object_managers;
guint owner_id;
guint listener_id;
} XAppStatusIconMonitorPrivate;
struct _XAppStatusIconMonitor
{
GObject parent_instance;
};
G_DEFINE_TYPE_WITH_PRIVATE (XAppStatusIconMonitor, xapp_status_icon_monitor, G_TYPE_OBJECT)
static void
on_object_manager_name_owner_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
XAppStatusIconMonitor *self = XAPP_STATUS_ICON_MONITOR (user_data);
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (self);
gchar *name, *owner;
g_object_get (object,
"name-owner", &owner,
"name", &name,
NULL);
DEBUG("App name owner changed - name '%s' is now %s)",
name, owner != NULL ? "owned" : "unowned");
if (owner == NULL)
{
g_hash_table_remove (priv->object_managers, name);
}
g_free (owner);
g_free (name);
}
static void
object_manager_object_added (XAppObjectManagerClient *manager,
GDBusObject *object,
gpointer user_data)
{
XAppStatusIconMonitor *self = XAPP_STATUS_ICON_MONITOR (user_data);
GDBusInterface *proxy;
proxy = g_dbus_object_get_interface (object, STATUS_ICON_INTERFACE);
g_signal_emit (self, signals[ICON_ADDED], 0, XAPP_STATUS_ICON_INTERFACE_PROXY (proxy));
g_object_unref (proxy);
}
static void
object_manager_object_removed (XAppObjectManagerClient *manager,
GDBusObject *object,
gpointer user_data)
{
XAppStatusIconMonitor *self = XAPP_STATUS_ICON_MONITOR (user_data);
GDBusInterface *proxy;
proxy = g_dbus_object_get_interface (object, STATUS_ICON_INTERFACE);
g_signal_emit (self, signals[ICON_REMOVED], 0, XAPP_STATUS_ICON_INTERFACE_PROXY (proxy));
g_object_unref (proxy);
}
static void
new_object_manager_created (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
XAppStatusIconMonitor *self = XAPP_STATUS_ICON_MONITOR (user_data);
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (self);
GDBusObjectManager *obj_mgr;
GList *objects = NULL, *iter;
GError *error;
gchar *name;
error = NULL;
obj_mgr = xapp_object_manager_client_new_finish (res,
&error);
if (error)
{
g_warning ("Couldn't create object manager for bus name: %s", error->message);
g_error_free (error);
return;
}
g_object_get (obj_mgr, "name", &name, NULL);
DEBUG("Object manager added for new bus name: '%s'", name);
g_signal_connect (obj_mgr,
"notify::name-owner",
G_CALLBACK (on_object_manager_name_owner_changed),
self);
g_signal_connect (obj_mgr,
"object-added",
G_CALLBACK (object_manager_object_added),
self);
g_signal_connect (obj_mgr,
"object-removed",
G_CALLBACK (object_manager_object_removed),
self);
g_hash_table_insert (priv->object_managers,
name,
obj_mgr);
objects = g_dbus_object_manager_get_objects (obj_mgr);
for (iter = objects; iter != NULL; iter = iter->next)
{
GDBusObject *object = G_DBUS_OBJECT (iter->data);
GDBusInterface *proxy = g_dbus_object_get_interface (object, STATUS_ICON_INTERFACE);
g_signal_emit (self, signals[ICON_ADDED], 0, proxy);
g_object_unref (proxy);
}
g_list_free_full (objects, g_object_unref);
}
static void
add_object_manager_for_name (XAppStatusIconMonitor *self,
const gchar *name)
{
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (self);
gchar **name_parts = NULL;
name_parts = g_strsplit (name, ".", -1);
if (g_strv_length (name_parts) == 4)
{
xapp_object_manager_client_new (priv->connection,
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START,
name,
STATUS_ICON_PATH,
NULL,
new_object_manager_created,
self);
}
else
{
DEBUG ("Adding object manager failed, bus name '%s' is invalid", name);
}
g_strfreev (name_parts);
}
static void
on_list_names_completed (GObject *source,
GAsyncResult *res,
gpointer user_data)
{
XAppStatusIconMonitor *self = XAPP_STATUS_ICON_MONITOR (user_data);
GVariant *result;
GVariantIter *iter;
gchar *str;
GError *error;
error = NULL;
result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
res,
&error);
if (error != NULL)
{
g_critical ("XAppStatusIconMonitor: attempt to ListNames failed: %s\n", error->message);
g_error_free (error);
return;
}
g_variant_get (result, "(as)", &iter);
while (g_variant_iter_loop (iter, "s", &str))
{
/* the '.' at the end so we don't catch ourselves in this */
if (g_str_has_prefix (str, STATUS_ICON_MATCH))
{
DEBUG ("Found new status icon app: %s", str);
add_object_manager_for_name (self, str);
}
}
g_variant_iter_free (iter);
g_variant_unref (result);
}
static void
find_and_add_icons (XAppStatusIconMonitor *self)
{
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (self);
DEBUG("Looking for status icon apps on the bus");
/* If there are no monitors (applets) already running when this is set up,
* this won't find anything. The XAppStatusIcons will be in fallback mode,
* and will only attempt to switch back after seeing this monitor appear
* on the bus, which means they'll show up via our NameOwnerChanged handler.
* Basically, this will never find anything if we're the first monitor to appear
* on the bus.
*/
g_dbus_connection_call (priv->connection,
"org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
"ListNames",
NULL,
G_VARIANT_TYPE ("(as)"),
G_DBUS_CALL_FLAGS_NONE,
3000, /* 3 secs */
NULL,
on_list_names_completed,
self);
}
static void
add_sn_watcher (XAppStatusIconMonitor *self)
{
GError *error = NULL;
if (!g_spawn_command_line_async (XAPP_SN_WATCHER_PATH, &error))
{
g_warning ("Could not spawn StatusNotifier watcher (xapp-sn-watcher): %s", error->message);
g_warning ("Support will be limited to native XAppStatusIcons only");
g_error_free (error);
}
}
static void
name_owner_changed (GDBusConnection *connection,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface_name,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
XAppStatusIconMonitor *self = XAPP_STATUS_ICON_MONITOR (user_data);
const gchar *name;
const gchar *old_owner;
const gchar *new_owner;
DEBUG ("NameOwnerChanged signal received: %s)", sender_name);
g_variant_get (parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
if (new_owner[0] != '\0')
{
add_object_manager_for_name (self, name);
}
}
static void
add_name_listener (XAppStatusIconMonitor *self)
{
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (self);
DEBUG ("Adding NameOwnerChanged listener for status icon apps");
priv->listener_id = g_dbus_connection_signal_subscribe (priv->connection,
"org.freedesktop.DBus",
"org.freedesktop.DBus",
"NameOwnerChanged",
"/org/freedesktop/DBus",
"org.x.StatusIcon",
G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE,
name_owner_changed,
self,
NULL);
}
static void
on_name_lost (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
if (connection == NULL)
{
g_warning ("error acquiring session bus");
}
}
static void
on_name_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
XAppStatusIconMonitor *self = XAPP_STATUS_ICON_MONITOR (user_data);
DEBUG ("Name owned on bus: %s", name);
add_name_listener (self);
find_and_add_icons (self);
add_sn_watcher (self);
}
static void
on_bus_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
XAppStatusIconMonitor *self = XAPP_STATUS_ICON_MONITOR (user_data);
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (self);
DEBUG ("Connected to bus: %s", name);
priv->connection = connection;
}
static void
connect_to_bus (XAppStatusIconMonitor *self)
{
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (self);
gchar *valid_app_name, *owned_name;
static gint unique_id = 0;
valid_app_name = g_strdelimit (g_strdup (g_get_prgname ()), ".-,=+~`/", '_');
owned_name = g_strdup_printf ("%s.%s_%d", MONITOR_NAME, valid_app_name, unique_id++);
g_free (valid_app_name);
DEBUG ("Attempting to own name on bus: %s", owned_name);
priv->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
owned_name,
G_DBUS_CONNECTION_FLAGS_NONE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
self,
NULL);
g_free(owned_name);
}
static void
xapp_status_icon_monitor_init (XAppStatusIconMonitor *self)
{
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (self);
priv->object_managers = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
connect_to_bus (self);
}
static void
xapp_status_icon_monitor_dispose (GObject *object)
{
XAppStatusIconMonitor *self = XAPP_STATUS_ICON_MONITOR (object);
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (self);
DEBUG ("XAppStatusIconMonitor dispose (%p)", object);
if (priv->connection != NULL)
{
if (priv->listener_id > 0)
{
g_dbus_connection_signal_unsubscribe (priv->connection, priv->listener_id);
priv->listener_id = 0;
}
if (priv->object_managers != NULL)
{
g_hash_table_unref (priv->object_managers);
priv->object_managers = NULL;
}
if (priv->owner_id > 0)
{
g_bus_unown_name(priv->owner_id);
priv->owner_id = 0;
}
g_clear_object (&priv->connection);
}
G_OBJECT_CLASS (xapp_status_icon_monitor_parent_class)->dispose (object);
}
static void
xapp_status_icon_monitor_finalize (GObject *object)
{
DEBUG ("XAppStatusIconMonitor finalize (%p)", object);
G_OBJECT_CLASS (xapp_status_icon_monitor_parent_class)->finalize (object);
}
static void
xapp_status_icon_monitor_class_init (XAppStatusIconMonitorClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = xapp_status_icon_monitor_dispose;
gobject_class->finalize = xapp_status_icon_monitor_finalize;
/**
* XAppStatusIconMonitor::icon-added:
* @monitor: the #XAppStatusIconMonitor
* @proxy: the interface proxy for the #XAppStatusIcon that has been added.
*
* This signal is emitted by the monitor when it has discovered a new
* #XAppStatusIcon on the bus.
*/
signals[ICON_ADDED] =
g_signal_new ("icon-added",
XAPP_TYPE_STATUS_ICON_MONITOR,
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, XAPP_TYPE_STATUS_ICON_INTERFACE_PROXY);
/**
* XAppStatusIconMonitor::icon-removed:
* @monitor: the #XAppStatusIconMonitor
* @proxy: the #XAppStatusIcon proxy that has been removed.
*
* This signal is emitted by the monitor when an #XAppStatusIcon has disappeared
* from the bus.
*/
signals[ICON_REMOVED] =
g_signal_new ("icon-removed",
XAPP_TYPE_STATUS_ICON_MONITOR,
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, XAPP_TYPE_STATUS_ICON_INTERFACE_PROXY);
}
static void
gather_objects_foreach_func (gpointer key,
gpointer value,
gpointer user_data)
{
GDBusObjectManager *obj_mgr = G_DBUS_OBJECT_MANAGER (value);
GList **ret = (GList **) user_data;
GList *objects = NULL, *iter;
objects = g_dbus_object_manager_get_objects (obj_mgr);
for (iter = objects; iter != NULL; iter = iter->next)
{
GDBusObject *object = G_DBUS_OBJECT (iter->data);
GDBusInterface *proxy = g_dbus_object_get_interface (object, STATUS_ICON_INTERFACE);
*ret = g_list_prepend (*ret, proxy);
g_object_unref (proxy);
}
g_list_free_full (objects, g_object_unref);
}
/**
* xapp_status_icon_monitor_list_icons:
* @monitor: a #XAppStatusIconMonitor
*
* List known icon proxies.
*
* Returns: (element-type XAppStatusIconMonitor) (transfer container): a #GList of icons
*
* Since: 1.6
*/
GList *
xapp_status_icon_monitor_list_icons (XAppStatusIconMonitor *monitor)
{
g_return_val_if_fail (XAPP_IS_STATUS_ICON_MONITOR (monitor), NULL);
GList *ret = NULL;
XAppStatusIconMonitorPrivate *priv = xapp_status_icon_monitor_get_instance_private (monitor);
g_hash_table_foreach (priv->object_managers,
(GHFunc) gather_objects_foreach_func,
&ret);
return ret;
}
/**
* xapp_status_icon_monitor_new:
*
* Creates a new monitor.
*
* Returns: (transfer full): a new #XAppStatusIconMonitor. Use g_object_unref when finished.
*
* Since: 1.6
*/
XAppStatusIconMonitor *
xapp_status_icon_monitor_new (void)
{
return g_object_new (XAPP_TYPE_STATUS_ICON_MONITOR, NULL);
}
xapp-2.8.2/libxapp/xapp-status-icon.h 0000664 0001750 0001750 00000006402 14545562517 016466 0 ustar fabio fabio #ifndef __XAPP_STATUS_ICON_H__
#define __XAPP_STATUS_ICON_H__
#include
#include
#include
G_BEGIN_DECLS
#define XAPP_TYPE_STATUS_ICON (xapp_status_icon_get_type ())
G_DECLARE_FINAL_TYPE (XAppStatusIcon, xapp_status_icon, XAPP, STATUS_ICON, GObject)
/**
* XAppStatusIconState:
* @XAPP_STATUS_ICON_STATE_NATIVE: The #XAppStatusIcon is currently being handled
* by an #XAppStatusIconMonitor (usually in an applet).
* @XAPP_STATUS_ICON_STATE_FALLBACK: The #XAppStatusIcon is currently being handled
* by a legacy system tray implementation (using GtkStatusIcon).
* @XAPP_STATUS_ICON_STATE_NO_SUPPORT: The #XAppStatusIcon is not currently being handled by any
* kind of status icon implementation.
*/
typedef enum
{
XAPP_STATUS_ICON_STATE_NATIVE,
XAPP_STATUS_ICON_STATE_FALLBACK,
XAPP_STATUS_ICON_STATE_NO_SUPPORT
} XAppStatusIconState;
/**
* XAppScrollDirection:
* @XAPP_SCROLL_UP: Scroll theoretical content up.
* @XAPP_SCROLL_DOWN: Scroll theoretical content down.
* @XAPP_SCROLL_LEFT: Scroll theoretical content left.
* @XAPP_SCROLL_RIGHT: Scroll theoretical content right.
*
* Represents the direction of icon scroll events.
*/
typedef enum
{
XAPP_SCROLL_UP,
XAPP_SCROLL_DOWN,
XAPP_SCROLL_LEFT,
XAPP_SCROLL_RIGHT
} XAppScrollDirection;
XAppStatusIcon *xapp_status_icon_new (void);
XAppStatusIcon *xapp_status_icon_new_with_name (const gchar *name);
void xapp_status_icon_set_name (XAppStatusIcon *icon, const gchar *name);
void xapp_status_icon_set_icon_name (XAppStatusIcon *icon, const gchar *icon_name);
gint xapp_status_icon_get_icon_size (XAppStatusIcon *icon);
void xapp_status_icon_set_tooltip_text (XAppStatusIcon *icon, const gchar *tooltip_text);
void xapp_status_icon_set_label (XAppStatusIcon *icon, const gchar *label);
void xapp_status_icon_set_visible (XAppStatusIcon *icon, const gboolean visible);
gboolean xapp_status_icon_get_visible (XAppStatusIcon *icon);
void xapp_status_icon_popup_menu (XAppStatusIcon *icon,
GtkMenu *menu,
gint x,
gint y,
guint button,
guint _time,
gint panel_position);
void xapp_status_icon_set_primary_menu (XAppStatusIcon *icon, GtkMenu *menu);
GtkWidget *xapp_status_icon_get_primary_menu (XAppStatusIcon *icon);
void xapp_status_icon_set_secondary_menu (XAppStatusIcon *icon, GtkMenu *menu);
GtkWidget *xapp_status_icon_get_secondary_menu (XAppStatusIcon *icon);
XAppStatusIconState xapp_status_icon_get_state (XAppStatusIcon *icon);
void xapp_status_icon_set_metadata (XAppStatusIcon *icon,
const gchar *metadata);
/* static */
gboolean xapp_status_icon_any_monitors (void);
G_END_DECLS
#endif /* __XAPP_STATUS_ICON_H__ */
xapp-2.8.2/libxapp/xapp-dark-mode-manager.h 0000664 0001750 0001750 00000000723 14545562517 017470 0 ustar fabio fabio #ifndef __XAPP_DARK_MODE_MANAGER_H__
#define __XAPP_DARK_MODE_MANAGER_H__
#include
#include
#include
G_BEGIN_DECLS
#define XAPP_TYPE_DARK_MODE_MANAGER (xapp_dark_mode_manager_get_type ())
G_DECLARE_FINAL_TYPE (XAppDarkModeManager, xapp_dark_mode_manager, XAPP, DARK_MODE_MANAGER, GObject)
XAppDarkModeManager *xapp_dark_mode_manager_new (gboolean prefer_dark_mode);
G_END_DECLS
#endif /* __XAPP_DARK_MODE_MANAGER_H__ */
xapp-2.8.2/libxapp/meson.build 0000664 0001750 0001750 00000011011 14545562517 015230 0 ustar fabio fabio glib_min_ver = '>=2.44.0'
gio_dep = dependency('gio-2.0', version: glib_min_ver, required: true)
gio_unix_dep = dependency('gio-unix-2.0', version: glib_min_ver, required: true)
glib_dep = dependency('glib-2.0', version: glib_min_ver, required: true)
gtk3_dep = dependency('gtk+-3.0', version: '>=3.22', required: true)
gmodule_dep = dependency('gmodule-2.0', version: glib_min_ver, required: true)
libdeps = []
libdeps += gio_dep
libdeps += gio_unix_dep
libdeps += glib_dep
libdeps += gtk3_dep
libdeps += gmodule_dep
libdeps += dependency('gdk-pixbuf-2.0', version: '>=2.22.0', required: true)
libdeps += dependency('cairo', required: true)
libdeps += dependency('x11', required: true)
favorite_vfs_sources = [
'favorite-vfs-file.c',
'favorite-vfs-file-enumerator.c',
'favorite-vfs-file-monitor.c'
]
xapp_debug = [
'xapp-debug.h',
'xapp-debug.c'
]
xapp_headers = [
'xapp-dark-mode-manager.h',
'xapp-favorites.h',
'xapp-gtk-window.h',
'xapp-gpu-offload-helper.h',
'xapp-icon-chooser-button.h',
'xapp-icon-chooser-dialog.h',
'xapp-monitor-blanker.h',
'xapp-preferences-window.h',
'xapp-stack-sidebar.h',
'xapp-status-icon.h',
'xapp-status-icon-monitor.h',
'xapp-style-manager.h',
'xapp-util.h',
'xapp-visibility-group.h'
]
xapp_sources = [
'xapp-dark-mode-manager.c',
'xapp-favorites.c',
'xapp-glade-catalog.c',
'xapp-gtk-window.c',
'xapp-gpu-offload-helper.c',
'xapp-icon-chooser-button.c',
'xapp-icon-chooser-dialog.c',
'xapp-monitor-blanker.c',
'xapp-preferences-window.c',
'xapp-stack-sidebar.c',
'xapp-status-icon.c',
'xapp-status-icon-monitor.c',
'xapp-style-manager.c',
'xapp-util.c',
'xapp-visibility-group.c'
]
switcheroo_sources = gnome.gdbus_codegen(
'xapp-switcheroo-interface',
sources: 'net.hadess.SwitcherooControl.xml',
interface_prefix: 'net.hadess',
namespace: 'XApp'
)
xapp_sources += switcheroo_sources
if not app_lib_only
libdeps += dependency('libgnomekbdui', required: true)
xapp_headers += 'xapp-kbd-layout-controller.h'
xapp_sources += 'xapp-kbd-layout-controller.c'
endif
xapp_statusicon_interface_sources = gnome.gdbus_codegen(
'xapp-statusicon-interface',
sources: 'org.x.StatusIcon.xml',
interface_prefix: 'org.x.StatusIcon',
namespace: 'XApp',
annotations: [[ 'org.x.StatusIcon', 'org.gtk.GDBus.C.Name', 'StatusIconInterface' ]],
object_manager: true,
install_header: true,
install_dir: join_paths(get_option('prefix'), get_option('includedir'), 'xapp/libxapp')
)
dbus_headers = [ xapp_statusicon_interface_sources[1] ]
xapp_sources += xapp_statusicon_interface_sources[0]
xapp_enums = gnome.mkenums_simple('xapp-enums',
sources : xapp_headers,
identifier_prefix : 'XApp',
symbol_prefix : 'xapp'
)
libxapp = library('xapp',
sources : xapp_headers + xapp_sources + xapp_enums + dbus_headers + favorite_vfs_sources + xapp_debug,
include_directories: [top_inc],
version: meson.project_version(),
soversion: '1',
dependencies: libdeps,
c_args: ['-Wno-declaration-after-statement', '-DG_LOG_DOMAIN="XApp"'],
link_args: [ '-Wl,-Bsymbolic', '-Wl,-z,relro', '-Wl,-z,now', '-lm'],
install: true
)
install_headers(xapp_headers,
subdir: 'xapp/libxapp'
)
libxapp_dep = declare_dependency(
link_with: libxapp,
include_directories: top_inc,
dependencies: libdeps,
sources: [ xapp_headers, dbus_headers ]
)
gir = gnome.generate_gir(libxapp,
namespace: 'XApp',
nsversion: '1.0',
sources: xapp_headers + xapp_sources + dbus_headers + xapp_enums,
identifier_prefix: 'XApp',
symbol_prefix: 'xapp_',
export_packages: 'xapp',
includes: ['GObject-2.0', 'Gtk-3.0'],
install: true
)
pkg.generate(
libraries: libxapp,
name: 'xapp',
subdirs: 'xapp',
description: 'Utility library',
version: meson.project_version(),
requires: ['gtk+-3.0', 'gobject-2.0', 'cairo'],
requires_private: 'xkbfile',
)
install_data(['xapp-glade-catalog.xml'],
install_dir : join_paths(get_option('datadir'), 'glade/catalogs')
)
gnome.generate_vapi('xapp',
packages: ['glib-2.0', 'gio-unix-2.0', 'gtk+-3.0'],
sources: gir[0],
metadata_dirs: meson.current_source_dir(),
install: true
)
if not app_lib_only
gtk3_module = shared_module(
'xapp-gtk3-module', ['xapp-gtk3-module.c'],
include_directories: [top_inc],
dependencies: [gtk3_dep, libxapp_dep],
install: true,
install_dir: join_paths(gtk3_dep.get_variable(pkgconfig: 'libdir'),'gtk-3.0','modules')
)
endif
xapp-2.8.2/libxapp/xapp-monitor-blanker.h 0000664 0001750 0001750 00000001337 14545562517 017322 0 ustar fabio fabio #ifndef __XAPP_MONITOR_BLANKER_H__
#define __XAPP_MONITOR_BLANKER_H__
#include
#include
#include
G_BEGIN_DECLS
#define XAPP_TYPE_MONITOR_BLANKER (xapp_monitor_blanker_get_type ())
G_DECLARE_FINAL_TYPE (XAppMonitorBlanker, xapp_monitor_blanker, XAPP, MONITOR_BLANKER, GObject)
XAppMonitorBlanker *xapp_monitor_blanker_new (void);
void xapp_monitor_blanker_blank_other_monitors (XAppMonitorBlanker *self,
GtkWindow *window);
void xapp_monitor_blanker_unblank_monitors (XAppMonitorBlanker *self);
gboolean xapp_monitor_blanker_are_monitors_blanked (XAppMonitorBlanker *self);
G_END_DECLS
#endif /* __XAPP_MONITOR_BLANKER_H__ */
xapp-2.8.2/libxapp/xapp-debug.c 0000664 0001750 0001750 00000006447 14545562517 015307 0 ustar fabio fabio /*
* xapp-debug: debug loggers for xapp
*
* Copyright (C) 2007 Collabora Ltd.
* Copyright (C) 2007 Nokia Corporation
* Copyright (C) 2010 Red Hat, Inc.
*
* 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
*
* Copied from nemo
*/
#include
#include
#include "xapp-debug.h"
#ifdef ENABLE_DEBUG
static DebugFlags flags = 0;
static gboolean initialized = FALSE;
static GDebugKey keys[] = {
{ "GtkWindow", XAPP_DEBUG_WINDOW },
{ "Favorites", XAPP_DEBUG_FAVORITES },
{ "FavoriteVfs", XAPP_DEBUG_FAVORITE_VFS },
{ "StatusIcon", XAPP_DEBUG_STATUS_ICON },
{ "SnWatcher", XAPP_DEBUG_SN_WATCHER },
{ "GtkModule", XAPP_DEBUG_MODULE},
{ "VisibilityGroup", XAPP_DEBUG_VISIBILITY_GROUP},
{ "GpuOffload", XAPP_DEBUG_GPU_OFFLOAD},
{ "DarkModeManager", XAPP_DEBUG_DARK_MODE_MANAGER},
{ 0, }
};
const gchar *
debug_flag_to_string (DebugFlags flag)
{
switch (flag)
{
case XAPP_DEBUG_WINDOW:
return "GtkWindow";
case XAPP_DEBUG_FAVORITES:
return "Favorites";
case XAPP_DEBUG_FAVORITE_VFS:
return "FavoriteVFS";
case XAPP_DEBUG_STATUS_ICON:
return "StatusIcon";
case XAPP_DEBUG_SN_WATCHER:
return "SnWatcher";
case XAPP_DEBUG_MODULE:
return "GtkModule";
case XAPP_DEBUG_VISIBILITY_GROUP:
return "VisibilityGroup";
case XAPP_DEBUG_GPU_OFFLOAD:
return "GpuOffload";
case XAPP_DEBUG_DARK_MODE_MANAGER:
return "DarkModeManager";
}
return "";
}
static void
xapp_debug_set_flags_from_env (void)
{
guint nkeys;
const gchar *flags_string;
for (nkeys = 0; keys[nkeys].value; nkeys++);
flags_string = g_getenv ("XAPP_DEBUG");
if (flags_string)
xapp_debug_set_flags (g_parse_debug_string (flags_string, keys, nkeys));
initialized = TRUE;
}
void
xapp_debug_set_flags (DebugFlags new_flags)
{
flags |= new_flags;
initialized = TRUE;
}
gboolean
xapp_debug_flag_is_set (DebugFlags flag)
{
return flag & flags;
}
void
xapp_debug (DebugFlags flag,
const gchar *format,
...)
{
va_list args;
va_start (args, format);
xapp_debug_valist (flag, format, args);
va_end (args);
}
void
xapp_debug_valist (DebugFlags flag,
const gchar *format,
va_list args)
{
if (G_UNLIKELY(!initialized))
xapp_debug_set_flags_from_env ();
if (flag & flags)
{
// I would think this should be G_LOG_LEVEL_DEBUG, but I can't get it to show up
// in the journal/xsession-errors unless I drop it to message (even with G_MESSAGES_DEBUG=all)
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, args);
}
}
#endif /* ENABLE_DEBUG */
xapp-2.8.2/libxapp/favorite-vfs-file-monitor.c 0000664 0001750 0001750 00000035101 14545562517 020255 0 ustar fabio fabio #include "xapp-favorites.h"
#include "favorite-vfs-file.h"
#include "favorite-vfs-file-monitor.h"
#define DEBUG_FLAG XAPP_DEBUG_FAVORITE_VFS
#include "xapp-debug.h"
typedef struct
{
gulong changed_handler_id;
GHashTable *file_monitors;
GList *infos;
GVolumeMonitor *mount_mon;
} FavoriteVfsFileMonitorPrivate;
struct _FavoriteVfsFileMonitor
{
GObject parent_instance;
FavoriteVfsFileMonitorPrivate *priv;
};
G_DEFINE_TYPE_WITH_PRIVATE(FavoriteVfsFileMonitor, \
favorite_vfs_file_monitor, \
G_TYPE_FILE_MONITOR)
GFile *_favorite_vfs_file_new_for_info (XAppFavoriteInfo *info);
// static void
// rename_favorite (GFile *old_file,
// GFile *new_file)
// {
// gchar *old_file_uri, *new_file_uri;
// old_file_uri = g_file_get_uri (old_file);
// new_file_uri = g_file_get_uri (new_file);
// _xapp_favorites_rename (xapp_favorites_get_default (),
// old_file_uri,
// new_file_uri);
// g_free (old_file_uri);
// g_free (new_file_uri);
// }
static void
favorite_real_file_changed (GFileMonitor *rfmonitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event_type,
gpointer user_data)
{
// Disabled
return;
// g_return_if_fail (FAVORITE_IS_VFS_FILE_MONITOR (user_data));
// FavoriteVfsFileMonitor *monitor = FAVORITE_VFS_FILE_MONITOR (user_data);
// FavoriteVfsFileMonitorPrivate *priv = favorite_vfs_file_monitor_get_instance_private (monitor);
// DEBUG ("real file changed: %s: %d", g_file_get_uri (file), event_type);
// switch (event_type)
// {
// case G_FILE_MONITOR_EVENT_MOVED_OUT:
// break;
// {
// gchar *uri = g_file_get_uri (file);
// DEBUG ("Deleted: %s\n", uri);
// xapp_favorites_remove (xapp_favorites_get_default (), uri);
// g_free (uri);
// }
// break;
// case G_FILE_MONITOR_EVENT_RENAMED:
// break;
// {
// gchar *uri = g_file_get_uri (file);
// DEBUG ("Renamed: %s\n", uri);
// rename_favorite (file, other_file);
// }
// break;
// case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
// case G_FILE_MONITOR_EVENT_CHANGED:
// {
// gchar *uri = g_file_get_uri (file);
// GList *iter;
// for (iter = priv->infos; iter != NULL; iter = iter->next)
// {
// XAppFavoriteInfo *info = (XAppFavoriteInfo *) iter->data;
// if (g_strcmp0 (uri, info->uri) == 0)
// {
// GFile *fav_file;
// gchar *uri;
// uri = path_to_fav_uri (info->display_name);
// fav_file = g_file_new_for_uri (uri);
// DEBUG ("Changed: %s", uri);
// g_free (uri);
// g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
// fav_file,
// NULL,
// G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED);
// g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
// fav_file,
// NULL,
// G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT);
// g_object_unref (fav_file);
// break;
// }
// }
// }
// break;
// case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
// case G_FILE_MONITOR_EVENT_CREATED:
// // case G_FILE_MONITOR_EVENT_CHANGED:
// case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
// case G_FILE_MONITOR_EVENT_UNMOUNTED:
// case G_FILE_MONITOR_EVENT_MOVED:
// case G_FILE_MONITOR_EVENT_MOVED_IN:
// case G_FILE_MONITOR_EVENT_DELETED:
// break;
// default:
// g_warn_if_reached ();
// }
}
static void
unmonitor_files (FavoriteVfsFileMonitor *monitor)
{
/* Disabled. See below */
return;
FavoriteVfsFileMonitorPrivate *priv = favorite_vfs_file_monitor_get_instance_private (monitor);
if (priv->file_monitors != NULL)
{
g_hash_table_destroy (priv->file_monitors);
priv->file_monitors = NULL;
}
}
static void
monitor_files (FavoriteVfsFileMonitor *monitor)
{
/* Disabled - this isn't necessary right now but could be expanded to help
* support less integrated apps. */
return;
FavoriteVfsFileMonitorPrivate *priv = favorite_vfs_file_monitor_get_instance_private (monitor);
GList *iter;
priv->file_monitors = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) g_object_unref);
for (iter = priv->infos; iter != NULL; iter = iter->next)
{
XAppFavoriteInfo *info = (XAppFavoriteInfo *) iter->data;
GFileMonitor *real_monitor;
GFile *real_file;
GError *error;
DEBUG ("Monitoring real file: %s\n", info->uri);
error = NULL;
real_file = g_file_new_for_uri (info->uri);
real_monitor = g_file_monitor (real_file,
G_FILE_MONITOR_WATCH_MOVES,
NULL,
&error);
g_object_unref (real_file);
if (real_monitor == NULL)
{
if (error != NULL)
{
g_warning ("Unable to add file monitor for '%s': %s", info->uri, error->message);
g_error_free (error);
}
continue;
}
g_hash_table_insert (priv->file_monitors,
(gpointer) g_strdup (info->uri),
(gpointer) real_monitor);
g_signal_connect (real_monitor,
"changed",
G_CALLBACK (favorite_real_file_changed),
monitor);
}
}
static gint
find_info_by_uri (gconstpointer ptr_a,
gconstpointer ptr_b)
{
XAppFavoriteInfo *info = (XAppFavoriteInfo *) ptr_a;
const gchar *uri = (gchar *) ptr_b;
// GCompareFunc returns 0 when there's a match.
return g_strcmp0 (info->uri, uri);
}
static void
favorites_changed (XAppFavorites *favorites,
gpointer user_data)
{
g_return_if_fail (XAPP_IS_FAVORITES (favorites));
g_return_if_fail (FAVORITE_IS_VFS_FILE_MONITOR (user_data));
FavoriteVfsFileMonitor *monitor = FAVORITE_VFS_FILE_MONITOR (user_data);
FavoriteVfsFileMonitorPrivate *priv = favorite_vfs_file_monitor_get_instance_private (monitor);
GList *added, *removed;
GList *iter, *new_infos;
if (g_file_monitor_is_cancelled (G_FILE_MONITOR (monitor)))
{
return;
}
added = removed = NULL;
new_infos = xapp_favorites_get_favorites (favorites, NULL);
for (iter = priv->infos; iter != NULL; iter = iter->next)
{
XAppFavoriteInfo *old_info = (XAppFavoriteInfo *) iter->data;
GList *res = g_list_find_custom (new_infos,
(gpointer) old_info->uri,
(GCompareFunc) find_info_by_uri);
if (res == NULL)
{
removed = g_list_prepend (removed, old_info);
}
}
for (iter = new_infos; iter != NULL; iter = iter->next)
{
XAppFavoriteInfo *new_info = (XAppFavoriteInfo *) iter->data;
GList *res = g_list_find_custom (priv->infos,
(gpointer) new_info->uri,
(GCompareFunc) find_info_by_uri);
if (res == NULL)
{
added = g_list_prepend (added, new_info);
}
}
for (iter = removed; iter != NULL; iter = iter->next)
{
XAppFavoriteInfo *removed_info = (XAppFavoriteInfo *) iter->data;
GFile *file = _favorite_vfs_file_new_for_info (removed_info);
g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
file,
NULL,
G_FILE_MONITOR_EVENT_DELETED);
g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
file,
NULL,
G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT);
g_object_unref (file);
}
for (iter = added; iter != NULL; iter = iter->next)
{
XAppFavoriteInfo *added_info = (XAppFavoriteInfo *) iter->data;
GFile *file = _favorite_vfs_file_new_for_info (added_info);
g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
file,
NULL,
G_FILE_MONITOR_EVENT_CREATED);
g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
file,
NULL,
G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT);
g_object_unref (file);
}
g_list_free (added);
g_list_free (removed);
GList *tmp = priv->infos;
priv->infos = new_infos;
g_list_free_full (tmp, (GDestroyNotify) xapp_favorite_info_free);
//FIXME: add/remove individually
unmonitor_files (monitor);
monitor_files (monitor);
}
static void
mounts_changed (GVolumeMonitor *mount_mon,
GMount *mount,
gpointer user_data)
{
g_return_if_fail (FAVORITE_IS_VFS_FILE_MONITOR (user_data));
FavoriteVfsFileMonitor *monitor = FAVORITE_VFS_FILE_MONITOR (user_data);
FavoriteVfsFileMonitorPrivate *priv = favorite_vfs_file_monitor_get_instance_private (monitor);
GFile *root;
GList *iter, *mount_favorites;
root = g_mount_get_root (mount);
mount_favorites = NULL;
// Find any favorites that are descendent from root.
for (iter = priv->infos; iter != NULL; iter = iter->next)
{
XAppFavoriteInfo *info = (XAppFavoriteInfo *) iter->data;
GFile *fav_file = g_file_new_for_uri (info->uri);
gchar *relpath;
relpath = g_file_get_relative_path (root, fav_file);
if (relpath != NULL)
{
mount_favorites = g_list_prepend (mount_favorites, info);
}
g_free (relpath);
g_object_unref (fav_file);
}
if (mount_favorites != NULL)
{
for (iter = mount_favorites; iter != NULL; iter = iter->next) {
XAppFavoriteInfo *info = (XAppFavoriteInfo *) iter->data;
GFile *fav_file;
gchar *uri;
uri = path_to_fav_uri (info->display_name);
fav_file = g_file_new_for_uri (uri);
g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
fav_file,
NULL,
G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED);
g_file_monitor_emit_event (G_FILE_MONITOR (monitor),
fav_file,
NULL,
G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT);
g_free (uri);
g_object_unref (fav_file);
}
g_list_free (mount_favorites);
}
g_object_unref (root);
unmonitor_files (monitor);
monitor_files (monitor);
}
static gboolean
favorite_vfs_file_monitor_cancel (GFileMonitor* gfilemon)
{
FavoriteVfsFileMonitor *monitor = FAVORITE_VFS_FILE_MONITOR (gfilemon);
FavoriteVfsFileMonitorPrivate *priv = favorite_vfs_file_monitor_get_instance_private (monitor);
if (priv->changed_handler_id > 0)
{
g_signal_handler_disconnect (xapp_favorites_get_default (), priv->changed_handler_id);
}
return TRUE;
}
static void
favorite_vfs_file_monitor_init (FavoriteVfsFileMonitor *monitor)
{
FavoriteVfsFileMonitorPrivate *priv = favorite_vfs_file_monitor_get_instance_private (monitor);
priv->mount_mon = g_volume_monitor_get ();
g_signal_connect (priv->mount_mon,
"mount-added",
G_CALLBACK (mounts_changed),
monitor);
g_signal_connect (priv->mount_mon,
"mount-removed",
G_CALLBACK (mounts_changed),
monitor);
priv->infos = xapp_favorites_get_favorites (xapp_favorites_get_default (), NULL);
priv->changed_handler_id = g_signal_connect (xapp_favorites_get_default (),
"changed",
G_CALLBACK (favorites_changed),
monitor);
monitor_files (monitor);
}
static void
favorite_vfs_file_monitor_dispose (GObject *object)
{
FavoriteVfsFileMonitor *monitor = FAVORITE_VFS_FILE_MONITOR(object);
FavoriteVfsFileMonitorPrivate *priv = favorite_vfs_file_monitor_get_instance_private(monitor);
unmonitor_files (monitor);
g_signal_handlers_disconnect_by_func (priv->mount_mon, mounts_changed, monitor);
g_clear_object (&priv->mount_mon);
if (priv->infos != NULL)
{
g_list_free_full (priv->infos, (GDestroyNotify) xapp_favorite_info_free);
priv->infos = NULL;
}
G_OBJECT_CLASS (favorite_vfs_file_monitor_parent_class)->dispose (object);
}
static void
favorite_vfs_file_monitor_finalize (GObject *object)
{
// FavoriteVfsFileMonitor *self = FAVORITE_VFS_FILE_MONITOR(object);
// FavoriteVfsFileMonitorPrivate *priv = favorite_vfs_file_monitor_get_instance_private(self);
G_OBJECT_CLASS (favorite_vfs_file_monitor_parent_class)->finalize (object);
}
static void
favorite_vfs_file_monitor_class_init (FavoriteVfsFileMonitorClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GFileMonitorClass *monitor_class = G_FILE_MONITOR_CLASS (klass);
gobject_class->dispose = favorite_vfs_file_monitor_dispose;
gobject_class->finalize = favorite_vfs_file_monitor_finalize;
monitor_class->cancel = favorite_vfs_file_monitor_cancel;
}
GFileMonitor *
favorite_vfs_file_monitor_new (void)
{
return G_FILE_MONITOR (g_object_new (FAVORITE_TYPE_VFS_FILE_MONITOR, NULL));
}
xapp-2.8.2/libxapp/xapp-preferences-window.c 0000664 0001750 0001750 00000014554 14545562517 020025 0 ustar fabio fabio #include
#include "xapp-preferences-window.h"
#include "xapp-stack-sidebar.h"
/**
* SECTION:xapp-preferences-window
* @Short_description: A base preferences window
* @Title: XAppPreferencesWindow
*
* The XAppPreferencesWindow sets up a simple dialog
* window with a GtkStack, GtkSidebarSwitcher, and
* GtkActionBar. The stack switcher and action bar only
* show when needed.
*/
typedef struct
{
GtkWidget *stack;
XAppStackSidebar *side_switcher;
GtkWidget *button_area;
gint num_pages;
} XAppPreferencesWindowPrivate;
enum
{
CLOSE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = {0, };
G_DEFINE_TYPE_WITH_PRIVATE (XAppPreferencesWindow, xapp_preferences_window, GTK_TYPE_WINDOW)
static void
xapp_preferences_window_init (XAppPreferencesWindow *window)
{
XAppPreferencesWindowPrivate *priv = xapp_preferences_window_get_instance_private (window);
GtkWidget *main_box;
GtkWidget *secondary_box;
GtkStyleContext *style_context;
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG);
gtk_container_set_border_width (GTK_CONTAINER (window), 5);
main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_set_border_width (GTK_CONTAINER (main_box), 5);
gtk_container_add (GTK_CONTAINER (window), main_box);
secondary_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_container_set_border_width (GTK_CONTAINER (secondary_box), 5);
gtk_box_pack_start (GTK_BOX (main_box), secondary_box, TRUE, TRUE, 0);
style_context = gtk_widget_get_style_context (secondary_box);
gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_FRAME);
priv->side_switcher = xapp_stack_sidebar_new ();
gtk_widget_set_size_request (GTK_WIDGET (priv->side_switcher), 100, -1);
gtk_box_pack_start (GTK_BOX (secondary_box), GTK_WIDGET (priv->side_switcher), FALSE, FALSE, 0);
gtk_widget_set_no_show_all (GTK_WIDGET (priv->side_switcher), TRUE);
// XAppStackSidebar calls show_all on itself during its init, we need to hide
// it here so our single/multiple page mechanism here works properly.
gtk_widget_hide (GTK_WIDGET (priv->side_switcher));
priv->stack = gtk_stack_new ();
gtk_stack_set_transition_type (GTK_STACK (priv->stack), GTK_STACK_TRANSITION_TYPE_CROSSFADE);
gtk_box_pack_start (GTK_BOX (secondary_box), priv->stack, TRUE, TRUE, 0);
xapp_stack_sidebar_set_stack (priv->side_switcher, GTK_STACK (priv->stack));
style_context = gtk_widget_get_style_context (priv->stack);
gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_VIEW);
priv->button_area = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_set_border_width (GTK_CONTAINER (priv->button_area), 5);
gtk_box_pack_start (GTK_BOX (main_box), priv->button_area, FALSE, FALSE, 0);
gtk_widget_set_no_show_all (priv->button_area, TRUE);
/* Keep track of the number of pages so we can hide the stack switcher with < 2 */
priv->num_pages = 0;
}
static void
xapp_preferences_window_close (XAppPreferencesWindow *window)
{
gtk_window_close (GTK_WINDOW (window));
}
static void
xapp_preferences_window_class_init (XAppPreferencesWindowClass *klass)
{
GtkBindingSet *binding_set;
klass->close = xapp_preferences_window_close;
signals[CLOSE] =
g_signal_new ("close",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (XAppPreferencesWindowClass, close),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0);
}
/**
* xapp_preferences_window_new:
*
* Creates a new #XAppPreferencesWindow.
*
* Returns: a newly created #XAppPreferencesWindow
*/
XAppPreferencesWindow *
xapp_preferences_window_new (void)
{
return g_object_new (XAPP_TYPE_PREFERENCES_WINDOW, NULL);
}
/**
* xapp_preferences_window_add_page:
* @window: a #XAppPreferencesWindow
* @widget: a #GtkWidget to add
* @name: the name for the page
* @title: a human-readable title for the page
*
* Adds a page to the window. The page is identified by name. The
* title will be used in the sidebar so should be short. The sidebar
* will show automatically once at least two pages are added.
*/
void
xapp_preferences_window_add_page (XAppPreferencesWindow *window,
GtkWidget *widget,
const gchar *name,
const gchar *title)
{
XAppPreferencesWindowPrivate *priv = xapp_preferences_window_get_instance_private (window);
g_return_if_fail (XAPP_IS_PREFERENCES_WINDOW (window));
gtk_stack_add_titled (GTK_STACK (priv->stack), widget, name, title);
priv->num_pages++;
if (priv->num_pages > 1)
{
gtk_widget_set_no_show_all (GTK_WIDGET (priv->side_switcher), FALSE);
}
}
/**
* xapp_preferences_window_add_button:
* @window: a #XAppPreferencesWindow
* @button: a #GtkWidget to add
* @pack_type: a #GtkPackType to use
*
* Adds a button to the bottom action bar of the window. Where
* the button is place will be determined by the #GtkPackType. The
* action bar will show automatically once at least one button is
* added.
*/
void
xapp_preferences_window_add_button (XAppPreferencesWindow *window,
GtkWidget *button,
GtkPackType pack_type)
{
XAppPreferencesWindowPrivate *priv = xapp_preferences_window_get_instance_private (window);
GtkStyleContext *style_context;
g_return_if_fail (XAPP_IS_PREFERENCES_WINDOW (window));
g_return_if_fail (GTK_IS_WIDGET (button));
gtk_container_add (GTK_CONTAINER (priv->button_area), button);
if (pack_type == GTK_PACK_END)
{
gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (priv->button_area), button, TRUE);
}
else if (pack_type != GTK_PACK_START)
{
return;
}
style_context = gtk_widget_get_style_context (button);
gtk_style_context_add_class (style_context, "text-button");
gtk_widget_set_no_show_all (priv->button_area, FALSE);
}
xapp-2.8.2/libxapp/xapp-gpu-offload-helper.c 0000664 0001750 0001750 00000046045 14545562517 017677 0 ustar fabio fabio #include "config.h"
#define DEBUG_FLAG XAPP_DEBUG_GPU_OFFLOAD
#include "xapp-debug.h"
#include "xapp-gpu-offload-helper.h"
#include "xapp-switcheroo-interface.h"
#include "xapp-util.h"
static const gchar *DEFAULT_ENV_ARGV[5] = {
"__NV_PRIME_RENDER_OFFLOAD", "1",
"__GLX_VENDOR_LIBRARY_NAME", "nvidia",
NULL
};
XAppGpuInfo *xapp_gpu_info_copy (const XAppGpuInfo *info);
void xapp_gpu_info_free (XAppGpuInfo *info);
G_DEFINE_BOXED_TYPE (XAppGpuInfo, xapp_gpu_info, xapp_gpu_info_copy, xapp_gpu_info_free);
/**
* SECTION:xapp-gpu-offload-helper
* @Short_description: Simple interface for Switcheroo.
* @Title: XAppGpuOffloadHelper
*
* #XAppGpuOffloadHelper is class that provides a reliable property cache and simple return methods
* for getting offload_helper parameters and conditions from the Switcheroo interface.
*
* Since 2.6
*/
XAppGpuInfo *
xapp_gpu_info_copy (const XAppGpuInfo *info)
{
DEBUG ("XAppGpuInfo copy");
g_return_val_if_fail (info != NULL, NULL);
#if GLIB_CHECK_VERSION(2, 68, 0)
XAppGpuInfo *_info = g_memdup2 (info, sizeof(XAppGpuInfo));
#else
XAppGpuInfo *_info = g_memdup (info, sizeof(XAppGpuInfo));
#endif
_info->id = info->id;
_info->is_default = info->is_default;
_info->display_name = g_strdup (info->display_name);
_info->env_strv = g_strdupv (info->env_strv);
return _info;
}
/**
* xapp_gpu_info_free:
* @group: The #XAppGpuInfo to free.
*
* Destroys the #XAppGpuInfo.
*
* Since 2.6
*/
void
xapp_gpu_info_free (XAppGpuInfo *info)
{
DEBUG ("XAppGpuInfo free");
g_return_if_fail (info != NULL);
g_strfreev (info->env_strv);
g_free (info->display_name);
g_free (info);
}
/**
* xapp_gpu_info_get_shell_env_prefix:
* @info: An #XAppGpuInfo.
*
* Creates a new string in a form intended to prefix a shell command, containing
* the appropriate name/values for this gpu. For example:
*
* __GLX_VENDOR_LIBRARY_NAME=nvidia __NV_PRIME_RENDER_OFFLOAD=1
*
* Returns: (transfer full): A new string, free with g_free().
*
* Since 2.6
*/
gchar *
xapp_gpu_info_get_shell_env_prefix(XAppGpuInfo *info)
{
g_return_val_if_fail (info != NULL, g_strdup (""));
if (info->env_strv == NULL)
{
return g_strdup ("");
}
g_return_val_if_fail (g_strv_length (info->env_strv) % 2 == 0, g_strdup (""));
GString *args = g_string_new (NULL);
for (gint i = 0; i < g_strv_length (info->env_strv); i++)
{
g_string_append_printf (args, "%s=", info->env_strv[i++]);
g_string_append_printf (args, "%s ", info->env_strv[i]);
}
DEBUG ("%s", args->str);
return g_string_free (args, FALSE);
}
struct _XAppGpuOffloadHelper
{
GObject parent_instance;
GCancellable *cancellable;
GDBusProxy *control;
guint num_gpus;
GMutex gpu_infos_mutex;
GList *gpu_infos; // XAppGpuInfos
gboolean ready;
gboolean ubuntu_offload_support_found;
};
G_DEFINE_TYPE (XAppGpuOffloadHelper, xapp_gpu_offload_helper, G_TYPE_OBJECT)
enum
{
READY,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = {0, };
static void
process_gpus_property (XAppGpuOffloadHelper *helper,
GError **error)
{
GVariant *gpus;
GList *infos = NULL;
gint num_children, i;
gboolean default_found = FALSE;
gpus = xapp_switcheroo_control_get_gpus (XAPP_SWITCHEROO_CONTROL (helper->control));
num_children = g_variant_n_children(gpus);
for (i = 0; i < num_children; i++)
{
g_autoptr(GVariant) gpu;
g_autoptr(GVariant) vname = NULL;
g_autoptr(GVariant) venv = NULL;
g_autoptr(GVariant) vdefault = NULL;
const char *name;
g_autofree const char **env_strv = NULL;
gsize env_len;
gboolean is_default;
gpu = g_variant_get_child_value (gpus, i);
if (!gpu || !g_variant_is_of_type (gpu, G_VARIANT_TYPE ("a{s*}")))
{
continue;
}
vname = g_variant_lookup_value (gpu, "Name", NULL);
venv = g_variant_lookup_value (gpu, "Environment", NULL);
vdefault= g_variant_lookup_value (gpu, "Default", NULL);
if (!vname || !venv)
continue;
name = g_variant_get_string (vname, NULL);
env_strv = g_variant_get_strv (venv, &env_len);
if (env_strv != NULL && env_len % 2 != 0)
{
g_autofree char *debug = NULL;
debug = g_strjoinv ("\n", (char **) env_strv);
g_warning ("Invalid environment returned from switcheroo:\n%s", debug);
g_clear_pointer (&env_strv, g_free);
continue;
}
is_default = vdefault ? g_variant_get_boolean (vdefault) : FALSE;
if (is_default)
{
default_found = TRUE;
}
XAppGpuInfo *info = g_new0 (XAppGpuInfo, 1);
info->id = i;
info->display_name = g_strdup (name);
info->env_strv = g_strdupv ((gchar **) env_strv);
info->is_default = is_default;
infos = g_list_append (infos, info);
}
if (infos == NULL)
{
*error = g_error_new (g_dbus_error_quark (),
G_DBUS_ERROR_FAILED,
"GPUs property didn't contain any valid gpu info.");
}
if (!default_found)
{
*error = g_error_new (g_dbus_error_quark (),
G_DBUS_ERROR_FAILED,
"No default GPU exists.");
g_list_free_full (infos, (GDestroyNotify) xapp_gpu_info_free);
infos = NULL;
}
g_mutex_lock (&helper->gpu_infos_mutex);
g_list_free_full (helper->gpu_infos, (GDestroyNotify) xapp_gpu_info_free);
helper->gpu_infos = infos;
helper->num_gpus = g_list_length (helper->gpu_infos);
g_mutex_unlock (&helper->gpu_infos_mutex);
}
static void
populate_gpu_info (XAppGpuOffloadHelper *helper,
GError **error)
{
GVariant *gpus;
g_auto(GStrv) cached_props = NULL;
cached_props = g_dbus_proxy_get_cached_property_names (helper->control);
if (cached_props != NULL && g_strv_contains ((const gchar * const *) cached_props, "GPUs"))
{
// (already cached)
DEBUG ("GPUs property already cached, skipping Get");
process_gpus_property (helper, error);
return;
}
gpus = g_dbus_connection_call_sync (g_dbus_proxy_get_connection (helper->control),
g_dbus_proxy_get_name (helper->control),
g_dbus_proxy_get_object_path (helper->control),
"org.freedesktop.DBus.Properties",
"Get",
g_variant_new ("(ss)",
g_dbus_proxy_get_interface_name (helper->control),
"GPUs"),
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
helper->cancellable,
error);
if (gpus == NULL)
{
return;
}
g_dbus_proxy_set_cached_property (helper->control, "(GPUs)", gpus);
process_gpus_property (helper, error);
}
static void
on_bus_connection_closed (GDBusConnection *connection,
gboolean remote_peer_vanished,
GError *error,
gpointer user_data)
{
XAppGpuOffloadHelper *helper = XAPP_GPU_OFFLOAD_HELPER (user_data);
if (error != NULL)
{
g_critical ("Bus connection unexpectedly lost: (%d) %s", error->code, error->message);
g_error_free (error);
}
g_object_unref (helper);
}
static void
helper_init_thread (GTask *task,
gpointer source_object,
gpointer task_data,
GCancellable *cancellable)
{
XAppGpuOffloadHelper *helper = XAPP_GPU_OFFLOAD_HELPER (source_object);
XAppSwitcherooControl *control;
GError *error = NULL;
control = xapp_switcheroo_control_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
"net.hadess.SwitcherooControl",
"/net/hadess/SwitcherooControl",
helper->cancellable,
&error);
if (error != NULL)
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
g_task_return_boolean (task, TRUE);
}
g_critical ("Could not create switcheroo proxy: (%d): %s", error->code, error->message);
g_task_return_error (task, error);
}
if (g_dbus_proxy_get_name_owner (G_DBUS_PROXY (control)) != NULL)
{
DEBUG ("Got switcheroo-control proxy successfully");
helper->control = G_DBUS_PROXY (control);
g_signal_connect (g_dbus_proxy_get_connection (helper->control), "closed", G_CALLBACK (on_bus_connection_closed), helper);
populate_gpu_info (helper, &error);
if (error != NULL)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
g_task_return_boolean (task, TRUE);
}
g_critical ("Could not get gpu info from switcheroo proxy: (%d): %s", error->code, error->message);
g_task_return_error (task, error);
}
}
else
{
g_warning ("Switcheroo-control doesn't appear to be running, checking for Ubuntu support...");
// Add a default GPU no matter what just so we're 'valid'
XAppGpuInfo *info;
GList *infos = NULL;
info = g_new0 (XAppGpuInfo, 1);
info->id = 0;
info->is_default = TRUE;
info->display_name = g_strdup ("Integrated GPU");
infos = g_list_append (infos, info);
// If there's support, make up a default and non-default XAppGpuInfo.
if (xapp_util_gpu_offload_supported ())
{
info = g_new0 (XAppGpuInfo, 1);
info->id = 1;
info->is_default = FALSE;
info->display_name = g_strdup ("NVIDIA GPU");
info->env_strv = g_strdupv ((gchar **) DEFAULT_ENV_ARGV);
infos = g_list_append (infos, info);
}
g_mutex_lock (&helper->gpu_infos_mutex);
g_list_free_full (helper->gpu_infos, (GDestroyNotify) xapp_gpu_info_free);
helper->gpu_infos = infos;
helper->num_gpus = g_list_length (helper->gpu_infos);
g_mutex_unlock (&helper->gpu_infos_mutex);
}
g_task_return_boolean (task, TRUE);
}
static void
helper_task_callback (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
XAppGpuOffloadHelper *helper = XAPP_GPU_OFFLOAD_HELPER (source_object);
// Todo with an error? This callback is only used in async mode.
gboolean success = g_task_propagate_boolean (G_TASK (res), NULL);
if (success)
{
helper->ready = TRUE;
if (DEBUGGING)
{
DEBUG ("Gpu infos:");
for (GList *l = helper->gpu_infos; l != NULL; l = l->next)
{
XAppGpuInfo *info = l->data;
gchar *shell_str = xapp_gpu_info_get_shell_env_prefix (info);
gchar *debug = g_strdup_printf ("%s: %s", info->display_name, shell_str);
DEBUG ("%s", debug);
g_free (shell_str);
g_free (debug);
}
}
}
g_signal_emit (helper, signals[READY], 0, helper->ready);
}
static void
init_helper (XAppGpuOffloadHelper *helper,
gboolean synchronous)
{
GTask *task = g_task_new (helper, helper->cancellable, helper_task_callback, NULL);
if (synchronous)
{
g_task_run_in_thread_sync (task, helper_init_thread);
helper_task_callback (G_OBJECT (helper), G_ASYNC_RESULT (task), NULL);
}
else
{
g_task_run_in_thread (task, helper_init_thread);
}
g_object_unref (task);
}
static void
xapp_gpu_offload_helper_init (XAppGpuOffloadHelper *helper)
{
helper->cancellable = g_cancellable_new ();
g_mutex_init (&helper->gpu_infos_mutex);
}
static void
xapp_gpu_offload_helper_dispose (GObject *object)
{
XAppGpuOffloadHelper *helper = XAPP_GPU_OFFLOAD_HELPER (object);
if (helper->gpu_infos != NULL)
{
g_list_free_full (helper->gpu_infos, (GDestroyNotify) xapp_gpu_info_free);
helper->gpu_infos = NULL;
}
g_clear_object (&helper->cancellable);
g_clear_object (&helper->control);
helper->ready = FALSE;
G_OBJECT_CLASS (xapp_gpu_offload_helper_parent_class)->dispose (object);
}
static void
xapp_gpu_offload_helper_class_init (XAppGpuOffloadHelperClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = xapp_gpu_offload_helper_dispose;
/**
* XAppGpuOffloadHelper::ready:
* @helper: the #XAppGpuOffloadHelper
* @success: Whether or not the helper initialize successfully.
*
* This signal is emitted by the helper when it has completed
* gathering GPU information. It will only be sent once.
*/
signals[READY] =
g_signal_new ("ready",
XAPP_TYPE_GPU_OFFLOAD_HELPER,
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
}
static gboolean
idle_init_helper (gpointer user_data)
{
XAppGpuOffloadHelper *helper = XAPP_GPU_OFFLOAD_HELPER (user_data);
init_helper (helper, FALSE);
return G_SOURCE_REMOVE;
}
static XAppGpuOffloadHelper *
helper_get_common (gboolean synchronous)
{
static XAppGpuOffloadHelper *gpu_offload_helper = NULL;
static gsize once_init_value = 0;
if (g_once_init_enter (&once_init_value))
{
gpu_offload_helper = g_object_new (XAPP_TYPE_GPU_OFFLOAD_HELPER, NULL);
if (synchronous)
{
DEBUG ("Initializing helper synchronously.");
init_helper (gpu_offload_helper, TRUE);
}
else
{
DEBUG ("Initializing helper asynchronously");
g_idle_add ((GSourceFunc) idle_init_helper, gpu_offload_helper);
}
g_once_init_leave (&once_init_value, 1);
}
return gpu_offload_helper;
}
/**
* xapp_gpu_offload_helper_get:
*
* Creates a new #XAppGpuOffloadHelper instance.
*
* The #XAppGpuOffloadHelper::ready signal will be emitted when the helper is initialized (successfully or not).
*
* Returns: (transfer none): a new #XAppGpuOffloadHelper.
*
* Since: 2.6
*/
XAppGpuOffloadHelper *
xapp_gpu_offload_helper_get (void)
{
return helper_get_common (FALSE);
}
/**
* xapp_gpu_offload_helper_get_sync:
*
* Creates a new #XAppGpuOffloadHelper instance. This performs initialization synchronously,
* and can potentially block.
*
* Use xapp_gpu_offload_helper_is_ready() to see if the helper was initialized successfully.
*
* Returns: (transfer none): a new #XAppGpuOffloadHelper, fully initialized.
*
* Since: 2.6
*/
XAppGpuOffloadHelper *
xapp_gpu_offload_helper_get_sync (void)
{
return helper_get_common (TRUE);
}
static void
warn_if_not_ready (XAppGpuOffloadHelper *helper)
{
if (!helper->ready)
{
g_warning ("Helper not initialized or failed to do so.");
}
}
/**
* xapp_gpu_offload_helper_is_ready:
* @helper: The #XAppGpuOffloadHelper.
*
* Checks if the helper is ready and valid. This does not mean
* offload support exists.
*
* Returns: %TRUE if the helper has been successfully initialized.
*
* Since: 2.6
*/
gboolean
xapp_gpu_offload_helper_is_ready (XAppGpuOffloadHelper *helper)
{
g_return_val_if_fail (XAPP_IS_GPU_OFFLOAD_HELPER (helper), 1);
return helper->ready;
}
/**
* xapp_gpu_offload_helper_is_offload_supported:
* @helper: The #XAppGpuOffloadHelper.
*
* Checks if there is a non-default GPU available for offloading.
*
* Returns: %TRUE if there is an extra GPU available.
*
* Since: 2.6
*/
gboolean
xapp_gpu_offload_helper_is_offload_supported (XAppGpuOffloadHelper *helper)
{
g_return_val_if_fail (XAPP_IS_GPU_OFFLOAD_HELPER (helper), 1);
return helper->num_gpus > 1;
}
/**
* xapp_gpu_offload_helper_get_n_gpus:
* @helper: The #XAppGpuOffloadHelper.
*
* Gets the number of GPUs noticed by Switcheroo.
*
* Returns: the total number of GPUs. A return value larger than
* 1 implies there are offloadable GPUs available.
*
* Since: 2.6
*/
gint
xapp_gpu_offload_helper_get_n_gpus (XAppGpuOffloadHelper *helper)
{
g_return_val_if_fail (XAPP_IS_GPU_OFFLOAD_HELPER (helper), 1);
warn_if_not_ready (helper);
return helper->num_gpus;
}
/**
* xapp_gpu_offload_helper_get_offload_infos:
* @helper: The #XAppGpuOffloadHelper.
*
* Generates a list of #XAppGpuInfos that can be offloaded to, if there are any.
*
* Returns: (element-type XAppGpuInfo) (transfer container): a list of #XAppGpuInfos or %NULL if there is only
* a single GPU. The elements are owned by @helper but the container itself should be freed.
*
* Since: 2.6
*/
GList *
xapp_gpu_offload_helper_get_offload_infos (XAppGpuOffloadHelper *helper)
{
g_return_val_if_fail (XAPP_IS_GPU_OFFLOAD_HELPER (helper), NULL);
warn_if_not_ready (helper);
GList *retval = NULL;
GList *l;
for (l = helper->gpu_infos; l != NULL; l = l->next)
{
XAppGpuInfo *info = l->data;
if (info->is_default)
continue;
retval = g_list_append (retval, info);
}
return retval;
}
/**
* xapp_gpu_offload_helper_get_default_info:
* @helper: The #XAppGpuOffloadHelper.
*
* Returns an #XAppGpuInfo for the default GPU.
*
* Returns: (transfer none): the default #XAppGpuInfo. Do not free
*
* Since: 2.6
*/
XAppGpuInfo *
xapp_gpu_offload_helper_get_default_info (XAppGpuOffloadHelper *helper)
{
g_return_val_if_fail (XAPP_IS_GPU_OFFLOAD_HELPER (helper), NULL);
warn_if_not_ready (helper);
GList *l;
for (l = helper->gpu_infos; l != NULL; l = l->next)
{
XAppGpuInfo *info = l->data;
if (info->is_default)
return info;
}
g_warning ("No default GPU found by switcheroo!");
return NULL;
}
/**
* xapp_gpu_offload_helper_get_info_by_id:
* @helper: The #XAppGpuOffloadHelper.
* @id: The ID of the info to retrieve.
*
* Returns an #XAppGpuInfo with the given ID.
*
* Returns: (transfer none): the appropriate #XAppGpuInfo, or %NULL if @id was invalid.
*
* Since: 2.6
*/
XAppGpuInfo *
xapp_gpu_offload_helper_get_info_by_id (XAppGpuOffloadHelper *helper, gint id)
{
g_return_val_if_fail (XAPP_IS_GPU_OFFLOAD_HELPER (helper), NULL);
warn_if_not_ready (helper);
GList *l;
for (l = helper->gpu_infos; l != NULL; l = l->next)
{
XAppGpuInfo *info = l->data;
if (info->id == id)
return info;
}
g_warning ("No GPU with id %d found.", id);
return NULL;
}
xapp-2.8.2/libxapp/xapp-gtk3-module.c 0000664 0001750 0001750 00000013747 14545562517 016355 0 ustar fabio fabio #include
#include
#include "xapp-favorites.h"
#include "favorite-vfs-file.h"
#define DEBUG_FLAG XAPP_DEBUG_MODULE
#include "xapp-debug.h"
#define ICON_OVERRIDE_VAR "XAPP_FORCE_GTKWINDOW_ICON"
/* xapp-gtk3-module:
*
* - Initializes the favorites:// vfs and adds a Favorites shortcut
* to any gtk3 sidebars (like in file dialogs).
*
* - Overrides the window icon for any GtkWindows when an environment
* variable is set with an icon path or name.
*/
void gtk_module_init (gint *argc, gchar ***argv[]);
static void (* original_sidebar_constructed) (GObject *object);
static void (* original_window_realize) (GtkWidget *widget);
static void (* original_window_unrealize) (GtkWidget *widget);
static void
on_sidebar_realized (GtkWidget *widget, gpointer data)
{
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (widget);
GSettings *fav_settings;
gchar **list;
// This is better than initializing favorites to count.
// That way if there aren't any favorites, fav_settings
// will go away. XAppFavorites is a singleton.
fav_settings = g_settings_new ("org.x.apps.favorites");
list = g_settings_get_strv (fav_settings, "list");
if (g_strv_length (list) > 0)
{
GFile *favorites = g_file_new_for_uri ("favorites:///");
gtk_places_sidebar_add_shortcut (sidebar, favorites);
g_object_unref (favorites);
}
g_strfreev (list);
g_object_unref (fav_settings);
g_signal_handlers_disconnect_by_func (widget, on_sidebar_realized, NULL);
}
static void
xapp_sidebar_constructed (GObject *object)
{
(* original_sidebar_constructed) (object);
g_signal_connect (object, "realize", G_CALLBACK (on_sidebar_realized), NULL);
}
static void
window_icon_changed (GtkWindow *window)
{
const gchar *forced_icon_str;
gpointer anti_recursion_ptr;
forced_icon_str = g_object_get_data (G_OBJECT (window), "xapp-forced-window-icon");
anti_recursion_ptr = g_object_get_data (G_OBJECT (window), "xapp-forced-icon-last-icon-ptr");
if (anti_recursion_ptr && anti_recursion_ptr == gtk_window_get_icon (window))
{
DEBUG ("Window icon notify received, but anti-recurse pointer hasn't changed, returning.");
return;
}
if (forced_icon_str != NULL)
{
gboolean clear_pixbuf = FALSE;
DEBUG ("Window icon changed, forcing back to '%s'", forced_icon_str);
g_signal_handlers_block_by_func (G_OBJECT (window), window_icon_changed, window);
if (g_path_is_absolute (forced_icon_str))
{
gtk_window_set_icon_name (window, NULL);
gtk_window_set_icon_from_file (window, forced_icon_str, NULL);
}
else
{
gtk_window_set_icon (window, NULL);
gtk_window_set_icon_name (window, forced_icon_str);
clear_pixbuf = TRUE;
}
g_object_set_data_full (G_OBJECT (window),
"xapp-forced-icon-last-icon-ptr",
clear_pixbuf ? NULL : g_object_ref (gtk_window_get_icon (window)),
g_object_unref);
g_signal_handlers_unblock_by_func (G_OBJECT (window), window_icon_changed, window);
}
}
static void
overridden_window_realize (GtkWidget *widget)
{
(* original_window_realize) (widget);
if (g_object_get_data (G_OBJECT (widget), "xapp-module-window-seen"))
{
return;
}
g_object_set_data (G_OBJECT (widget), "xapp-module-window-seen", GINT_TO_POINTER (1));
DEBUG ("Realize overridden window (%p).", widget);
const gchar *env_icon = g_getenv (ICON_OVERRIDE_VAR);
if (env_icon != NULL)
{
g_object_set_data_full (G_OBJECT (widget), "xapp-forced-window-icon", g_strdup (env_icon), g_free);
window_icon_changed (GTK_WINDOW (widget));
g_signal_connect_swapped (widget, "notify::icon", G_CALLBACK (window_icon_changed), widget);
g_signal_connect_swapped (widget, "notify::icon-name", G_CALLBACK (window_icon_changed), widget);
}
}
static void
overridden_window_unrealize (GtkWidget *widget)
{
(* original_window_unrealize) (widget);
DEBUG ("Unrealize overridden window (%p).", widget);
g_signal_handlers_disconnect_by_func (widget, window_icon_changed, widget);
}
static void
apply_window_icon_override (void)
{
static gboolean applied = 0;
// I don't think these guards are necessary. This should only run once, but better off safe.
if (!applied)
{
DEBUG ("XAPP_FORCE_GTKWINDOW_ICON found in environment, overriding the window icon with its contents");
applied = TRUE;
GtkWidgetClass *widget_class;
widget_class = g_type_class_ref (GTK_TYPE_WINDOW);
original_window_realize = widget_class->realize;
widget_class->realize = overridden_window_realize;
original_window_unrealize = widget_class->unrealize;
widget_class->unrealize = overridden_window_unrealize;
}
}
static void
apply_sidebar_favorites_override (void)
{
static gboolean applied = 0;
if (!applied)
{
DEBUG ("Adding a Favorites shortcut to GtkPlacesSideBars");
applied = TRUE;
GObjectClass *object_class;
object_class = g_type_class_ref (GTK_TYPE_PLACES_SIDEBAR);
original_sidebar_constructed = object_class->constructed;
object_class->constructed = xapp_sidebar_constructed;
}
}
G_MODULE_EXPORT void gtk_module_init (gint *argc, gchar ***argv[]) {
DEBUG ("Initializing XApp GtkModule");
// This won't instantiate XAppFavorites but will register the uri so
// it can be used by apps (like pix which doesn't use the favorites api,
// but just adds favorites:/// to its sidebar.)
init_favorite_vfs ();
apply_sidebar_favorites_override ();
if (g_getenv (ICON_OVERRIDE_VAR) != NULL)
{
apply_window_icon_override ();
}
}
G_MODULE_EXPORT gchar* g_module_check_init (GModule *module);
G_MODULE_EXPORT gchar* g_module_check_init (GModule *module) {
g_module_make_resident(module);
return NULL;
}
xapp-2.8.2/libxapp/favorite-vfs-file.h 0000664 0001750 0001750 00000001657 14545562517 016606 0 ustar fabio fabio #ifndef FAVORITE_VFS_FILE_H
#define FAVORITE_VFS_FILE_H
#include "xapp-favorites.h"
#include
#include
G_BEGIN_DECLS
#define FAVORITE_TYPE_VFS_FILE (favorite_vfs_file_get_type ())
G_DECLARE_FINAL_TYPE (FavoriteVfsFile, favorite_vfs_file, \
FAVORITE, VFS_FILE, GObject)
// Initializer for favorites:/// - called when the XAppFavorites singleton is created
void init_favorite_vfs (void);
GFile *favorite_vfs_file_new_for_uri (const char *uri);
gchar *favorite_vfs_file_get_real_uri (GFile *file);
#define URI_SCHEME "favorites"
#define ROOT_URI ("favorites:///")
#define FAVORITE_METADATA_KEY "metadata::xapp-favorite"
#define FAVORITE_AVAILABLE_METADATA_KEY "metadata::xapp-favorite-available"
#define META_TRUE "true"
#define META_FALSE "false"
gchar *path_to_fav_uri (const gchar *path);
gchar *fav_uri_to_display_name (const gchar *uri);
G_END_DECLS
#endif // FAVORITE_VFS_FILE_H
xapp-2.8.2/libxapp/favorite-vfs-file-monitor.h 0000664 0001750 0001750 00000000736 14545562517 020270 0 ustar fabio fabio #ifndef __FAVORITE_VFS_FILE_MONITOR_H__
#define __FAVORITE_VFS_FILE_MONITOR_H__
#include
#include
G_BEGIN_DECLS
#define FAVORITE_TYPE_VFS_FILE_MONITOR (favorite_vfs_file_monitor_get_type ())
G_DECLARE_FINAL_TYPE (FavoriteVfsFileMonitor, favorite_vfs_file_monitor,
FAVORITE, VFS_FILE_MONITOR, GFileMonitor)
GFileMonitor *favorite_vfs_file_monitor_new (void);
G_END_DECLS
#endif /* __FAVORITE_VFS_FILE_MONITOR_H__ */
xapp-2.8.2/libxapp/xapp-gtk-window.c 0000664 0001750 0001750 00000056621 14545562517 016312 0 ustar fabio fabio
#include
#include
#include
#include
#include
#include
#include
#include
#include "xapp-gtk-window.h"
#define DEBUG_FLAG XAPP_DEBUG_WINDOW
#include "xapp-debug.h"
#define ICON_NAME_HINT "_NET_WM_XAPP_ICON_NAME"
#define PROGRESS_HINT "_NET_WM_XAPP_PROGRESS"
#define PROGRESS_PULSE_HINT "_NET_WM_XAPP_PROGRESS_PULSE"
/**
* SECTION:xapp-gtk-window
* @Short_description: A subclass of %GtkWindow that allows additional
communication with the window manager.
* @Title: XAppGtkWindow
*
* This widget is a simple subclass of GtkWindow that provides the following
* additional capabilities:
*
* - Ability to set an icon name or icon file path for the window manager to
* make use of, rather than relying on a desktop file or fixed-size window-
* backed icon that Gtk normally generates. The window manager must support
* the NET_WM_XAPP_ICON_NAME hint.
*
* - Ability to send progress info to the window manager, in the form of an integer,
* 0-100, which can then be used to display this progress in some manner in a task
* manager or window list. The window manager must support the NET_WM_XAPP_PROGRESS
* hint.
*
* - Ability to signal a 'pulsing' progress state, of potentially indeterminate value,
* in the form of a boolean, which can be passed on to a window list. The window
* manager must support the NET_WM_XAPP_PROGRESS_PULSE hint
*
* Wrappers:
*
* Also provided are corresponding wrapper functions for normal GtkWindows.
* They are not class methods - they are called with the target widget as their first
* argument.
*
* For example:
*
* win = Gtk.Window()
* XApp.set_window_icon_name(win, "foobar")
*
* These functions mirror those of the #XAppGtkWindow class, but allow the properties
* to work with normal GtkWindows and descendants of GtkWindow.
*/
typedef struct
{
gchar *icon_name;
gchar *icon_path;
guint progress;
gboolean progress_pulse;
} XAppGtkWindowPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (XAppGtkWindow, xapp_gtk_window, GTK_TYPE_WINDOW)
static gboolean
is_x11_session (void)
{
static gboolean running_x11 = FALSE;
static gsize once_init_value = 0;
if (g_once_init_enter (&once_init_value))
{
running_x11 = GDK_IS_X11_DISPLAY(gdk_display_get_default());
DEBUG ("XAppGtkWindow: is_x11_session: %s\n", running_x11 ? "TRUE" : "FALSE");
g_once_init_leave (&once_init_value, 1);
}
return running_x11;
}
static void
clear_icon_strings (XAppGtkWindowPrivate *priv)
{
g_clear_pointer (&priv->icon_name, g_free);
g_clear_pointer (&priv->icon_path, g_free);
}
static void
set_window_hint_utf8 (Window xid,
const gchar *atom_name,
const gchar *str)
{
GdkDisplay *display;
display = gdk_display_get_default ();
if (str != NULL)
{
XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
xid,
gdk_x11_get_xatom_by_name_for_display (display, atom_name),
gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
PropModeReplace, (guchar *) str, strlen (str));
}
else
{
XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
xid,
gdk_x11_get_xatom_by_name_for_display (display, atom_name));
}
}
static void
set_window_hint_cardinal (Window xid,
const gchar *atom_name,
gulong cardinal)
{
GdkDisplay *display;
display = gdk_display_get_default ();
gdk_error_trap_push ();
if (cardinal > 0)
{
XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
xid,
gdk_x11_get_xatom_by_name_for_display (display, atom_name),
XA_CARDINAL, 32,
PropModeReplace,
(guchar *) &cardinal, 1);
}
else
{
XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
xid,
gdk_x11_get_xatom_by_name_for_display (display, atom_name));
}
gdk_error_trap_pop_ignored ();
}
static Window
get_window_xid (GtkWindow *window)
{
GdkWindow *gdk_window;
gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
if (gdk_window_get_effective_toplevel (gdk_window) != gdk_window)
{
g_warning ("Window is not toplevel");
return 0;
}
return GDK_WINDOW_XID (gdk_window);
}
static void
update_window_icon (GtkWindow *window,
XAppGtkWindowPrivate *priv)
{
if (!is_x11_session ()) {
return;
}
/* Icon name/path */
if (priv->icon_name != NULL)
{
set_window_hint_utf8 (get_window_xid (window),
ICON_NAME_HINT,
priv->icon_name);
}
else if (priv->icon_path != NULL)
{
set_window_hint_utf8 (get_window_xid (window),
ICON_NAME_HINT,
priv->icon_path);
}
else
{
set_window_hint_utf8 (get_window_xid (window),
ICON_NAME_HINT,
NULL);
}
}
static void
update_window_progress (GtkWindow *window,
XAppGtkWindowPrivate *priv)
{
if (!is_x11_session ()) {
return;
}
/* Progress: 0 - 100 */
set_window_hint_cardinal (get_window_xid (window),
PROGRESS_HINT,
(gulong) priv->progress);
set_window_hint_cardinal (get_window_xid (window),
PROGRESS_PULSE_HINT,
(gulong) (priv->progress_pulse ? 1 : 0));
}
static void
set_icon_name_internal (GtkWindow *window,
XAppGtkWindowPrivate *priv,
const gchar *icon_name)
{
if (g_strcmp0 (icon_name, priv->icon_name) == 0)
{
gtk_window_set_icon_name (window, icon_name);
return;
}
/* Clear both strings when either is set - this ensures the
* correct value is set during update_window() */
clear_icon_strings (priv);
if (icon_name != NULL)
{
priv->icon_name = g_strdup (icon_name);
}
/* If the window is realized, set the icon name immediately.
* If it's not, it will be set by xapp_gtk_window_realize(). */
if (gtk_widget_get_realized (GTK_WIDGET (window)))
{
update_window_icon (window, priv);
}
/* Call the GtkWindow method for compatibility */
gtk_window_set_icon_name (GTK_WINDOW (window), icon_name);
}
static void
set_icon_from_file_internal (GtkWindow *window,
XAppGtkWindowPrivate *priv,
const gchar *file_name,
GError **error)
{
if (g_strcmp0 (file_name, priv->icon_path) == 0)
{
gtk_window_set_icon_from_file (window, file_name, error);
return;
}
/* Clear both strings when either is set - this ensures the correct
* value is set during update_window() */
clear_icon_strings (priv);
if (file_name != NULL)
{
priv->icon_path = g_strdup (file_name);
}
/* If the window is realized, set the icon path immediately.
* If it's not, it will be set by xapp_gtk_window_realize(). */
if (gtk_widget_get_realized (GTK_WIDGET (window)))
{
update_window_icon (window, priv);
}
gtk_window_set_icon_from_file (GTK_WINDOW (window), file_name, error);
}
static void
set_progress_internal (GtkWindow *window,
XAppGtkWindowPrivate *priv,
gint progress)
{
gboolean update;
guint clamped_progress;
update = FALSE;
if (priv->progress_pulse)
{
priv->progress_pulse = FALSE;
update = TRUE;
}
clamped_progress = CLAMP (progress, 0, 100);
if (clamped_progress != priv->progress)
{
priv->progress = clamped_progress;
update = TRUE;
}
/* If the window is realized, set the progress immediately.
* If it's not, it will be set by xapp_gtk_window_realize(). */
if (gtk_widget_get_realized (GTK_WIDGET (window)))
{
if (update)
{
update_window_progress (window, priv);
}
}
}
static void
set_progress_pulse_internal (GtkWindow *window,
XAppGtkWindowPrivate *priv,
gboolean pulse)
{
gboolean update;
update = FALSE;
if (priv->progress_pulse != pulse)
{
priv->progress_pulse = pulse;
update = TRUE;
}
/* If the window is realized, set the progress immediately.
* If it's not, it will be set by xapp_gtk_window_realize(). */
if (gtk_widget_get_realized (GTK_WIDGET (window)))
{
if (update)
{
update_window_progress (window, priv);
}
}
}
static void
xapp_gtk_window_realize (GtkWidget *widget)
{
XAppGtkWindow *window = XAPP_GTK_WINDOW (widget);
XAppGtkWindowPrivate *priv = xapp_gtk_window_get_instance_private (window);
GTK_WIDGET_CLASS (xapp_gtk_window_parent_class)->realize (widget);
update_window_icon (GTK_WINDOW (window), priv);
update_window_progress (GTK_WINDOW (window), priv);
}
static void
xapp_gtk_window_unrealize (GtkWidget *widget)
{
GTK_WIDGET_CLASS (xapp_gtk_window_parent_class)->unrealize (widget);
}
static void
xapp_gtk_window_finalize (GObject *object)
{
XAppGtkWindow *window = XAPP_GTK_WINDOW (object);
XAppGtkWindowPrivate *priv = xapp_gtk_window_get_instance_private (window);
clear_icon_strings (priv);
G_OBJECT_CLASS (xapp_gtk_window_parent_class)->finalize (object);
}
static void
xapp_gtk_window_init (XAppGtkWindow *window)
{
XAppGtkWindowPrivate *priv;
priv = xapp_gtk_window_get_instance_private (window);
priv->icon_name = NULL;
priv->icon_path = NULL;
}
static void
xapp_gtk_window_class_init (XAppGtkWindowClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass);
gobject_class->finalize = xapp_gtk_window_finalize;
wclass->realize = xapp_gtk_window_realize;
wclass->unrealize = xapp_gtk_window_unrealize;
}
/**
* xapp_gtk_window_new:
* @type: The #GtkWindowType to use
*
* Creates a new #XAppGtkWindow of type @type. See gtk_window_new()
* for more details.
*
* Returns: A new #XAppGtkWindow (transfer: full)
*/
GtkWidget *
xapp_gtk_window_new (GtkWindowType type)
{
return g_object_new (XAPP_TYPE_GTK_WINDOW, "type", type, NULL);
}
/**
* xapp_gtk_window_set_icon_name:
* @window: The #XAppGtkWindow to set the icon name for
* @icon_name: (nullable): The icon name or path to set, or %NULL to unset.
*
* Sets the icon name hint for a window manager (like muffin) to make
* available when applications want to change their icons during runtime
* without having to resort to the internal low-res pixbufs that GdkWindow
* sets on the client side. This also chains up and calls GtkWindow.set_icon_name
* for convenience and compatibility. Set to %NULL to unset.
*/
void
xapp_gtk_window_set_icon_name (XAppGtkWindow *window,
const gchar *icon_name)
{
g_return_if_fail (XAPP_IS_GTK_WINDOW (window));
XAppGtkWindowPrivate *priv = xapp_gtk_window_get_instance_private (window);
set_icon_name_internal (GTK_WINDOW (window), priv, icon_name);
}
/**
* xapp_gtk_window_set_icon_from_file:
* @window: The #XAppGtkWindow to set the icon name for
* @file_name: (nullable): The icon path to set, or %NULL to unset.
* @error: (nullable): An error to set if something goes wrong.
*
* Sets the icon name hint for a window manager (like muffin) to make
* available when applications want to change their icons during runtime
* without having to resort to the internal low-res pixbufs that GdkWindow
* sets on the client side. This also chains up and calls GtkWindow.set_icon_from_file
* for convenience and compatibility. Set to %NULL to unset.
*/
void
xapp_gtk_window_set_icon_from_file (XAppGtkWindow *window,
const gchar *file_name,
GError **error)
{
g_return_if_fail (XAPP_IS_GTK_WINDOW (window));
XAppGtkWindowPrivate *priv = xapp_gtk_window_get_instance_private (window);
set_icon_from_file_internal (GTK_WINDOW (window), priv, file_name, error);
}
/**
* xapp_gtk_window_set_progress:
* @window: The #XAppGtkWindow to set the progress for
* @progress: The value to set for progress.
*
* Sets the progress hint for a window manager (like muffin) to make
* available when applications want to display the application's progress
* in some operation. The value sent to the WM will be clamped to
* between 0 and 100.
*
* Note: If a window will stick around after progress is complete, you will
* probaby need to set progress to 0 to remove any progress effects on taskbars
* and window lists.
*
* Setting progress will also cancel the 'pulsing' flag on the window as
* well, if it has been set.
*/
void
xapp_gtk_window_set_progress (XAppGtkWindow *window,
gint progress)
{
g_return_if_fail (XAPP_IS_GTK_WINDOW (window));
XAppGtkWindowPrivate *priv = xapp_gtk_window_get_instance_private (window);
set_progress_internal (GTK_WINDOW (window), priv, progress);
}
/**
* xapp_gtk_window_set_progress_pulse:
* @window: The #XAppGtkWindow to set the progress for
* @pulse: Whether to have pulsing set or not.
*
* Sets the progress pulse hint hint for a window manager (like muffin)
* to make available when applications want to display indeterminate or
* ongoing progress in a task manager.
*
* Note: If a window will stick around after progress is complete, you will
* probaby need to set progress to 0 to remove any progress effects on taskbars
* and window lists. This will also remove the pulse state, if it is set.
*
* Setting an explicit progress value will unset this flag.
*/
void
xapp_gtk_window_set_progress_pulse (XAppGtkWindow *window,
gboolean pulse)
{
g_return_if_fail (XAPP_IS_GTK_WINDOW (window));
XAppGtkWindowPrivate *priv = xapp_gtk_window_get_instance_private (window);
set_progress_pulse_internal (GTK_WINDOW (window), priv, pulse);
}
/* Wrappers (for GtkWindow subclasses like GtkDialog)
* window must be a GtkWindow or descendant */
static void
on_gtk_window_realized (GtkWidget *widget,
gpointer user_data)
{
XAppGtkWindowPrivate *priv;
priv = (XAppGtkWindowPrivate *) user_data;
update_window_icon (GTK_WINDOW (widget), priv);
update_window_progress (GTK_WINDOW (widget), priv);
}
static void
destroy_xapp_struct (gpointer user_data)
{
XAppGtkWindowPrivate *priv = (XAppGtkWindowPrivate *) user_data;
g_clear_pointer (&priv->icon_name, g_free);
g_clear_pointer (&priv->icon_path, g_free);
g_slice_free (XAppGtkWindowPrivate, priv);
}
static XAppGtkWindowPrivate *
get_xapp_struct (GtkWindow *window)
{
XAppGtkWindowPrivate *priv;
priv = g_object_get_data (G_OBJECT (window),
"xapp-window-struct");
if (priv)
{
return priv;
}
priv = g_slice_new0 (XAppGtkWindowPrivate);
g_object_set_data_full (G_OBJECT (window),
"xapp-window-struct",
priv,
(GDestroyNotify) destroy_xapp_struct);
g_signal_connect_after (GTK_WIDGET (window),
"realize",
G_CALLBACK (on_gtk_window_realized),
priv);
return priv;
}
/**
* xapp_set_window_icon_name:
* @window: The #GtkWindow to set the icon name for
* @icon_name: (nullable): The icon name to set, or %NULL to unset.
*
* Sets the icon name hint for a window manager (like muffin) to make
* available when applications want to change their icons during runtime
* without having to resort to the internal low-res pixbufs that GdkWindow
* sets on the client side. This is a function, not a method, for taking
* advantage of this feature with descendants of GtkWindows, such as
* GtkDialogs. Sets gtk_window_set_icon_name as well, to avoid needing
* to have two calls each time. Set to %NULL to unset.
*/
void
xapp_set_window_icon_name (GtkWindow *window,
const gchar *icon_name)
{
XAppGtkWindowPrivate *priv;
g_return_if_fail (GTK_IS_WINDOW (window));
priv = get_xapp_struct (window);
if (XAPP_IS_GTK_WINDOW (window))
{
g_warning("Window is an instance of XAppGtkWindow. Use the instance set_icon_name method instead.");
}
set_icon_name_internal (window, priv, icon_name);
}
/**
* xapp_set_window_icon_from_file:
* @window: The #GtkWindow to set the icon name for
* @file_name: (nullable): The icon path to set, or %NULL to unset.
* @error: (nullable): An error to set if something goes wrong.
*
* Sets the icon name hint for a window manager (like muffin) to make
* available when applications want to change their icons during runtime
* without having to resort to the internal low-res pixbufs that GdkWindow
* sets on the client side. This also chains up and calls GtkWindow.set_icon_from_file
* for convenience and compatibility. Set to %NULL to unset.
*/
void
xapp_set_window_icon_from_file (GtkWindow *window,
const gchar *file_name,
GError **error)
{
XAppGtkWindowPrivate *priv;
g_return_if_fail (GTK_IS_WINDOW (window));
priv = get_xapp_struct (window);
if (XAPP_IS_GTK_WINDOW (window))
{
g_warning("Window is an instance of XAppGtkWindow. Use the instance set_icon_from_file method instead.");
}
set_icon_from_file_internal (window, priv, file_name, error);
}
/**
* xapp_set_window_progress:
* @window: The #GtkWindow to set the progress for
* @progress: The value to set for progress.
*
* Sets the progress hint for a window manager (like muffin) to make
* available when applications want to display the application's progress
* in some operation. The value sent to the WM will be clamped to
* between 0 and 100.
*
* Note: If a window will stick around after progress is complete, you will
* probaby need to set progress to 0 to remove any progress effects on taskbars
* and window lists.
*
* Setting progress will also cancel the 'pulsing' flag on the window as
* well, if it has been set.
*/
void
xapp_set_window_progress (GtkWindow *window,
gint progress)
{
XAppGtkWindowPrivate *priv;
g_return_if_fail (GTK_IS_WINDOW (window));
priv = get_xapp_struct (window);
if (XAPP_IS_GTK_WINDOW (window))
{
g_warning("Window is an instance of XAppGtkWindow. Use the instance set_progress method instead.");
}
set_progress_internal (window, priv, progress);
}
/**
* xapp_set_window_progress_pulse:
* @window: The #GtkWindow to set the progress for
* @pulse: Whether to have pulsing set or not.
*
* Sets the progress pulse hint hint for a window manager (like muffin)
* to make available when applications want to display indeterminate or
* ongoing progress in a task manager.
*
* Note: If a window will stick around after progress is complete, you will
* probaby need to set progress to 0 to remove any progress effects on taskbars
* and window lists. This will also remove the pulse state, if it is set.
*
* Setting an explicit progress value will unset this flag.
*/
void
xapp_set_window_progress_pulse (GtkWindow *window,
gboolean pulse)
{
XAppGtkWindowPrivate *priv;
g_return_if_fail (GTK_IS_WINDOW (window));
priv = get_xapp_struct (window);
if (XAPP_IS_GTK_WINDOW (window))
{
g_warning("Window is an instance of XAppGtkWindow. Use the instance set_progress_pulse method instead.");
}
set_progress_pulse_internal (GTK_WINDOW (window), priv, pulse);
}
/**
* xapp_set_xid_icon_name:
* @xid: The Window to set the icon name for
* @icon_name: (nullable): The icon name to set, or %NULL to unset.
*
* Sets the icon name hint for a window manager (like muffin) to make
* available when applications want to change their icons during runtime
* without having to resort to the internal low-res pixbufs that GdkWindow
* sets on the client side. This is a function, not a method, for applying
* the icon name property for a given (possibly foreign) window, by passing
* the window's XID. Set to %NULL to unset.
*/
void
xapp_set_xid_icon_name (gulong xid,
const gchar *icon_name)
{
g_return_if_fail (xid > 0);
set_window_hint_utf8 (xid, ICON_NAME_HINT, icon_name);
}
/**
* xapp_set_xid_icon_from_file:
* @xid: The Window to set the icon name for
* @file_name: (nullable): The icon path to set, or %NULL to unset.
*
* Sets the icon name hint for a window manager (like muffin) to make
* available when applications want to change their icons during runtime
* without having to resort to the internal low-res pixbufs that GdkWindow
* sets on the client side. This is a function, not a method, for applying
* the icon name property for a given (possibly foreign) window, by passing
* the window's XID. Set to %NULL to unset.
*/
void
xapp_set_xid_icon_from_file (gulong xid,
const gchar *file_name)
{
g_return_if_fail (xid > 0);
set_window_hint_utf8 (xid, ICON_NAME_HINT, file_name);
}
/**
* xapp_set_xid_progress:
* @xid: The Window to set the progress for
* @progress: The value to set for progress.
*
* Sets the progress hint for a window manager (like muffin) to make
* available when applications want to display the application's progress
* in some operation. The value sent to the WM will be clamped to
* between 0 and 100.
*
* Setting progress will also cancel the 'pulsing' flag on the window as
* well, if it has been set.
*
* Note: If a window will stick around after progress is complete, you will
* probaby need to set progress to 0 to remove any progress effects on taskbars
* and window lists.
*
* This is a function, not a method, for applying the progress property for
* a given (possibly foreign) window, by passing the window's XID.
*/
void
xapp_set_xid_progress (gulong xid,
gint progress)
{
g_return_if_fail (xid > 0);
set_window_hint_cardinal (xid, PROGRESS_HINT, (gulong) (CLAMP (progress, 0, 100)));
set_window_hint_cardinal (xid, PROGRESS_PULSE_HINT, (gulong) 0);
}
/**
* xapp_set_xid_progress_pulse:
* @xid: The Window to set the progress for
* @pulse: Whether to have pulsing set or not.
*
* Sets the progress pulse hint hint for a window manager (like muffin)
* to make available when applications want to display indeterminate or
* ongoing progress in a task manager.
*
* Note: If a window will stick around after progress is complete, you will
* probaby need to set progress to 0 to remove any progress effects on taskbars
* and window lists.
*
* Setting an explicit progress value will unset this flag.
*/
void
xapp_set_xid_progress_pulse (gulong xid,
gboolean pulse)
{
g_return_if_fail (xid > 0);
set_window_hint_cardinal (xid, PROGRESS_PULSE_HINT, (gulong) (pulse ? 1 : 0));
}
xapp-2.8.2/libxapp/org.x.StatusIcon.xml 0000664 0001750 0001750 00000003115 14545562517 016746 0 ustar fabio fabio