Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: bus/ibusimpl.c

Issue 1735020: Support changing the global input method engine without focus. (Closed) Base URL: ssh://git@chromiumos-git/ibus.git
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | ibus/bus.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* vim:set et sts=4: */ 1 /* vim:set et sts=4: */
2 /* ibus - The Input Bus 2 /* ibus - The Input Bus
3 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com> 3 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
4 * Copyright (C) 2008-2010 Red Hat, Inc. 4 * Copyright (C) 2008-2010 Red Hat, Inc.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 (BusIBusImpl *ibus, 75 (BusIBusImpl *ibus,
76 GValue *value); 76 GValue *value);
77 77
78 static void bus_ibus_impl_set_use_global_engine 78 static void bus_ibus_impl_set_use_global_engine
79 (BusIBusImpl *ibus, 79 (BusIBusImpl *ibus,
80 GValue *value); 80 GValue *value);
81 static void bus_ibus_impl_set_global_engine (BusIBusImpl *ibus, 81 static void bus_ibus_impl_set_global_engine (BusIBusImpl *ibus,
82 BusEngineProxy *engine); 82 BusEngineProxy *engine);
83 83
84 static void bus_ibus_impl_registry_changed (BusIBusImpl *ibus); 84 static void bus_ibus_impl_registry_changed (BusIBusImpl *ibus);
85 static void bus_ibus_impl_global_engine_changed
86 (BusIBusImpl *ibus);
87
85 static void _factory_destroy_cb (BusFactoryProxy *factory, 88 static void _factory_destroy_cb (BusFactoryProxy *factory,
86 BusIBusImpl *ibus); 89 BusIBusImpl *ibus);
87 90
88 static void bus_ibus_impl_set_context_engine(BusIBusImpl *ibus, 91 static void bus_ibus_impl_set_context_engine(BusIBusImpl *ibus,
89 BusInputContext *context, 92 BusInputContext *context,
90 BusEngineProxy *engine); 93 BusEngineProxy *engine);
91 94
92 static gchar *bus_ibus_impl_load_global_engine_name_from_config 95 static gchar *bus_ibus_impl_load_global_engine_name_from_config
93 (BusIBusImpl *ibus); 96 (BusIBusImpl *ibus);
94 static void bus_ibus_impl_save_global_engine_name_to_config 97 static void bus_ibus_impl_save_global_engine_name_to_config
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 " <method name=\"Exit\">\n" 724 " <method name=\"Exit\">\n"
722 " <arg name=\"restart\" direction=\"in\" type=\"b\"/>\n" 725 " <arg name=\"restart\" direction=\"in\" type=\"b\"/>\n"
723 " </method>\n" 726 " </method>\n"
724 " <method name=\"Ping\">\n" 727 " <method name=\"Ping\">\n"
725 " <arg name=\"data\" direction=\"in\" type=\"v\"/>\n" 728 " <arg name=\"data\" direction=\"in\" type=\"v\"/>\n"
726 " <arg name=\"data\" direction=\"out\" type=\"v\"/>\n" 729 " <arg name=\"data\" direction=\"out\" type=\"v\"/>\n"
727 " </method>\n" 730 " </method>\n"
728 " <method name=\"GetUseSysLayout\">\n" 731 " <method name=\"GetUseSysLayout\">\n"
729 " <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n" 732 " <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
730 " </method>\n" 733 " </method>\n"
734 " <method name=\"GetUseGlobalEngine\">\n"
735 " <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
736 " </method>\n"
737 " <method name=\"GetGlobalEngine\">\n"
738 " <arg name=\"desc\" direction=\"out\" type=\"v\"/>\n"
739 " </method>\n"
740 " <method name=\"SetGlobalEngine\">\n"
741 " <arg name=\"name\" direction=\"in\" type=\"s\"/>\n"
742 " </method>\n"
743 " <method name=\"IsGlobalEngineEnabled\">\n"
744 " <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
745 " </method>\n"
731 " <signal name=\"RegistryChanged\">\n" 746 " <signal name=\"RegistryChanged\">\n"
732 " </signal>\n" 747 " </signal>\n"
748 " <signal name=\"GlobalEngineChanged\">\n"
749 " </signal>\n"
733 " </interface>\n" 750 " </interface>\n"
734 "</node>\n"; 751 "</node>\n";
735 752
736 IBusMessage *reply_message; 753 IBusMessage *reply_message;
737 reply_message = ibus_message_new_method_return (message); 754 reply_message = ibus_message_new_method_return (message);
738 ibus_message_append_args (reply_message, 755 ibus_message_append_args (reply_message,
739 G_TYPE_STRING, &introspect, 756 G_TYPE_STRING, &introspect,
740 G_TYPE_INVALID); 757 G_TYPE_INVALID);
741 758
742 return reply_message; 759 return reply_message;
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 1002
986 if (engine != NULL && !IBUS_OBJECT_DESTROYED (engine)) { 1003 if (engine != NULL && !IBUS_OBJECT_DESTROYED (engine)) {
987 g_object_ref (engine); 1004 g_object_ref (engine);
988 ibus->global_engine = engine; 1005 ibus->global_engine = engine;
989 g_signal_connect (ibus->global_engine, "destroy", 1006 g_signal_connect (ibus->global_engine, "destroy",
990 G_CALLBACK (_global_engine_destroy_cb), ibus); 1007 G_CALLBACK (_global_engine_destroy_cb), ibus);
991 } 1008 }
992 1009
993 bus_ibus_impl_save_global_engine_name_to_config (ibus); 1010 bus_ibus_impl_save_global_engine_name_to_config (ibus);
994 bus_ibus_impl_save_global_previous_engine_name_to_config (ibus); 1011 bus_ibus_impl_save_global_previous_engine_name_to_config (ibus);
1012 bus_ibus_impl_global_engine_changed (ibus);
995 } 1013 }
996 1014
997 static void 1015 static void
998 bus_ibus_impl_set_context_engine (BusIBusImpl *ibus, 1016 bus_ibus_impl_set_context_engine (BusIBusImpl *ibus,
999 BusInputContext *context, 1017 BusInputContext *context,
1000 BusEngineProxy *engine) { 1018 BusEngineProxy *engine) {
1001 g_object_set_data (G_OBJECT (context), "previous-engine-name", NULL); 1019 g_object_set_data (G_OBJECT (context), "previous-engine-name", NULL);
1002 1020
1003 /* If use_global_engine is disabled, then we need to save the previous engine 1021 /* If use_global_engine is disabled, then we need to save the previous engine
1004 * of each input context. */ 1022 * of each input context. */
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 1473
1456 return reply; 1474 return reply;
1457 } 1475 }
1458 1476
1459 static IBusMessage * 1477 static IBusMessage *
1460 _ibus_get_use_sys_layout (BusIBusImpl *ibus, 1478 _ibus_get_use_sys_layout (BusIBusImpl *ibus,
1461 IBusMessage *message, 1479 IBusMessage *message,
1462 BusConnection *connection) 1480 BusConnection *connection)
1463 { 1481 {
1464 IBusMessage *reply; 1482 IBusMessage *reply;
1465 IBusMessageIter src, dst;
1466 1483
1467 reply = ibus_message_new_method_return (message); 1484 reply = ibus_message_new_method_return (message);
1468 ibus_message_append_args (reply, 1485 ibus_message_append_args (reply,
1469 G_TYPE_BOOLEAN, &ibus->use_sys_layout, 1486 G_TYPE_BOOLEAN, &ibus->use_sys_layout,
1470 G_TYPE_INVALID); 1487 G_TYPE_INVALID);
1471 1488
1472 return reply; 1489 return reply;
1473 } 1490 }
1474 1491
1492 static IBusMessage *
1493 _ibus_get_use_global_engine (BusIBusImpl *ibus,
1494 IBusMessage *message,
1495 BusConnection *connection)
1496 {
1497 IBusMessage *reply;
1498
1499 reply = ibus_message_new_method_return (message);
1500 ibus_message_append_args (reply,
1501 G_TYPE_BOOLEAN, &ibus->use_global_engine,
1502 G_TYPE_INVALID);
1503
1504 return reply;
1505 }
1506
1507 static IBusMessage *
1508 _ibus_get_global_engine (BusIBusImpl *ibus,
1509 IBusMessage *message,
1510 BusConnection *connection)
1511 {
1512 IBusMessage *reply;
1513
1514 if (ibus->use_global_engine && ibus->global_engine) {
1515 IBusEngineDesc *desc = bus_engine_proxy_get_desc (ibus->global_engine);
1516 if (desc != NULL) {
1517 reply = ibus_message_new_method_return (message);
1518 ibus_message_append_args (reply,
1519 IBUS_TYPE_ENGINE_DESC, &desc,
1520 G_TYPE_INVALID);
1521 return reply;
1522 }
1523 }
1524
1525 reply = ibus_message_new_error (message, DBUS_ERROR_FAILED,
1526 "No global engine.");
1527 return reply;
1528 }
1529
1530 static IBusMessage *
1531 _ibus_set_global_engine (BusIBusImpl *ibus,
1532 IBusMessage *message,
1533 BusConnection *connection)
1534 {
1535 gboolean retval;
1536 IBusMessage *reply;
1537 IBusError *error;
1538 gchar *new_engine_name;
1539 gchar *old_engine_name;
1540
1541 if (!ibus->use_global_engine) {
1542 reply = ibus_message_new_error (message, DBUS_ERROR_FAILED,
1543 "Global engine feature is disable.");
1544 return reply;
1545 }
1546
1547 retval = ibus_message_get_args (message,
1548 &error,
1549 G_TYPE_STRING, &new_engine_name,
1550 G_TYPE_INVALID);
1551 if (!retval) {
1552 reply = ibus_message_new_error (message,
1553 error->name,
1554 error->message);
1555 ibus_error_free (error);
1556 return reply;
1557 }
1558
1559 reply = ibus_message_new_method_return (message);
1560 old_engine_name = NULL;
1561
1562 if (ibus->global_engine) {
1563 old_engine_name = bus_engine_proxy_get_desc (ibus->global_engine)->name;
1564 }
1565
1566 if (g_strcmp0 (new_engine_name, old_engine_name) == 0) {
1567 /* If the user requested the same global engine, then we just enable the
1568 * original one. */
1569 if (ibus->focused_context) {
1570 bus_input_context_enable (ibus->focused_context);
1571 }
1572 else if (ibus->global_engine) {
1573 bus_engine_proxy_enable (ibus->global_engine);
1574 }
1575 return reply;
1576 }
1577
1578 /* If there is a focused input context, then we just change the engine of
1579 * the focused context, which will then change the global engine
1580 * automatically. Otherwise, we need to change the global engine directly.
1581 */
1582 if (ibus->focused_context) {
1583 _context_request_engine_cb (ibus->focused_context, new_engine_name, ibus );
1584 }
1585 else {
1586 IBusEngineDesc *engine_desc = _find_engine_desc_by_name (ibus, new_engin e_name);
1587 if (engine_desc != NULL) {
1588 BusEngineProxy *new_engine = bus_ibus_impl_create_engine (engine_des c);
1589 if (new_engine != NULL) {
1590 /* Enable the global engine by default, because the user
1591 * selected it explicitly. */
1592 bus_engine_proxy_enable (new_engine);
1593
1594 /* Assume the ownership of the new global engine. Normally it's
1595 * done by the input context. But as we need to change the globa l
1596 * engine directly, so we need to do it here. */
1597 g_object_ref_sink (new_engine);
1598 bus_ibus_impl_set_global_engine (ibus, new_engine);
1599
1600 /* The global engine should already be referenced. */
1601 g_object_unref (new_engine);
1602 }
1603 }
1604 }
1605
1606 return reply;
1607 }
1608
1609 static IBusMessage *
1610 _ibus_is_global_engine_enabled (BusIBusImpl *ibus,
1611 IBusMessage *message,
1612 BusConnection *connection)
1613 {
1614 IBusMessage *reply;
1615 gboolean enabled = (ibus->use_global_engine && ibus->global_engine &&
1616 bus_engine_proxy_is_enabled (ibus->global_engine));
1617
1618 reply = ibus_message_new_method_return (message);
1619 ibus_message_append_args (reply,
1620 G_TYPE_BOOLEAN, &enabled,
1621 G_TYPE_INVALID);
1622 return reply;
1623 }
1624
1625
1475 static gboolean 1626 static gboolean
1476 bus_ibus_impl_ibus_message (BusIBusImpl *ibus, 1627 bus_ibus_impl_ibus_message (BusIBusImpl *ibus,
1477 BusConnection *connection, 1628 BusConnection *connection,
1478 IBusMessage *message) 1629 IBusMessage *message)
1479 { 1630 {
1480 g_assert (BUS_IS_IBUS_IMPL (ibus)); 1631 g_assert (BUS_IS_IBUS_IMPL (ibus));
1481 g_assert (BUS_IS_CONNECTION (connection)); 1632 g_assert (BUS_IS_CONNECTION (connection));
1482 g_assert (message != NULL); 1633 g_assert (message != NULL);
1483 1634
1484 gint i; 1635 gint i;
(...skipping 10 matching lines...) Expand all
1495 /* IBus interface */ 1646 /* IBus interface */
1496 { IBUS_INTERFACE_IBUS, "GetAddress", _ibus_get_address }, 1647 { IBUS_INTERFACE_IBUS, "GetAddress", _ibus_get_address },
1497 { IBUS_INTERFACE_IBUS, "CreateInputContext", _ibus_create_input_conte xt }, 1648 { IBUS_INTERFACE_IBUS, "CreateInputContext", _ibus_create_input_conte xt },
1498 { IBUS_INTERFACE_IBUS, "CurrentInputContext", _ibus_current_input_cont ext }, 1649 { IBUS_INTERFACE_IBUS, "CurrentInputContext", _ibus_current_input_cont ext },
1499 { IBUS_INTERFACE_IBUS, "RegisterComponent", _ibus_register_component }, 1650 { IBUS_INTERFACE_IBUS, "RegisterComponent", _ibus_register_component },
1500 { IBUS_INTERFACE_IBUS, "ListEngines", _ibus_list_engines }, 1651 { IBUS_INTERFACE_IBUS, "ListEngines", _ibus_list_engines },
1501 { IBUS_INTERFACE_IBUS, "ListActiveEngines", _ibus_list_active_engine s }, 1652 { IBUS_INTERFACE_IBUS, "ListActiveEngines", _ibus_list_active_engine s },
1502 { IBUS_INTERFACE_IBUS, "Exit", _ibus_exit }, 1653 { IBUS_INTERFACE_IBUS, "Exit", _ibus_exit },
1503 { IBUS_INTERFACE_IBUS, "Ping", _ibus_ping }, 1654 { IBUS_INTERFACE_IBUS, "Ping", _ibus_ping },
1504 { IBUS_INTERFACE_IBUS, "GetUseSysLayout", _ibus_get_use_sys_layout }, 1655 { IBUS_INTERFACE_IBUS, "GetUseSysLayout", _ibus_get_use_sys_layout },
1656 { IBUS_INTERFACE_IBUS, "GetUseGlobalEngine", _ibus_get_use_global_eng ine },
1657 { IBUS_INTERFACE_IBUS, "GetGlobalEngine", _ibus_get_global_engine },
1658 { IBUS_INTERFACE_IBUS, "SetGlobalEngine", _ibus_set_global_engine },
1659 { IBUS_INTERFACE_IBUS, "IsGlobalEngineEnabled", _ibus_is_global_engine_e nabled },
1505 }; 1660 };
1506 1661
1507 ibus_message_set_sender (message, bus_connection_get_unique_name (connection )); 1662 ibus_message_set_sender (message, bus_connection_get_unique_name (connection ));
1508 ibus_message_set_destination (message, DBUS_SERVICE_DBUS); 1663 ibus_message_set_destination (message, DBUS_SERVICE_DBUS);
1509 1664
1510 if (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) { 1665 if (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) {
1511 for (i = 0; i < G_N_ELEMENTS (handlers); i++) { 1666 for (i = 0; i < G_N_ELEMENTS (handlers); i++) {
1512 if (ibus_message_is_method_call (message, 1667 if (ibus_message_is_method_call (message,
1513 handlers[i].interface, 1668 handlers[i].interface,
1514 handlers[i].name)) { 1669 handlers[i].name)) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 ibus_message_append_args (message, 1743 ibus_message_append_args (message,
1589 G_TYPE_INVALID); 1744 G_TYPE_INVALID);
1590 ibus_message_set_sender (message, IBUS_SERVICE_IBUS); 1745 ibus_message_set_sender (message, IBUS_SERVICE_IBUS);
1591 1746
1592 bus_dbus_impl_dispatch_message_by_rule (BUS_DEFAULT_DBUS, message, NULL); 1747 bus_dbus_impl_dispatch_message_by_rule (BUS_DEFAULT_DBUS, message, NULL);
1593 1748
1594 ibus_message_unref (message); 1749 ibus_message_unref (message);
1595 1750
1596 } 1751 }
1597 1752
1753 static void
1754 bus_ibus_impl_global_engine_changed (BusIBusImpl *ibus)
1755 {
1756 g_assert (BUS_IS_IBUS_IMPL (ibus));
1757
1758 IBusMessage *message;
1759
1760 message = ibus_message_new_signal (IBUS_PATH_IBUS,
1761 IBUS_INTERFACE_IBUS,
1762 "GlobalEngineChanged");
1763 ibus_message_append_args (message,
1764 G_TYPE_INVALID);
1765 ibus_message_set_sender (message, IBUS_SERVICE_IBUS);
1766
1767 bus_dbus_impl_dispatch_message_by_rule (BUS_DEFAULT_DBUS, message, NULL);
1768
1769 ibus_message_unref (message);
1770 }
1598 1771
1599 gboolean 1772 gboolean
1600 bus_ibus_impl_filter_keyboard_shortcuts (BusIBusImpl *ibus, 1773 bus_ibus_impl_filter_keyboard_shortcuts (BusIBusImpl *ibus,
1601 BusInputContext *context, 1774 BusInputContext *context,
1602 guint keyval, 1775 guint keyval,
1603 guint modifiers, 1776 guint modifiers,
1604 guint prev_keyval, 1777 guint prev_keyval,
1605 guint prev_modifiers) 1778 guint prev_modifiers)
1606 { 1779 {
1607 static GQuark trigger = 0; 1780 static GQuark trigger = 0;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 1881
1709 if (ibus->use_global_engine && ibus->global_previous_engine_name) { 1882 if (ibus->use_global_engine && ibus->global_previous_engine_name) {
1710 GValue value = { 0 }; 1883 GValue value = { 0 };
1711 g_value_init (&value, G_TYPE_STRING); 1884 g_value_init (&value, G_TYPE_STRING);
1712 g_value_set_static_string (&value, ibus->global_previous_engine_name); 1885 g_value_set_static_string (&value, ibus->global_previous_engine_name);
1713 1886
1714 ibus_config_set_value (ibus->config, "general", "global_previous_engine" , &value); 1887 ibus_config_set_value (ibus->config, "general", "global_previous_engine" , &value);
1715 g_value_unset (&value); 1888 g_value_unset (&value);
1716 } 1889 }
1717 } 1890 }
OLDNEW
« no previous file with comments | « no previous file | ibus/bus.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698