/* vim:set et sts=4 sw=4: * * ibus - The Input Bus * * Copyright(c) 2018 Peng Huang * Copyright(c) 2018 Takao Fujwiara * * 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 Street, Fifth Floor, Boston, MA 02110-1301 * USA */ /* This file depends on keybindingmanager.vala */ class BindingCommon { public enum KeyEventFuncType { ANY, IME_SWITCHER, EMOJI_TYPING, } public class Keybinding : GLib.Object { public Keybinding(uint keysym, Gdk.ModifierType modifiers, bool reverse, KeyEventFuncType ftype) { this.keysym = keysym; this.modifiers = modifiers; this.reverse = reverse; this.ftype = ftype; } public uint keysym { get; set; } public Gdk.ModifierType modifiers { get; set; } public bool reverse { get; set; } public KeyEventFuncType ftype { get; set; } } public delegate void KeybindingFuncHandlerFunc(Gdk.Event event); public static void keybinding_manager_bind(KeybindingManager keybinding_manager, ref GLib.List keybindings, string? accelerator, KeyEventFuncType ftype, KeybindingManager.KeybindingHandlerFunc handler_normal, KeybindingManager.KeybindingHandlerFunc? handler_reverse) { uint switch_keysym = 0; Gdk.ModifierType switch_modifiers = 0; Gdk.ModifierType reverse_modifier = Gdk.ModifierType.SHIFT_MASK; Keybinding keybinding; Gtk.accelerator_parse(accelerator, out switch_keysym, out switch_modifiers); // Map virtual modifiers to (i.e. Mod2, Mod3, ...) const Gdk.ModifierType VIRTUAL_MODIFIERS = ( Gdk.ModifierType.SUPER_MASK | Gdk.ModifierType.HYPER_MASK | Gdk.ModifierType.META_MASK); if ((switch_modifiers & VIRTUAL_MODIFIERS) != 0) { // workaround a bug in gdk vapi vala > 0.18 // https://bugzilla.gnome.org/show_bug.cgi?id=677559 #if VALA_0_18 Gdk.Keymap.get_default().map_virtual_modifiers( ref switch_modifiers); #else if ((switch_modifiers & Gdk.ModifierType.SUPER_MASK) != 0) switch_modifiers |= Gdk.ModifierType.MOD4_MASK; if ((switch_modifiers & Gdk.ModifierType.HYPER_MASK) != 0) switch_modifiers |= Gdk.ModifierType.MOD4_MASK; #endif switch_modifiers &= ~VIRTUAL_MODIFIERS; } if (switch_keysym == 0 && switch_modifiers == 0) { warning("Parse accelerator '%s' failed!", accelerator); return; } keybinding = new Keybinding(switch_keysym, switch_modifiers, false, ftype); keybindings.append(keybinding); keybinding_manager.bind(switch_keysym, switch_modifiers, handler_normal); if (ftype == KeyEventFuncType.EMOJI_TYPING) { return; } // accelerator already has Shift mask if ((switch_modifiers & reverse_modifier) != 0) { return; } switch_modifiers |= reverse_modifier; keybinding = new Keybinding(switch_keysym, switch_modifiers, true, ftype); keybindings.append(keybinding); if (ftype == KeyEventFuncType.IME_SWITCHER) { keybinding_manager.bind(switch_keysym, switch_modifiers, handler_reverse); } return; } public static void unbind_switch_shortcut(KeyEventFuncType ftype, GLib.List keybindings) { var keybinding_manager = KeybindingManager.get_instance(); while (keybindings != null) { Keybinding keybinding = keybindings.data; if (ftype == KeyEventFuncType.ANY || ftype == keybinding.ftype) { keybinding_manager.unbind(keybinding.keysym, keybinding.modifiers); } keybindings = keybindings.next; } } public static void set_custom_font(GLib.Settings? settings_panel, GLib.Settings? settings_emoji, ref Gtk.CssProvider? css_provider) { Gdk.Display display = Gdk.Display.get_default(); Gdk.Screen screen = (display != null) ? display.get_default_screen() : null; if (screen == null) { warning("Could not open display."); return; } if (settings_emoji != null) { string emoji_font = settings_emoji.get_string("font"); if (emoji_font == null) { warning("No config emoji:font."); return; } IBusEmojier.set_emoji_font(emoji_font); } if (settings_panel == null) return; bool use_custom_font = settings_panel.get_boolean("use-custom-font"); if (css_provider != null) { Gtk.StyleContext.remove_provider_for_screen(screen, css_provider); css_provider = null; } if (use_custom_font == false) { return; } string custom_font = settings_panel.get_string("custom-font"); if (custom_font == null) { warning("No config panel:custom-font."); return; } Pango.FontDescription font_desc = Pango.FontDescription.from_string(custom_font); string font_family = font_desc.get_family(); int font_size = font_desc.get_size() / Pango.SCALE; string data; if (Gtk.MAJOR_VERSION < 3 || (Gtk.MAJOR_VERSION == 3 && Gtk.MINOR_VERSION < 20)) { data = "GtkLabel { font: %s; }".printf(custom_font); } else { data = "label { font-family: %s; font-size: %dpt; }" .printf(font_family, font_size); } css_provider = new Gtk.CssProvider(); try { css_provider.load_from_data(data, -1); } catch (GLib.Error e) { warning("Failed css_provider_from_data: %s: %s", custom_font, e.message); return; } Gtk.StyleContext.add_provider_for_screen( screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } }