Blame ui/gtk3/indicator.vala

Packit Service 1d8f1c
/* vim:set et sts=4 sw=4:
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * ibus - The Input Bus
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * Copyright(c) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
Packit Service 1d8f1c
 * Copyright(c) 2015 Red Hat, Inc.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is free software; you can redistribute it and/or
Packit Service 1d8f1c
 * modify it under the terms of the GNU Lesser General Public
Packit Service 1d8f1c
 * License as published by the Free Software Foundation; either
Packit Service 1d8f1c
 * version 2.1 of the License, or (at your option) any later version.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is distributed in the hope that it will be useful,
Packit Service 1d8f1c
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 1d8f1c
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 1d8f1c
 * Lesser General Public License for more details.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * You should have received a copy of the GNU Lesser General Public
Packit Service 1d8f1c
 * License along with this library; if not, write to the Free Software
Packit Service 1d8f1c
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
Packit Service 1d8f1c
 * USA
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
Packit Service 1d8f1c
/* This class extends AppIndicator because
Packit Service 1d8f1c
 * AppIndicator misses "Activate" dbus method in the definition
Packit Service 1d8f1c
 * for left click on the indicator.
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
Packit Service 1d8f1c
public extern string _notification_item;
Packit Service 1d8f1c
public extern string _notification_watcher;
Packit Service 1d8f1c
Packit Service 1d8f1c
class Indicator : IBus.Service
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    public string id { get; construct; }
Packit Service 1d8f1c
    public string category_s { get; construct; }
Packit Service 1d8f1c
    public string status_s { get; set; }
Packit Service 1d8f1c
    public string icon_name { get; set; }
Packit Service 1d8f1c
    public string icon_desc { get; set; }
Packit Service 1d8f1c
    public string attention_icon_name { get; set; }
Packit Service 1d8f1c
    public string attention_icon_desc { get; set; }
Packit Service 1d8f1c
    public string title { get; set; }
Packit Service 1d8f1c
    public string icon_theme_path { get; set; }
Packit Service 1d8f1c
    public bool   connected { get; set; }
Packit Service 1d8f1c
    public string label_s { get; set; }
Packit Service 1d8f1c
    public string label_guide_s { get; set; }
Packit Service 1d8f1c
    public uint32 ordering_index { get; set; }
Packit Service 1d8f1c
    public GLib.Variant icon_vector { get; set; }
Packit Service 1d8f1c
Packit Service 1d8f1c
    public enum Category {
Packit Service 1d8f1c
        APPLICATION_STATUS,
Packit Service 1d8f1c
        COMMUNICATIONS,
Packit Service 1d8f1c
        SYSTEM_SERVICES,
Packit Service 1d8f1c
        HARDWARE,
Packit Service 1d8f1c
        OTHER;
Packit Service 1d8f1c
Packit Service 1d8f1c
        public string to_nick() {
Packit Service 1d8f1c
            switch(this) {
Packit Service 1d8f1c
            case APPLICATION_STATUS: return "ApplicationStatus";
Packit Service 1d8f1c
            case COMMUNICATIONS: return "Communications";
Packit Service 1d8f1c
            case SYSTEM_SERVICES: return "SystemServices";
Packit Service 1d8f1c
            case HARDWARE: return "Hardware";
Packit Service 1d8f1c
            case OTHER: return "Other";
Packit Service 1d8f1c
            default: assert_not_reached();
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    public enum Status {
Packit Service 1d8f1c
        PASSIVE,
Packit Service 1d8f1c
        ACTIVE,
Packit Service 1d8f1c
        ATTENTION;
Packit Service 1d8f1c
Packit Service 1d8f1c
        public string to_nick() {
Packit Service 1d8f1c
            switch(this) {
Packit Service 1d8f1c
            case PASSIVE: return "Passive";
Packit Service 1d8f1c
            case ACTIVE: return "Active";
Packit Service 1d8f1c
            case ATTENTION: return "NeedsAttention";
Packit Service 1d8f1c
            default: assert_not_reached();
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    private const string DEFAULT_ITEM_PATH = "/org/ayatana/NotificationItem";
Packit Service 1d8f1c
    private const string NOTIFICATION_ITEM_DBUS_IFACE =
Packit Service 1d8f1c
            "org.kde.StatusNotifierItem";
Packit Service 1d8f1c
    private const string NOTIFICATION_WATCHER_DBUS_IFACE =
Packit Service 1d8f1c
            "org.kde.StatusNotifierWatcher";
Packit Service 1d8f1c
    private const string NOTIFICATION_WATCHER_DBUS_ADDR =
Packit Service 1d8f1c
            "org.kde.StatusNotifierWatcher";
Packit Service 1d8f1c
    private const string NOTIFICATION_WATCHER_DBUS_OBJ =
Packit Service 1d8f1c
            "/StatusNotifierWatcher";
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.DBusNodeInfo m_watcher_node_info;
Packit Service 1d8f1c
    private unowned GLib.DBusInterfaceInfo m_watcher_interface_info;
Packit Service 1d8f1c
    private GLib.DBusProxy m_proxy;
Packit Service 1d8f1c
    private int m_context_menu_x;
Packit Service 1d8f1c
    private int m_context_menu_y;
Packit Service 1d8f1c
    private int m_activate_menu_x;
Packit Service 1d8f1c
    private int m_activate_menu_y;
Packit Service 1d8f1c
    private Gdk.Window m_indicator_window;
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public Indicator(string id,
Packit Service 1d8f1c
                     GLib.DBusConnection connection,
Packit Service 1d8f1c
                     Category category = Category.OTHER) {
Packit Service 1d8f1c
        string path = DEFAULT_ITEM_PATH + "/" + id;
Packit Service 1d8f1c
        path = path.delimit("-", '_');
Packit Service 1d8f1c
Packit Service 1d8f1c
        // AppIndicator.set_category() converts enum value to string internally.
Packit Service 1d8f1c
        GLib.Object(object_path: path,
Packit Service 1d8f1c
                    id: id,
Packit Service 1d8f1c
                    connection: connection,
Packit Service 1d8f1c
                    category_s: category.to_nick());
Packit Service 1d8f1c
        this.status_s = Status.PASSIVE.to_nick();
Packit Service 1d8f1c
        this.icon_name = "";
Packit Service 1d8f1c
        this.icon_desc = "";
Packit Service 1d8f1c
        this.title = "";
Packit Service 1d8f1c
        this.icon_theme_path = "";
Packit Service 1d8f1c
        this.attention_icon_name = "";
Packit Service 1d8f1c
        this.attention_icon_desc = "";
Packit Service 1d8f1c
        this.label_s = "";
Packit Service 1d8f1c
        this.label_guide_s = "";
Packit Service 1d8f1c
        unregister(connection);
Packit Service 1d8f1c
        add_interfaces(_notification_item);
Packit Service 1d8f1c
        try {
Packit Service 1d8f1c
            if (!register(connection))
Packit Service 1d8f1c
                return;
Packit Service 1d8f1c
        } catch (GLib.Error e) {
Packit Service 1d8f1c
            warning("Failed to register the application indicator xml: " +
Packit Service 1d8f1c
                    e.message);
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
Packit Service 1d8f1c
        try {
Packit Service 1d8f1c
            m_watcher_node_info =
Packit Service 1d8f1c
                    new GLib.DBusNodeInfo.for_xml(_notification_watcher);
Packit Service 1d8f1c
        } catch (GLib.Error e) {
Packit Service 1d8f1c
            warning("Failed to create dbus node info: " + e.message);
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        m_watcher_interface_info =
Packit Service 1d8f1c
                m_watcher_node_info.lookup_interface(
Packit Service 1d8f1c
                        NOTIFICATION_WATCHER_DBUS_IFACE);
Packit Service 1d8f1c
        check_connect();
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void check_connect() {
Packit Service 1d8f1c
        if (m_proxy == null) {
Packit Service 1d8f1c
            GLib.DBusProxy.new.begin(
Packit Service 1d8f1c
                    connection,
Packit Service 1d8f1c
                    GLib.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES |
Packit Service 1d8f1c
                            GLib.DBusProxyFlags.DO_NOT_CONNECT_SIGNALS,
Packit Service 1d8f1c
                    m_watcher_interface_info,
Packit Service 1d8f1c
                    NOTIFICATION_WATCHER_DBUS_ADDR,
Packit Service 1d8f1c
                    NOTIFICATION_WATCHER_DBUS_OBJ,
Packit Service 1d8f1c
                    NOTIFICATION_WATCHER_DBUS_IFACE,
Packit Service 1d8f1c
                    null,
Packit Service 1d8f1c
                    (obj, res) => {
Packit Service 1d8f1c
                            bus_watcher_ready(obj, res);
Packit Service 1d8f1c
                    });
Packit Service 1d8f1c
        } else {
Packit Service 1d8f1c
            bus_watcher_ready(null, null);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void bus_watcher_ready(GLib.Object? obj, GLib.AsyncResult? res) {
Packit Service 1d8f1c
        if (res != null) {
Packit Service 1d8f1c
            try {
Packit Service 1d8f1c
                m_proxy = GLib.DBusProxy.new.end(res);
Packit Service 1d8f1c
            } catch (GLib.IOError e) {
Packit Service 1d8f1c
                warning("Failed to call dbus proxy: " + e.message);
Packit Service 1d8f1c
                return;
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
Packit Service 1d8f1c
            m_proxy.notify["g-name-owner"].connect((obj, pspec) => {
Packit Service 1d8f1c
                    var name = m_proxy.get_name_owner();
Packit Service 1d8f1c
                    if (name != null)
Packit Service 1d8f1c
                        check_connect();
Packit Service 1d8f1c
            });
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
Packit Service 1d8f1c
        var name = m_proxy.get_name_owner();
Packit Service 1d8f1c
        // KDE panel does not run yet if name == null
Packit Service 1d8f1c
        if (name == null)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_proxy.call.begin("RegisterStatusNotifierItem",
Packit Service 1d8f1c
                           new GLib.Variant("(s)", this.object_path),
Packit Service 1d8f1c
                           GLib.DBusCallFlags.NONE,
Packit Service 1d8f1c
                           -1,
Packit Service 1d8f1c
                           null,
Packit Service 1d8f1c
                           (p_obj, p_res) => {
Packit Service 1d8f1c
                                   try {
Packit Service 1d8f1c
                                       m_proxy.call.end(p_res);
Packit Service 1d8f1c
                                       registered_status_notifier_item();
Packit Service 1d8f1c
                                   } catch (GLib.Error e) {
Packit Service 1d8f1c
                        warning("Failed to call " +
Packit Service 1d8f1c
                                "RegisterStatusNotifierItem: " +
Packit Service 1d8f1c
                                e.message);
Packit Service 1d8f1c
                                   }
Packit Service 1d8f1c
                           });
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void _context_menu_cb(GLib.DBusConnection       connection,
Packit Service 1d8f1c
                                  GLib.Variant              parameters,
Packit Service 1d8f1c
                                  GLib.DBusMethodInvocation invocation) {
Packit Service 1d8f1c
        GLib.Variant var_x = parameters.get_child_value(0);
Packit Service 1d8f1c
        GLib.Variant var_y = parameters.get_child_value(1);
Packit Service 1d8f1c
        m_context_menu_x = var_x.get_int32();
Packit Service 1d8f1c
        m_context_menu_y = var_y.get_int32();
Packit Service 1d8f1c
        Gdk.Window window = query_gdk_window();
Packit Service 1d8f1c
        context_menu(m_context_menu_x, m_context_menu_y, window, 2, 0);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void _activate_menu_cb(GLib.DBusConnection       connection,
Packit Service 1d8f1c
                                   GLib.Variant              parameters,
Packit Service 1d8f1c
                                   GLib.DBusMethodInvocation invocation) {
Packit Service 1d8f1c
        GLib.Variant var_x = parameters.get_child_value(0);
Packit Service 1d8f1c
        GLib.Variant var_y = parameters.get_child_value(1);
Packit Service 1d8f1c
        m_activate_menu_x = var_x.get_int32();
Packit Service 1d8f1c
        m_activate_menu_y = var_y.get_int32();
Packit Service 1d8f1c
        Gdk.Window window = query_gdk_window();
Packit Service 1d8f1c
        activate(m_activate_menu_x, m_activate_menu_y, window);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private Gdk.Window? query_gdk_window() {
Packit Service 1d8f1c
        if (m_indicator_window != null)
Packit Service 1d8f1c
            return m_indicator_window;
Packit Service 1d8f1c
Packit Service 1d8f1c
        Gdk.Display display = Gdk.Display.get_default();
Packit Service 1d8f1c
        unowned X.Display xdisplay =
Packit Service 1d8f1c
                (display as Gdk.X11.Display).get_xdisplay();
Packit Service 1d8f1c
        X.Window current = xdisplay.default_root_window();
Packit Service 1d8f1c
        X.Window parent = 0;
Packit Service 1d8f1c
        X.Window child = 0;
Packit Service 1d8f1c
        int root_x, root_y, win_x, win_y;
Packit Service 1d8f1c
        uint mask = 0;
Packit Service 1d8f1c
        root_x = root_y = win_x = win_y = 0;
Packit Service 1d8f1c
        bool retval;
Packit Service 1d8f1c
        // Need XSetErrorHandler for BadWindow?
Packit Service 1d8f1c
        while ((retval = xdisplay.query_pointer(current,
Packit Service 1d8f1c
                                      out parent, out child,
Packit Service 1d8f1c
                                      out root_x, out root_y,
Packit Service 1d8f1c
                                      out win_x, out win_y,
Packit Service 1d8f1c
                                      out mask))) {
Packit Service 1d8f1c
            if (child == 0)
Packit Service 1d8f1c
                break;
Packit Service 1d8f1c
            current = child;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (!retval) {
Packit Service 1d8f1c
            string format =
Packit Service 1d8f1c
                    "XQueryPointer is failed: current: %x root: %x " +
Packit Service 1d8f1c
                    "child: %x (%d, %d), (%d, %d), %u";
Packit Service 1d8f1c
            string message = format.printf((uint)current,
Packit Service 1d8f1c
                                           (uint)xdisplay.default_root_window(),
Packit Service 1d8f1c
                                           (uint)child,
Packit Service 1d8f1c
                                           root_x, root_y, win_x, win_y,
Packit Service 1d8f1c
                                           mask);
Packit Service 1d8f1c
            warning("XQueryPointer is failed: %s", message);
Packit Service 1d8f1c
            return null;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (current == xdisplay.default_root_window())
Packit Service 1d8f1c
            warning("The query window is root window");
Packit Service 1d8f1c
        m_indicator_window = Gdk.X11.Window.lookup_for_display(
Packit Service 1d8f1c
                display as Gdk.X11.Display,
Packit Service 1d8f1c
                current);
Packit Service 1d8f1c
        if (m_indicator_window != null)
Packit Service 1d8f1c
            return m_indicator_window;
Packit Service 1d8f1c
        m_indicator_window = new Gdk.X11.Window.foreign_for_display(
Packit Service 1d8f1c
                display as Gdk.X11.Display,
Packit Service 1d8f1c
                current);
Packit Service 1d8f1c
        return m_indicator_window;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_id(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.id);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_category(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.category_s);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_status(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.status_s);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_icon_name(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.icon_name);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_icon_vector(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return this.icon_vector;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_icon_desc(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.icon_desc);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_attention_icon_name(GLib.DBusConnection
Packit Service 1d8f1c
                                                             connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.attention_icon_name);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_attention_icon_desc(GLib.DBusConnection
Packit Service 1d8f1c
                                                             connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.attention_icon_desc);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_title(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.title);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_icon_theme_path(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.icon_theme_path);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_menu(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return null;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_xayatana_label(GLib.DBusConnection connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.label_s);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_xayatana_label_guide(GLib.DBusConnection
Packit Service 1d8f1c
                                                              connection) {
Packit Service 1d8f1c
        return new GLib.Variant.string(this.label_guide_s);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private GLib.Variant? _get_xayatana_ordering_index(GLib.DBusConnection
Packit Service 1d8f1c
                                                              connection) {
Packit Service 1d8f1c
        return new GLib.Variant.uint32(this.ordering_index);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void service_method_call(GLib.DBusConnection
Packit Service 1d8f1c
                                                                connection,
Packit Service 1d8f1c
                                             string             sender,
Packit Service 1d8f1c
                                             string             object_path,
Packit Service 1d8f1c
                                             string             interface_name,
Packit Service 1d8f1c
                                             string             method_name,
Packit Service 1d8f1c
                                             GLib.Variant       parameters,
Packit Service 1d8f1c
                                             GLib.DBusMethodInvocation
Packit Service 1d8f1c
                                                                invocation) {
Packit Service 1d8f1c
        GLib.return_if_fail (object_path == this.object_path);
Packit Service 1d8f1c
        GLib.return_if_fail (interface_name == NOTIFICATION_ITEM_DBUS_IFACE);
Packit Service 1d8f1c
Packit Service 1d8f1c
        if (method_name == "Activate") {
Packit Service 1d8f1c
            _activate_menu_cb(connection, parameters, invocation);
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (method_name == "ContextMenu") {
Packit Service 1d8f1c
            _context_menu_cb(connection, parameters, invocation);
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
Packit Service 1d8f1c
        warning("service_method_call() does not handle the method: " +
Packit Service 1d8f1c
                method_name);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override GLib.Variant? service_get_property(GLib.DBusConnection
Packit Service 1d8f1c
                                                                connection,
Packit Service 1d8f1c
                                                       string   sender,
Packit Service 1d8f1c
                                                       string   object_path,
Packit Service 1d8f1c
                                                       string   interface_name,
Packit Service 1d8f1c
                                                       string   property_name) {
Packit Service 1d8f1c
        GLib.return_val_if_fail (object_path == this.object_path, null);
Packit Service 1d8f1c
        GLib.return_val_if_fail (
Packit Service 1d8f1c
                interface_name == NOTIFICATION_ITEM_DBUS_IFACE,
Packit Service 1d8f1c
                null);
Packit Service 1d8f1c
Packit Service 1d8f1c
        if (property_name == "Id")
Packit Service 1d8f1c
            return _get_id(connection);
Packit Service 1d8f1c
        if (property_name == "Category")
Packit Service 1d8f1c
            return _get_category(connection);
Packit Service 1d8f1c
        if (property_name == "Status")
Packit Service 1d8f1c
            return _get_status(connection);
Packit Service 1d8f1c
        if (property_name == "IconName")
Packit Service 1d8f1c
            return _get_icon_name(connection);
Packit Service 1d8f1c
        if (property_name == "IconPixmap")
Packit Service 1d8f1c
            return _get_icon_vector(connection);
Packit Service 1d8f1c
        if (property_name == "IconAccessibleDesc")
Packit Service 1d8f1c
            return _get_icon_desc(connection);
Packit Service 1d8f1c
        if (property_name == "AttentionIconName")
Packit Service 1d8f1c
            return _get_attention_icon_name(connection);
Packit Service 1d8f1c
        if (property_name == "AttentionAccessibleDesc")
Packit Service 1d8f1c
            return _get_attention_icon_desc(connection);
Packit Service 1d8f1c
        if (property_name == "Title")
Packit Service 1d8f1c
            return _get_title(connection);
Packit Service 1d8f1c
        if (property_name == "IconThemePath")
Packit Service 1d8f1c
            return _get_icon_theme_path(connection);
Packit Service 1d8f1c
        if (property_name == "Menu")
Packit Service 1d8f1c
            return _get_menu(connection);
Packit Service 1d8f1c
        if (property_name == "XAyatanaLabel")
Packit Service 1d8f1c
            return _get_xayatana_label(connection);
Packit Service 1d8f1c
        if (property_name == "XAyatanaLabelGuide")
Packit Service 1d8f1c
            return _get_xayatana_label_guide(connection);
Packit Service 1d8f1c
        if (property_name == "XAyatanaOrderingIndex")
Packit Service 1d8f1c
            return _get_xayatana_ordering_index(connection);
Packit Service 1d8f1c
Packit Service 1d8f1c
        warning("service_get_property() does not handle the property: " +
Packit Service 1d8f1c
                property_name);
Packit Service 1d8f1c
Packit Service 1d8f1c
        return null;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override bool service_set_property(GLib.DBusConnection
Packit Service 1d8f1c
                                                           connection,
Packit Service 1d8f1c
                                              string       sender,
Packit Service 1d8f1c
                                              string       object_path,
Packit Service 1d8f1c
                                              string       interface_name,
Packit Service 1d8f1c
                                              string       property_name,
Packit Service 1d8f1c
                                              GLib.Variant value) {
Packit Service 1d8f1c
        return false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    // AppIndicator.set_status() converts enum value to string internally.
Packit Service 1d8f1c
    public void set_status(Status status) {
Packit Service 1d8f1c
        string status_s = status.to_nick();
Packit Service 1d8f1c
        if (this.status_s == status_s)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        this.status_s = status_s;
Packit Service 1d8f1c
Packit Service 1d8f1c
        /* This API does not require (this.connection != null)
Packit Service 1d8f1c
         * because service_get_property() can be called when
Packit Service 1d8f1c
         * this.connection emits the "NewStatus" signal or
Packit Service 1d8f1c
         * or m_proxy calls the "RegisterStatusNotifierItem" signal.
Packit Service 1d8f1c
         */
Packit Service 1d8f1c
        if (this.connection == null)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        try {
Packit Service 1d8f1c
            this.connection.emit_signal(null,
Packit Service 1d8f1c
                                        this.object_path,
Packit Service 1d8f1c
                                        NOTIFICATION_ITEM_DBUS_IFACE,
Packit Service 1d8f1c
                                        "NewStatus",
Packit Service 1d8f1c
                                        new GLib.Variant("(s)", status_s));
Packit Service 1d8f1c
        } catch(GLib.Error e) {
Packit Service 1d8f1c
            warning("Unable to send signal for NewIcon: %s", e.message);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    // AppIndicator.set_icon() is deprecated.
Packit Service 1d8f1c
    public void set_icon_full(string icon_name, string? icon_desc) {
Packit Service 1d8f1c
        bool changed = false;
Packit Service 1d8f1c
        if (this.icon_name != icon_name) {
Packit Service 1d8f1c
            this.icon_name = icon_name;
Packit Service 1d8f1c
            this.icon_vector = null;
Packit Service 1d8f1c
            changed = true;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (this.icon_desc != icon_desc) {
Packit Service 1d8f1c
            this.icon_desc = icon_desc;
Packit Service 1d8f1c
            changed = true;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (!changed)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
Packit Service 1d8f1c
        /* This API does not require (this.connection != null)
Packit Service 1d8f1c
         * because service_get_property() can be called when
Packit Service 1d8f1c
         * this.connection emits the "NewIcon" signal or
Packit Service 1d8f1c
         * or m_proxy calls the "RegisterStatusNotifierItem" signal.
Packit Service 1d8f1c
         */
Packit Service 1d8f1c
        if (this.connection == null)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        try {
Packit Service 1d8f1c
            this.connection.emit_signal(null,
Packit Service 1d8f1c
                                        this.object_path,
Packit Service 1d8f1c
                                        NOTIFICATION_ITEM_DBUS_IFACE,
Packit Service 1d8f1c
                                        "NewIcon",
Packit Service 1d8f1c
                                        null);
Packit Service 1d8f1c
        } catch(GLib.Error e) {
Packit Service 1d8f1c
            warning("Unable to send signal for NewIcon: %s", e.message);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void set_cairo_image_surface_full(Cairo.ImageSurface image,
Packit Service 1d8f1c
                                             string?            icon_desc) {
Packit Service 1d8f1c
        int width = image.get_width();
Packit Service 1d8f1c
        int height = image.get_height();
Packit Service 1d8f1c
        int stride = image.get_stride();
Packit Service 1d8f1c
        unowned uint8[] data = (uint8[]) image.get_data();
Packit Service 1d8f1c
        data.length = stride * height;
Packit Service 1d8f1c
        GLib.Bytes bytes = new GLib.Bytes(data);
Packit Service 1d8f1c
        GLib.Variant bs =
Packit Service 1d8f1c
                new GLib.Variant.from_bytes(GLib.VariantType.BYTESTRING,
Packit Service 1d8f1c
                                            bytes,
Packit Service 1d8f1c
                                            true);
Packit Service 1d8f1c
        GLib.VariantBuilder builder = new GLib.VariantBuilder(
Packit Service 1d8f1c
                new GLib.VariantType("a(iiay)"));
Packit Service 1d8f1c
        builder.open(new GLib.VariantType("(iiay)"));
Packit Service 1d8f1c
        builder.add("i", width);
Packit Service 1d8f1c
        builder.add("i", height);
Packit Service 1d8f1c
        builder.add_value(bs);
Packit Service 1d8f1c
        builder.close();
Packit Service 1d8f1c
        this.icon_vector = new GLib.Variant("a(iiay)", builder);
Packit Service 1d8f1c
        this.icon_name = "";
Packit Service 1d8f1c
Packit Service 1d8f1c
        if (this.icon_desc != icon_desc)
Packit Service 1d8f1c
            this.icon_desc = icon_desc;
Packit Service 1d8f1c
Packit Service 1d8f1c
        /* This API does not require (this.connection != null)
Packit Service 1d8f1c
         * because service_get_property() can be called when
Packit Service 1d8f1c
         * this.connection emits the "NewIcon" signal or
Packit Service 1d8f1c
         * or m_proxy calls the "RegisterStatusNotifierItem" signal.
Packit Service 1d8f1c
         */
Packit Service 1d8f1c
        if (this.connection == null)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        try {
Packit Service 1d8f1c
            this.connection.emit_signal(null,
Packit Service 1d8f1c
                                        this.object_path,
Packit Service 1d8f1c
                                        NOTIFICATION_ITEM_DBUS_IFACE,
Packit Service 1d8f1c
                                        "NewIcon",
Packit Service 1d8f1c
                                        null);
Packit Service 1d8f1c
        } catch(GLib.Error e) {
Packit Service 1d8f1c
            warning("Unable to send signal for NewIcon: %s", e.message);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void position_context_menu(Gtk.Menu menu,
Packit Service 1d8f1c
                                      out int  x,
Packit Service 1d8f1c
                                      out int  y,
Packit Service 1d8f1c
                                      out bool push_in) {
Packit Service 1d8f1c
        x = m_context_menu_x;
Packit Service 1d8f1c
        y = m_context_menu_y;
Packit Service 1d8f1c
        push_in = false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void position_activate_menu(Gtk.Menu menu,
Packit Service 1d8f1c
                                       out int  x,
Packit Service 1d8f1c
                                       out int  y,
Packit Service 1d8f1c
                                       out bool push_in) {
Packit Service 1d8f1c
        x = m_activate_menu_x;
Packit Service 1d8f1c
        y = m_activate_menu_y;
Packit Service 1d8f1c
        push_in = false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    /**
Packit Service 1d8f1c
     * unregister_connection:
Packit Service 1d8f1c
     *
Packit Service 1d8f1c
     * "Destroy" dbus method is not called for the indicator's connection
Packit Service 1d8f1c
     * when panel's connection is disconneted because the dbus connection
Packit Service 1d8f1c
     * is a shared session bus so need to call
Packit Service 1d8f1c
     * g_dbus_connection_unregister_object() by manual here
Packit Service 1d8f1c
     * so that g_object_unref(m_panel) will be called later with an idle method,
Packit Service 1d8f1c
     * which was assigned in the arguments of
Packit Service 1d8f1c
     * g_dbus_connection_register_object()
Packit Service 1d8f1c
     */
Packit Service 1d8f1c
    public void unregister_connection() {
Packit Service 1d8f1c
        unregister(get_connection());
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public signal void context_menu(int        x,
Packit Service 1d8f1c
                                    int        y,
Packit Service 1d8f1c
                                    Gdk.Window window,
Packit Service 1d8f1c
                                    uint       button,
Packit Service 1d8f1c
                                    uint       activate_time);
Packit Service 1d8f1c
    public signal void activate(int        x,
Packit Service 1d8f1c
                                int        y,
Packit Service 1d8f1c
                                Gdk.Window window);
Packit Service 1d8f1c
    public signal void registered_status_notifier_item();
Packit Service 1d8f1c
}