Skip to content

Commit

Permalink
(shmif/lua) add target anchorhint
Browse files Browse the repository at this point in the history
This is a concession to primarily allow toolkits and protocol bridges
to systems that expect information about not just visibility and desired
dimensions but also position and hierarchy.

A side-effect to this is that it should make it rather trivial to put
together a miniwm appl (or durden workspace owner tool) that just
informs and delegates window management feedback to an external process
written in whatever.
  • Loading branch information
letoram committed May 20, 2023
1 parent 18ed255 commit aeb71b5
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* util:random\_bytes(len) added for CSPRNG byte string
* target_input long messages are now marked as multipart
* convey tui/tpack state in resize events
* target\_anchorhint added for informing clients about positioning and hierarchy

## Core
* respect border attribute in text rasteriser
Expand Down
38 changes: 38 additions & 0 deletions doc/target_anchorhint.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-- target_anchorhint
-- @short: Inform a target about its coordinates relative to a reference
-- @inargs: vid:tgt, int:type=ANCHORHINT_SEGMENT, int:parent, int:x, int:y, int:z
-- @inargs: vid:tgt, int:type=ANCHORHINT_EXTERNAL, int:parent, int:x, int:y, int:z
-- @inargs: vid:tgt, int:type=ANCHORHINT_PROXY, vid:src, int:parent, int:x, int:y, int:z
-- @inargs: vid:tgt, int:type=ANCHORHINT_PROXY_EXTERNAL, int:src, int:parent, int:x, int:y, int:z
-- @outargs:
-- @longdescr: While ref:target_displayhint can be used to provide additional
-- information about how a client will be presented, it does not carry
-- information about how it will be positioned within some reference frame.
-- This is not as useful since clients can already hint in the other direction
-- through viewport events.
--
-- The major exceptions are when one client is bridging to other windowing
-- systems (ANCHORHINT_PROXY, ANCHORHINT_PROXY_EXTERNAL),
-- acting as a window manager for nested/embedded subsegments (ANCHORHINT_SEGMENT)
-- or as an out-of-process external window manager (ANCHORHINT_PROXY).
-- *x* and *y* refers to the resolved upper-left corner position of the target,
-- and *z* the stacking or composition order.
--
-- In such cases target_anchorhint can be used. The type indicates which
-- reference objects that could be provided. If the type contains EXTERNAL the
-- *src* and *parent* arguments will be treated as an opaque externally
-- provided identifier, as with ref:target_displayhint and received through the
-- segment_request and viewport events.
--
-- The non-external types will have *src* and *parent* verified as valid
-- frameservers and the VIDs substitued for the respective cookie identifier
-- (see ref:launch_target). If these point to an invalid vid or ones without
-- TYPE_FRAMESERVER the event will fail silent and be discarded.
--
-- @group: targetcontrol
-- @cfunction: targetdisphint
-- @related: target_displayhint, launch_target
function main()
#ifdef MAIN
#endif
end
99 changes: 95 additions & 4 deletions src/engine/arcan_lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,22 @@ typedef int acoord;
#define CONST_TRUST_TRANSITIVE 13
#endif

#ifndef CONST_ANCHORHINT_SEGMENT
#define CONST_ANCHORHINT_SEGMENT 10
#endif

#ifndef CONST_ANCHORHINT_EXTERNAL
#define CONST_ANCHORHINT_EXTERNAL 11
#endif

#ifndef CONST_ANCHORHINT_PROXY
#define CONST_ANCHORHINT_PROXY 12
#endif

#ifndef CONST_ANCHORHINT_PROXY_EXTERNAL
#define CONST_ANCHORHINT_PROXY_EXTERNAL 13
#endif

/*
* disable support for all builtin frameservers
* which removes most (launch_target and target_alloc remain)
Expand Down Expand Up @@ -234,6 +250,10 @@ static const int RENDERFMT_RETAIN_ALPHA = RENDERTARGET_RETAIN_ALPHA;
static const int DEVICE_INDIRECT = CONST_DEVICE_INDIRECT;
static const int DEVICE_DIRECT = CONST_DEVICE_DIRECT;
static const int DEVICE_LOST = CONST_DEVICE_LOST;
static const int ANCHORHINT_SEGMENT = CONST_ANCHORHINT_SEGMENT;
static const int ANCHORHINT_EXTERNAL = CONST_ANCHORHINT_EXTERNAL;
static const int ANCHORHINT_PROXY = CONST_ANCHORHINT_PROXY;
static const int ANCHORHINT_PROXY_EXTERNAL = CONST_ANCHORHINT_PROXY_EXTERNAL;

#define DBHANDLE arcan_db_get_shared(NULL)

Expand Down Expand Up @@ -1083,12 +1103,12 @@ static int loadimageasynch(lua_State* ctx)

static int imageloaded(lua_State* ctx)
{
LUA_TRACE("imageloaded");
LUA_TRACE("image_loaded");
arcan_vobject* vobj;
luaL_checkvid(ctx, 1, &vobj);

lua_pushnumber(ctx, vobj->feed.state.tag == ARCAN_TAG_IMAGE);
LUA_ETRACE("load_image_asynch", NULL, 1);
LUA_ETRACE("image_loaded", NULL, 1);
}

static int moveimage(lua_State* ctx)
Expand Down Expand Up @@ -4221,8 +4241,10 @@ void arcan_lwa_subseg_ev(
case TARGET_COMMAND_PAUSE:
case TARGET_COMMAND_UNPAUSE:
case TARGET_COMMAND_GRAPHMODE:
/* handled in platform */
case TARGET_COMMAND_RESET:
case TARGET_COMMAND_ANCHORHINT: /* should probably feed back to know position,
but unclear if _lwa applications should rely
on that */
case TARGET_COMMAND_RESET: /* handled in platform */
case TARGET_COMMAND_SEEKCONTENT: /* scrolling */
case TARGET_COMMAND_COREOPT: /* dynamic key-value */
case TARGET_COMMAND_SEEKTIME: /* scrolling? */
Expand Down Expand Up @@ -7815,6 +7837,71 @@ static int targetdisphint(lua_State* ctx)
LUA_ETRACE("target_displayhint", NULL, 2);
}

static unsigned int get_vid_token(lua_State* ctx, int ind)
{
arcan_vobject* vobj;
arcan_vobj_id parent = luaL_checkvid(ctx, ind, &vobj);
if (vobj->feed.state.tag != ARCAN_TAG_FRAMESERV){
arcan_fatal("target_anchorhint(vid, ANCHORHINT_SEGMENT, "
">parent<, ...) not connected to a frameserver");
}
arcan_frameserver* fsrv = vobj->feed.state.ptr;
return fsrv->cookie;
}

static int targetanchor(lua_State* ctx)
{

LUA_TRACE("target_anchorhint");
arcan_event ev = {
.category = EVENT_TARGET,
.tgt.kind = TARGET_COMMAND_ANCHORHINT
};

arcan_vobject* vobj;
arcan_vobj_id vid = luaL_checkvid(ctx, 1, &vobj);

if (vobj->feed.state.tag != ARCAN_TAG_FRAMESERV){
arcan_fatal("target_anchorhint(>vid<, ...) not connected to a frameserver");
}

int type = luaL_checknumber(ctx, 2);
bool swap_token = false;
bool want_source = false;
int coord_ofs = 4;

switch (type){
case CONST_ANCHORHINT_SEGMENT:
ev.tgt.ioevs[4].uiv = get_vid_token(ctx, 3);
break;
case CONST_ANCHORHINT_PROXY:
ev.tgt.ioevs[3].uiv = get_vid_token(ctx, 3);
ev.tgt.ioevs[4].uiv = get_vid_token(ctx, 4);
break;
case CONST_ANCHORHINT_EXTERNAL:
ev.tgt.ioevs[4].uiv = luaL_checknumber(ctx, 3);
ev.tgt.ioevs[5].iv = 1;
coord_ofs = 5;
break;
case CONST_ANCHORHINT_PROXY_EXTERNAL:
ev.tgt.ioevs[3].uiv = luaL_checknumber(ctx, 3);
ev.tgt.ioevs[4].uiv = luaL_checknumber(ctx, 4);
ev.tgt.ioevs[5].iv = 1;
coord_ofs = 5;
break;
default:
arcan_fatal("target_anchorhint(vid, >type<, ..) invalid type value");
break;
}

ev.tgt.ioevs[0].uiv = luaL_checknumber(ctx, coord_ofs + 0);
ev.tgt.ioevs[1].uiv = luaL_checknumber(ctx, coord_ofs + 1);
ev.tgt.ioevs[2].uiv = luaL_optnumber(ctx, coord_ofs + 2, 0);

tgtevent(vid, ev);
LUA_ETRACE("target_anchorhint", NULL, 0);
}

static int targetgraph(lua_State* ctx)
{
LUA_TRACE("target_graphmode");
Expand Down Expand Up @@ -12159,6 +12246,10 @@ void arcan_lua_pushglobalconsts(lua_State* ctx){
{"DEVICE_INDIRECT", DEVICE_INDIRECT},
{"DEVICE_DIRECT", DEVICE_DIRECT},
{"DEVICE_LOST", DEVICE_LOST},
{"ANCHORHINT_SEGMENT", ANCHORHINT_SEGMENT},
{"ANCHORHINT_EXTERNAL", ANCHORHINT_EXTERNAL},
{"ANCHORHINT_PROXY", ANCHORHINT_PROXY},
{"ANCHORHINT_PROXY_EXTERNAL", ANCHORHINT_PROXY_EXTERNAL},
{"RENDERTARGET_NOSCALE", RENDERTARGET_NOSCALE},
{"RENDERTARGET_SCALE", RENDERTARGET_SCALE},
{"RENDERTARGET_NODETACH", RENDERTARGET_NODETACH},
Expand Down
4 changes: 4 additions & 0 deletions src/shmif/arcan_shmif_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@ enum ARCAN_TARGET_COMMAND {
* [2].iv : rel_z
* [3].uiv : source
* [4].uiv : parent
* [5].iv : extns (!0)
*
* Most clients should not rely or depend on these events. They are mainly
* provided to bridge other windowing systems, for pseudo-window management of
Expand All @@ -672,6 +673,9 @@ enum ARCAN_TARGET_COMMAND {
* The Z value may be used to carry stacking or draw order, e.g. < 0 the source
* is below the parent (drawn before), with > 0 is above the parent (drawn
* after).
*
* If extns is set (!0) the values of source and parent refers to previously
* provded extids from viewport and segment requests rather than segment token.
*/
TARGET_COMMAND_ANCHORHINT,

Expand Down
12 changes: 12 additions & 0 deletions src/wayland/wlimpl/surf.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,18 @@ static void surf_damage(struct wl_client* cl,
w *= surf->scale;
h *= surf->scale;

if (x < 0)
x = 0;

if (y < 0)
y = 0;

if (w < 0)
w = surf->acon.w;

if (h < 0)
h = surf->acon.h;

trace(TRACE_SURF,"%s:(%"PRIxPTR") @x,y+w,h(%d+%d, %d+%d)",
surf->tracetag, (uintptr_t)res, (int)x, (int)w, (int)y, (int)h);

Expand Down

0 comments on commit aeb71b5

Please sign in to comment.