Blame ui/gtk3/bindingcommon.vala

Packit 3ff832
/* vim:set et sts=4 sw=4:
Packit 3ff832
 *
Packit 3ff832
 * ibus - The Input Bus
Packit 3ff832
 *
Packit 3ff832
 * Copyright(c) 2018 Peng Huang <shawn.p.huang@gmail.com>
Packit 3ff832
 * Copyright(c) 2018 Takao Fujwiara <takao.fujiwara1@gmail.com>
Packit 3ff832
 *
Packit 3ff832
 * This library is free software; you can redistribute it and/or
Packit 3ff832
 * modify it under the terms of the GNU Lesser General Public
Packit 3ff832
 * License as published by the Free Software Foundation; either
Packit 3ff832
 * version 2.1 of the License, or (at your option) any later version.
Packit 3ff832
 *
Packit 3ff832
 * This library is distributed in the hope that it will be useful,
Packit 3ff832
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 3ff832
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 3ff832
 * Lesser General Public License for more details.
Packit 3ff832
 *
Packit 3ff832
 * You should have received a copy of the GNU Lesser General Public
Packit 3ff832
 * License along with this library; if not, write to the Free Software
Packit 3ff832
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
Packit 3ff832
 * USA
Packit 3ff832
 */
Packit 3ff832
Packit 3ff832
/* This file depends on keybindingmanager.vala */
Packit 3ff832
Packit 3ff832
class BindingCommon {
Packit 3ff832
    public enum KeyEventFuncType {
Packit 3ff832
        ANY,
Packit 3ff832
        IME_SWITCHER,
Packit 3ff832
        EMOJI_TYPING,
Packit 3ff832
    }
Packit 3ff832
Packit 3ff832
    public class Keybinding : GLib.Object {
Packit 3ff832
        public Keybinding(uint             keysym,
Packit 3ff832
                          Gdk.ModifierType modifiers,
Packit 3ff832
                          bool             reverse,
Packit 3ff832
                          KeyEventFuncType ftype) {
Packit 3ff832
            this.keysym = keysym;
Packit 3ff832
            this.modifiers = modifiers;
Packit 3ff832
            this.reverse = reverse;
Packit 3ff832
            this.ftype = ftype;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        public uint keysym { get; set; }
Packit 3ff832
        public Gdk.ModifierType modifiers { get; set; }
Packit 3ff832
        public bool reverse { get; set; }
Packit 3ff832
        public KeyEventFuncType ftype { get; set; }
Packit 3ff832
    }
Packit 3ff832
Packit 3ff832
    public delegate void KeybindingFuncHandlerFunc(Gdk.Event event);
Packit 3ff832
Packit 3ff832
    public static void
Packit 3ff832
    keybinding_manager_bind(KeybindingManager           keybinding_manager,
Packit 3ff832
                            ref GLib.List<Keybinding>   keybindings,
Packit 3ff832
                            string?                     accelerator,
Packit 3ff832
                            KeyEventFuncType            ftype,
Packit 3ff832
                            KeybindingManager.KeybindingHandlerFunc
Packit 3ff832
                                                        handler_normal,
Packit 3ff832
                            KeybindingManager.KeybindingHandlerFunc?
Packit 3ff832
                                                        handler_reverse) {
Packit 3ff832
        uint switch_keysym = 0;
Packit 3ff832
        Gdk.ModifierType switch_modifiers = 0;
Packit 3ff832
        Gdk.ModifierType reverse_modifier = Gdk.ModifierType.SHIFT_MASK;
Packit 3ff832
        Keybinding keybinding;
Packit 3ff832
Packit 3ff832
        Gtk.accelerator_parse(accelerator,
Packit 3ff832
                out switch_keysym, out switch_modifiers);
Packit 3ff832
Packit 3ff832
        // Map virtual modifiers to (i.e. Mod2, Mod3, ...)
Packit 3ff832
        const Gdk.ModifierType VIRTUAL_MODIFIERS = (
Packit 3ff832
                Gdk.ModifierType.SUPER_MASK |
Packit 3ff832
                Gdk.ModifierType.HYPER_MASK |
Packit 3ff832
                Gdk.ModifierType.META_MASK);
Packit 3ff832
        if ((switch_modifiers & VIRTUAL_MODIFIERS) != 0) {
Packit 3ff832
        // workaround a bug in gdk vapi vala > 0.18
Packit 3ff832
        // https://bugzilla.gnome.org/show_bug.cgi?id=677559
Packit 3ff832
#if VALA_0_18
Packit 3ff832
            Gdk.Keymap.get_default().map_virtual_modifiers(
Packit 3ff832
                    ref switch_modifiers);
Packit 3ff832
#else
Packit 3ff832
            if ((switch_modifiers & Gdk.ModifierType.SUPER_MASK) != 0)
Packit 3ff832
                switch_modifiers |= Gdk.ModifierType.MOD4_MASK;
Packit 3ff832
            if ((switch_modifiers & Gdk.ModifierType.HYPER_MASK) != 0)
Packit 3ff832
                switch_modifiers |= Gdk.ModifierType.MOD4_MASK;
Packit 3ff832
#endif
Packit 3ff832
            switch_modifiers &= ~VIRTUAL_MODIFIERS;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        if (switch_keysym == 0 && switch_modifiers == 0) {
Packit 3ff832
            warning("Parse accelerator '%s' failed!", accelerator);
Packit 3ff832
            return;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        keybinding = new Keybinding(switch_keysym,
Packit 3ff832
                                    switch_modifiers,
Packit 3ff832
                                    false,
Packit 3ff832
                                    ftype);
Packit 3ff832
        keybindings.append(keybinding);
Packit 3ff832
Packit 3ff832
        keybinding_manager.bind(switch_keysym, switch_modifiers,
Packit 3ff832
                                handler_normal);
Packit 3ff832
        if (ftype == KeyEventFuncType.EMOJI_TYPING) {
Packit 3ff832
            return;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        // accelerator already has Shift mask
Packit 3ff832
        if ((switch_modifiers & reverse_modifier) != 0) {
Packit 3ff832
            return;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        switch_modifiers |= reverse_modifier;
Packit 3ff832
Packit 3ff832
        keybinding = new Keybinding(switch_keysym,
Packit 3ff832
                                    switch_modifiers,
Packit 3ff832
                                    true,
Packit 3ff832
                                    ftype);
Packit 3ff832
        keybindings.append(keybinding);
Packit 3ff832
Packit 3ff832
        if (ftype == KeyEventFuncType.IME_SWITCHER) {
Packit 3ff832
            keybinding_manager.bind(switch_keysym, switch_modifiers,
Packit 3ff832
                                    handler_reverse);
Packit 3ff832
        }
Packit 3ff832
        return;
Packit 3ff832
    }
Packit 3ff832
Packit 3ff832
    public static void
Packit 3ff832
    unbind_switch_shortcut(KeyEventFuncType      ftype,
Packit 3ff832
                           GLib.List<Keybinding> keybindings) {
Packit 3ff832
        var keybinding_manager = KeybindingManager.get_instance();
Packit 3ff832
Packit 3ff832
        while (keybindings != null) {
Packit 3ff832
            Keybinding keybinding = keybindings.data;
Packit 3ff832
Packit 3ff832
            if (ftype == KeyEventFuncType.ANY ||
Packit 3ff832
                ftype == keybinding.ftype) {
Packit 3ff832
                keybinding_manager.unbind(keybinding.keysym,
Packit 3ff832
                                          keybinding.modifiers);
Packit 3ff832
            }
Packit 3ff832
            keybindings = keybindings.next;
Packit 3ff832
        }
Packit 3ff832
    }
Packit 3ff832
Packit 3ff832
    public static void
Packit 3ff832
    set_custom_font(GLib.Settings?       settings_panel,
Packit 3ff832
                    GLib.Settings?       settings_emoji,
Packit 3ff832
                    ref Gtk.CssProvider? css_provider) {
Packit 3ff832
        Gdk.Display display = Gdk.Display.get_default();
Packit 3ff832
        Gdk.Screen screen = (display != null) ?
Packit 3ff832
                display.get_default_screen() : null;
Packit 3ff832
Packit 3ff832
        if (screen == null) {
Packit 3ff832
            warning("Could not open display.");
Packit 3ff832
            return;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        if (settings_emoji != null) {
Packit 3ff832
            string emoji_font = settings_emoji.get_string("font");
Packit 3ff832
            if (emoji_font == null) {
Packit 3ff832
                warning("No config emoji:font.");
Packit 3ff832
                return;
Packit 3ff832
            }
Packit 3ff832
            IBusEmojier.set_emoji_font(emoji_font);
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        if (settings_panel == null)
Packit 3ff832
            return;
Packit 3ff832
Packit 3ff832
        bool use_custom_font = settings_panel.get_boolean("use-custom-font");
Packit 3ff832
Packit 3ff832
        if (css_provider != null) {
Packit 3ff832
            Gtk.StyleContext.remove_provider_for_screen(screen,
Packit 3ff832
                                                        css_provider);
Packit 3ff832
            css_provider = null;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        if (use_custom_font == false) {
Packit 3ff832
            return;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        string custom_font = settings_panel.get_string("custom-font");
Packit 3ff832
        if (custom_font == null) {
Packit 3ff832
            warning("No config panel:custom-font.");
Packit 3ff832
            return;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        Pango.FontDescription font_desc =
Packit 3ff832
                Pango.FontDescription.from_string(custom_font);
Packit 3ff832
        string font_family = font_desc.get_family();
Packit 3ff832
        int font_size = font_desc.get_size() / Pango.SCALE;
Packit 3ff832
        string data;
Packit 3ff832
Packit 3ff832
        if (Gtk.MAJOR_VERSION < 3 ||
Packit 3ff832
            (Gtk.MAJOR_VERSION == 3 && Gtk.MINOR_VERSION < 20)) {
Packit 3ff832
            data = "GtkLabel { font: %s; }".printf(custom_font);
Packit 3ff832
        } else {
Packit 3ff832
            data = "label { font-family: %s; font-size: %dpt; }"
Packit 3ff832
                           .printf(font_family, font_size);
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        css_provider = new Gtk.CssProvider();
Packit 3ff832
Packit 3ff832
        try {
Packit 3ff832
            css_provider.load_from_data(data, -1);
Packit 3ff832
        } catch (GLib.Error e) {
Packit 3ff832
            warning("Failed css_provider_from_data: %s: %s", custom_font,
Packit 3ff832
                                                             e.message);
Packit 3ff832
            return;
Packit 3ff832
        }
Packit 3ff832
Packit 3ff832
        Gtk.StyleContext.add_provider_for_screen(
Packit 3ff832
                screen,
Packit 3ff832
                css_provider,
Packit 3ff832
                Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
Packit 3ff832
    }
Packit 3ff832
}