Emit a "request" signal on selection acquire objects

This now creates a selection transfer object and requests Lua to reply
to the request via this object. However, so far no answer is possible.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2019-02-10 18:22:31 +01:00
parent b979fb724a
commit 53db43c2b2
1 changed files with 70 additions and 7 deletions

View File

@ -21,13 +21,29 @@
#include "objects/selection_transfer.h"
#include "common/luaobject.h"
#include "common/atoms.h"
#include "globalconf.h"
#define REGISTRY_TRANSFER_TABLE_INDEX "awesome_selection_transfers"
enum transfer_state {
TRANSFER_WAIT_FOR_DATA,
TRANSFER_DONE
};
typedef struct selection_transfer_t
{
LUA_OBJECT_HEADER
/** Reference in the special table to this object */
int ref;
/* Information from the xcb_selection_request_event_t */
xcb_window_t requestor;
xcb_atom_t selection;
xcb_atom_t target;
xcb_atom_t property;
xcb_timestamp_t time;
/* Current state of the transfer */
enum transfer_state state;
} selection_transfer_t;
static lua_class_t selection_transfer_class;
@ -58,22 +74,69 @@ selection_transfer_reject(xcb_window_t requestor, xcb_atom_t selection,
selection_transfer_notify(requestor, selection, target, XCB_NONE, time);
}
#include "common/atoms.h" /* TODO remove */
static void
transfer_done(lua_State *L, selection_transfer_t *transfer)
{
transfer->state = TRANSFER_DONE;
lua_pushliteral(L, REGISTRY_TRANSFER_TABLE_INDEX);
lua_rawget(L, LUA_REGISTRYINDEX);
luaL_unref(L, -1, transfer->ref);
transfer->ref = LUA_NOREF;
lua_pop(L, 1);
}
void
selection_transfer_begin(lua_State *L, int ud, xcb_window_t requestor,
xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property,
xcb_timestamp_t time)
{
/* TODO implement this */
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
requestor, property, UTF8_STRING, 8, 5, "Test\n");
selection_transfer_notify(requestor, selection, target, property, time);
ud = luaA_absindex(L, ud);
/* Allocate a transfer object */
selection_transfer_t *transfer = (void *) selection_transfer_class.allocator(L);
transfer->requestor = requestor;
transfer->selection = selection;
transfer->target = target;
transfer->property = property;
transfer->time = time;
transfer->state = TRANSFER_WAIT_FOR_DATA;
/* Save the object in the registry */
lua_pushliteral(L, REGISTRY_TRANSFER_TABLE_INDEX);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushvalue(L, -2);
transfer->ref = luaL_ref(L, -2);
lua_pop(L, 1);
/* Get the atom name */
xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(globalconf.connection,
xcb_get_atom_name_unchecked(globalconf.connection, target), NULL);
if (reply) {
lua_pushlstring(L, xcb_get_atom_name_name(reply),
xcb_get_atom_name_name_length(reply));
p_delete(&reply);
} else
lua_pushnil(L);
/* Emit the request signal with target and transfer object */
lua_pushvalue(L, -2);
luaA_object_emit_signal(L, ud, "request", 2);
/* Reject the transfer if Lua did not do anything */
if (transfer->state == TRANSFER_WAIT_FOR_DATA) {
selection_transfer_reject(requestor, selection, target, time);
transfer_done(L, transfer);
}
/* Remove the transfer object from the stack */
lua_pop(L, 1);
}
static bool
selection_transfer_checker(selection_transfer_t *selection)
selection_transfer_checker(selection_transfer_t *transfer)
{
return true;
return transfer->state != TRANSFER_DONE;
}
void