You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

489 lines
16 KiB

#include "e.h"
/* local subsystem functions */
static void _e_msgbus_request_name_cb(void *data, const Eldbus_Message *msg,
Eldbus_Pending *pending);
static Eldbus_Message *_e_msgbus_core_restart_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_core_shutdown_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_module_load_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_module_unload_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_module_enable_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_module_disable_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_module_list_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_profile_set_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_profile_get_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_profile_list_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_profile_add_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
static Eldbus_Message *_e_msgbus_profile_delete_cb(const Eldbus_Service_Interface *iface,
const Eldbus_Message *msg);
#define E_MSGBUS_WIN_ACTION_CB_PROTO(NAME) \
static Eldbus_Message * _e_msgbus_window_##NAME##_cb(const Eldbus_Service_Interface * iface, \
const Eldbus_Message * msg)
E_MSGBUS_WIN_ACTION_CB_PROTO(list);
E_MSGBUS_WIN_ACTION_CB_PROTO(close);
E_MSGBUS_WIN_ACTION_CB_PROTO(kill);
E_MSGBUS_WIN_ACTION_CB_PROTO(focus);
E_MSGBUS_WIN_ACTION_CB_PROTO(iconify);
E_MSGBUS_WIN_ACTION_CB_PROTO(uniconify);
E_MSGBUS_WIN_ACTION_CB_PROTO(maximize);
E_MSGBUS_WIN_ACTION_CB_PROTO(unmaximize);
/* local subsystem globals */
static E_Msgbus_Data *_e_msgbus_data = NULL;
static const Eldbus_Method core_methods[] = {
{ "Restart", NULL, NULL, _e_msgbus_core_restart_cb },
{ "Shutdown", NULL, NULL, _e_msgbus_core_shutdown_cb },
{ }
};
static const Eldbus_Method module_methods[] = {
{ "Load", ELDBUS_ARGS({"s", "module"}), NULL, _e_msgbus_module_load_cb },
{ "Unload", ELDBUS_ARGS({"s", "module"}), NULL, _e_msgbus_module_unload_cb },
{ "Enable", ELDBUS_ARGS({"s", "module"}), NULL, _e_msgbus_module_enable_cb },
{ "Disable", ELDBUS_ARGS({"s", "module"}), NULL, _e_msgbus_module_disable_cb },
{ "List", NULL, ELDBUS_ARGS({"a(si)", "modules"}),
_e_msgbus_module_list_cb },
{ }
};
static const Eldbus_Method profile_methods[] = {
{ "Set", ELDBUS_ARGS({"s", "profile"}), NULL, _e_msgbus_profile_set_cb },
{ "Get", NULL, ELDBUS_ARGS({"s", "profile"}), _e_msgbus_profile_get_cb },
{ "List", NULL, ELDBUS_ARGS({"as", "array_profiles"}),
_e_msgbus_profile_list_cb },
{ "Add", ELDBUS_ARGS({"s", "profile"}), NULL, _e_msgbus_profile_add_cb },
{ "Delete", ELDBUS_ARGS({"s", "profile"}), NULL, _e_msgbus_profile_delete_cb },
{ }
};
static const Eldbus_Method window_methods[] = {
{ "List", NULL, ELDBUS_ARGS({"a(si)", "array_of_window"}),
_e_msgbus_window_list_cb },
{ "Close", ELDBUS_ARGS({"i", "window_id"}), NULL, _e_msgbus_window_close_cb },
{ "Kill", ELDBUS_ARGS({"i", "window_id"}), NULL, _e_msgbus_window_kill_cb },
{ "Focus", ELDBUS_ARGS({"i", "window_id"}), NULL, _e_msgbus_window_focus_cb },
{ "Iconify", ELDBUS_ARGS({"i", "window_id"}), NULL,
_e_msgbus_window_iconify_cb },
{ "Uniconify", ELDBUS_ARGS({"i", "window_id"}), NULL,
_e_msgbus_window_uniconify_cb },
{ "Maximize", ELDBUS_ARGS({"i", "window_id"}), NULL,
_e_msgbus_window_maximize_cb },
{ "Unmaximize", ELDBUS_ARGS({"i", "window_id"}), NULL,
_e_msgbus_window_unmaximize_cb },
{ }
};
#define PATH "/org/enlightenment/wm/RemoteObject"
static const Eldbus_Service_Interface_Desc core_desc = {
"org.enlightenment.wm.Core", core_methods
};
static const Eldbus_Service_Interface_Desc module_desc = {
"org.enlightenment.wm.Module", module_methods
};
static const Eldbus_Service_Interface_Desc profile_desc = {
"org.enlightenment.wm.Profile", profile_methods
};
static const Eldbus_Service_Interface_Desc window_desc = {
"org.enlightenment.wm.Window", window_methods
};
/* externally accessible functions */
EINTERN int
e_msgbus_init(void)
{
_e_msgbus_data = E_NEW(E_Msgbus_Data, 1);
eldbus_init();
_e_msgbus_data->conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
if (!_e_msgbus_data->conn)
{
WRN("Cannot get ELDBUS_CONNECTION_TYPE_SESSION");
return 0;
}
_e_msgbus_data->iface = eldbus_service_interface_register(_e_msgbus_data->conn,
PATH, &core_desc);
eldbus_service_interface_register(_e_msgbus_data->conn, PATH, &module_desc);
eldbus_service_interface_register(_e_msgbus_data->conn, PATH, &profile_desc);
eldbus_service_interface_register(_e_msgbus_data->conn, PATH, &window_desc);
eldbus_name_request(_e_msgbus_data->conn, "org.enlightenment.wm.service",
0, _e_msgbus_request_name_cb, NULL);
return 1;
}
EINTERN int
e_msgbus_shutdown(void)
{
if (_e_msgbus_data->iface)
eldbus_service_object_unregister(_e_msgbus_data->iface);
if (_e_msgbus_data->conn)
{
eldbus_name_release(_e_msgbus_data->conn,
"org.enlightenment.wm.service", NULL, NULL);
eldbus_connection_unref(_e_msgbus_data->conn);
}
eldbus_shutdown();
E_FREE(_e_msgbus_data);
_e_msgbus_data = NULL;
return 1;
}
EAPI Eldbus_Service_Interface *
e_msgbus_interface_attach(const Eldbus_Service_Interface_Desc *desc)
{
if (!_e_msgbus_data->iface)
return NULL;
return eldbus_service_interface_register(_e_msgbus_data->conn, PATH, desc);
}
static void
_e_msgbus_request_name_cb(void *data __UNUSED__, const Eldbus_Message *msg,
Eldbus_Pending *pending __UNUSED__)
{
unsigned int flag;
if (eldbus_message_error_get(msg, NULL, NULL))
{
ERR("Could not request bus name");
return;
}
if (!eldbus_message_arguments_get(msg, "u", &flag))
{
ERR("Could not get arguments on on_name_request");
return;
}
if (!(flag & ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER))
ERR("Name already in use\n");
}
/* Core Handlers */
static Eldbus_Message *
_e_msgbus_core_restart_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
e_sys_action_do(E_SYS_RESTART, NULL);
return eldbus_message_method_return_new(msg);
}
static Eldbus_Message *
_e_msgbus_core_shutdown_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
e_sys_action_do(E_SYS_EXIT, NULL);
return eldbus_message_method_return_new(msg);
}
/* Modules Handlers */
static Eldbus_Message *
_e_msgbus_module_load_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
char *module;
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
if (!eldbus_message_arguments_get(msg, "s", &module))
return reply;
if (!e_module_find(module))
{
e_module_new(module);
e_config_save_queue();
}
return reply;
}
static Eldbus_Message *
_e_msgbus_module_unload_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
char *module;
E_Module *m;
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
if (!eldbus_message_arguments_get(msg, "s", &module))
return reply;
if ((m = e_module_find(module)))
{
e_module_disable(m);
e_object_del(E_OBJECT(m));
e_config_save_queue();
}
return reply;
}
static Eldbus_Message *
_e_msgbus_module_enable_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
char *module;
E_Module *m;
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
if (!eldbus_message_arguments_get(msg, "s", &module))
return reply;
if ((m = e_module_find(module)))
{
e_module_enable(m);
e_config_save_queue();
}
return reply;
}
static Eldbus_Message *
_e_msgbus_module_disable_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
char *module;
E_Module *m;
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
if (!eldbus_message_arguments_get(msg, "s", &module))
return reply;
if ((m = e_module_find(module)))
{
e_module_disable(m);
e_config_save_queue();
}
return reply;
}
static Eldbus_Message *
_e_msgbus_module_list_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
Eina_List *l;
E_Module *mod;
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
Eldbus_Message_Iter *main_iter, *array;
EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
main_iter = eldbus_message_iter_get(reply);
EINA_SAFETY_ON_NULL_RETURN_VAL(main_iter, reply);
eldbus_message_iter_arguments_append(main_iter, "a(si)", &array);
EINA_SAFETY_ON_NULL_RETURN_VAL(array, reply);
EINA_LIST_FOREACH(e_module_list(), l, mod)
{
Eldbus_Message_Iter *s;
const char *name;
int enabled;
name = mod->name;
enabled = mod->enabled;
eldbus_message_iter_arguments_append(array, "(si)", &s);
if (!s) continue;
eldbus_message_iter_arguments_append(s, "si", name, enabled);
eldbus_message_iter_container_close(array, s);
}
eldbus_message_iter_container_close(main_iter, array);
return reply;
}
/* Profile Handlers */
static Eldbus_Message *
_e_msgbus_profile_set_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
char *profile;
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
if (!eldbus_message_arguments_get(msg, "s", &profile))
return reply;
e_config_save_flush();
e_config_profile_set(profile);
e_config_profile_save();
e_config_save_block_set(1);
e_sys_action_do(E_SYS_RESTART, NULL);
return reply;
}
static Eldbus_Message *
_e_msgbus_profile_get_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
const char *profile;
EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
profile = e_config_profile_get();
eldbus_message_arguments_append(reply, "s", profile);
return reply;
}
static Eldbus_Message *
_e_msgbus_profile_list_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
Eina_List *l;
char *name;
Eldbus_Message *reply;
Eldbus_Message_Iter *array, *main_iter;
reply = eldbus_message_method_return_new(msg);
EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
main_iter = eldbus_message_iter_get(reply);
EINA_SAFETY_ON_FALSE_RETURN_VAL(main_iter, reply);
eldbus_message_iter_arguments_append(main_iter, "as", &array);
EINA_SAFETY_ON_FALSE_RETURN_VAL(array, reply);
l = e_config_profile_list();
EINA_LIST_FREE(l, name)
{
eldbus_message_iter_basic_append(array, 's', name);
free(name);
}
eldbus_message_iter_container_close(main_iter, array);
return reply;
}
static Eldbus_Message *
_e_msgbus_profile_add_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
char *profile;
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
if (!eldbus_message_arguments_get(msg, "s", &profile))
return reply;
e_config_profile_add(profile);
return reply;
}
static Eldbus_Message *
_e_msgbus_profile_delete_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
char *profile;
if (!eldbus_message_arguments_get(msg, "s", &profile))
return eldbus_message_method_return_new(msg);
if (!strcmp(e_config_profile_get(), profile))
return eldbus_message_error_new(msg,
"org.enlightenment.DBus.InvalidArgument",
"Can't delete active profile");
e_config_profile_del(profile);
return eldbus_message_method_return_new(msg);
}
/* Window handlers */
static Eldbus_Message *
_e_msgbus_window_list_cb(const Eldbus_Service_Interface *iface __UNUSED__,
const Eldbus_Message *msg)
{
Eina_List *l;
E_Border *bd;
Eldbus_Message *reply;
Eldbus_Message_Iter *main_iter, *array;
reply = eldbus_message_method_return_new(msg);
EINA_SAFETY_ON_FALSE_RETURN_VAL(reply, NULL);
main_iter = eldbus_message_iter_get(reply);
EINA_SAFETY_ON_FALSE_RETURN_VAL(main_iter, reply);
eldbus_message_iter_arguments_append(main_iter, "a(si)", &array);
EINA_SAFETY_ON_FALSE_RETURN_VAL(array, reply);
EINA_LIST_FOREACH(e_border_client_list(), l, bd)
{
Eldbus_Message_Iter *s;
eldbus_message_iter_arguments_append(array, "(si)", &s);
if (!s) continue;
eldbus_message_iter_arguments_append(s, "si", bd->client.icccm.name,
bd->client.win);
eldbus_message_iter_container_close(array, s);
}
eldbus_message_iter_container_close(main_iter, array);
return reply;
}
#define E_MSGBUS_WIN_ACTION_CB_BEGIN(NAME) \
static Eldbus_Message * \
_e_msgbus_window_##NAME##_cb(const Eldbus_Service_Interface * iface __UNUSED__, \
const Eldbus_Message * msg) \
{ \
E_Border *bd; \
int xwin; \
\
if (!eldbus_message_arguments_get(msg, "i", &xwin)) \
return eldbus_message_method_return_new(msg); \
bd = e_border_find_by_client_window(xwin); \
if (bd) \
{
#define E_MSGBUS_WIN_ACTION_CB_END \
} \
\
return eldbus_message_method_return_new(msg); \
}
E_MSGBUS_WIN_ACTION_CB_BEGIN(close)
e_border_act_close_begin(bd);
E_MSGBUS_WIN_ACTION_CB_END
E_MSGBUS_WIN_ACTION_CB_BEGIN(kill)
e_border_act_kill_begin(bd);
E_MSGBUS_WIN_ACTION_CB_END
E_MSGBUS_WIN_ACTION_CB_BEGIN(focus)
remove "border_raise_on_focus" config option buckle up. for the first time in history, a config option is getting removed instead of added. the reasons for this removal are many, but let's go way back to the beginning and see why it was added: oh wait, we can't because the commit message (from 2006) is >> patches that i said were in - commit. (see my reply emails) >> also finish off a TODO item or 2 reading through the TODO items which were also crossed off in that commit, I'm assuming that this was the "option to NOT raise on focus in click to focus" item. == REASON 1 == the problem here is that there's another, BETTER option called "click raises window" (always_click_to_raise) which does the same thing, except it doesn't totally fuck you when you get a random X focus event, which happens more often than you might think. this means that, to avoid broken behavior which might cause your windows to spastically raise for a few frames in common cases (using winlist...) with click-to-focus, you have to know that this is the default-enabled option that's fucking you, and you have to remember to manually disable it every time. if you DON'T know that this is the option that's fucking you, and you just see windows randomly raising on their own, you'll probably either ignore it or file a bug, when this is supposed to be a "feature" that actually worked in reverse, since it was intended only for disabling. == REASON 2 == there's also auto-raise, which can be set to 0.0s, which is effectively the same thing since it also triggers on focus but can be configured not to fuck your window stack == REASON 3 == aaand finally, this option makes any sort of pointer focus model impossible to use, since your windows will constantly be raising all over as you move the mouse tl;dr: I'm removing it, e-dealwithit.gif
9 years ago
e_border_activate(bd, 1);
E_MSGBUS_WIN_ACTION_CB_END
E_MSGBUS_WIN_ACTION_CB_BEGIN(iconify)
e_border_iconify(bd);
E_MSGBUS_WIN_ACTION_CB_END
E_MSGBUS_WIN_ACTION_CB_BEGIN(uniconify)
e_border_uniconify(bd);
E_MSGBUS_WIN_ACTION_CB_END
E_MSGBUS_WIN_ACTION_CB_BEGIN(maximize)
e_border_maximize(bd, e_config->maximize_policy);
E_MSGBUS_WIN_ACTION_CB_END
E_MSGBUS_WIN_ACTION_CB_BEGIN(unmaximize)
e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
E_MSGBUS_WIN_ACTION_CB_END