clipboard fixes
This commit is contained in:
parent
57e3634691
commit
83dd2f6039
146
platform.d
146
platform.d
@ -528,7 +528,7 @@ struct PlatformWindow
|
||||
Inputs[2] inputs;
|
||||
TicketMut input_mutex;
|
||||
|
||||
Mut cb_mut;
|
||||
TicketMut cb_mut;
|
||||
Selection[CBM.max] selections;
|
||||
version(linux) u32 cb_transfer_size;
|
||||
};
|
||||
@ -566,7 +566,7 @@ CreateWindow(string name, u16 width, u16 height)
|
||||
h: height,
|
||||
input_mutex: CreateTicketMut(),
|
||||
msg_queue: CreateMessageQueue(),
|
||||
cb_mut: CreateMut(),
|
||||
cb_mut: CreateTicketMut(),
|
||||
inputs: [
|
||||
{ arena: CreateArena(MB(1)) },
|
||||
{ arena: CreateArena(MB(1)) },
|
||||
@ -819,35 +819,34 @@ TransmitSelection(PlatformWindow* w, xcb_selection_request_event_t* ev)
|
||||
else if(ev.target == w.atoms[Atoms.Utf8String])
|
||||
{
|
||||
Selection* sel = null;
|
||||
if(TryLock(&w.cb_mut))
|
||||
Lock(&w.cb_mut);
|
||||
|
||||
foreach(i; CBM.min .. CBM.max)
|
||||
{
|
||||
foreach(i; CBM.min .. CBM.max)
|
||||
if(w.selections[i].xmode == ev.selection)
|
||||
{
|
||||
if(w.selections[i].xmode == ev.selection)
|
||||
{
|
||||
sel = &w.selections[i];
|
||||
break;
|
||||
}
|
||||
sel = &w.selections[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if(sel != null && sel.owned && sel.data.length > 0 && sel.target == ev.target)
|
||||
{
|
||||
xcb_change_property(
|
||||
w.conn,
|
||||
XCB_PROP_MODE_REPLACE,
|
||||
ev.requestor,
|
||||
ev.property,
|
||||
ev.target,
|
||||
8,
|
||||
cast(u32)sel.data.length,
|
||||
sel.data.ptr
|
||||
);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
Unlock(&w.cb_mut);
|
||||
}
|
||||
|
||||
if(sel != null && sel.owned && sel.data.length > 0 && sel.target == ev.target)
|
||||
{
|
||||
xcb_change_property(
|
||||
w.conn,
|
||||
XCB_PROP_MODE_REPLACE,
|
||||
ev.requestor,
|
||||
ev.property,
|
||||
ev.target,
|
||||
8,
|
||||
cast(u32)sel.data.length,
|
||||
sel.data.ptr
|
||||
);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
Unlock(&w.cb_mut);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -858,11 +857,10 @@ ClipboardOwns(PlatformWindow* w, ClipboardMode mode)
|
||||
{
|
||||
bool result;
|
||||
|
||||
if(TryLock(&w.cb_mut))
|
||||
{
|
||||
result = w.selections[mode].owned;
|
||||
Unlock(&w.cb_mut);
|
||||
}
|
||||
Lock(&w.cb_mut);
|
||||
|
||||
result = w.selections[mode].owned;
|
||||
Unlock(&w.cb_mut);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -872,51 +870,48 @@ ClipboardText(PlatformWindow* w, ClipboardMode mode)
|
||||
{
|
||||
u8[] buf;
|
||||
|
||||
if(TryLock(&w.cb_mut))
|
||||
Lock(&w.cb_mut);
|
||||
|
||||
scope(exit) Unlock(&w.cb_mut);
|
||||
|
||||
Selection* sel = &w.selections[mode];
|
||||
|
||||
if(sel.owned)
|
||||
{
|
||||
scope(exit) Unlock(&w.cb_mut);
|
||||
buf = GetClipboardSelection(w, sel);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeval now;
|
||||
timespec timeout;
|
||||
int pret = 0;
|
||||
|
||||
Selection* sel = &w.selections[mode];
|
||||
auto owner = xcb_get_selection_owner_reply(w.conn, xcb_get_selection_owner(w.conn, sel.xmode), null);
|
||||
scope(exit) pureFree(owner);
|
||||
|
||||
if(sel.owned)
|
||||
if(owner != null && owner.owner != 0)
|
||||
{
|
||||
buf = GetClipboardSelection(w, sel);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeval now;
|
||||
timespec timeout;
|
||||
int pret = 0;
|
||||
FreeArray(sel.data);
|
||||
sel.data = [];
|
||||
|
||||
auto owner = xcb_get_selection_owner_reply(w.conn, xcb_get_selection_owner(w.conn, sel.xmode), null);
|
||||
scope(exit) pureFree(owner);
|
||||
sel.target = w.atoms[Atoms.Utf8String];
|
||||
xcb_convert_selection(w.conn, w.window, sel.xmode, sel.target, sel.xmode, XCB_CURRENT_TIME);
|
||||
xcb_flush(w.conn);
|
||||
|
||||
if(owner != null && owner.owner != 0)
|
||||
gettimeofday(&now, null);
|
||||
|
||||
timeout.tv_sec = now.tv_sec + (X11_TIMEOUT_DEFAULT / 1000);
|
||||
timeout.tv_nsec = (now.tv_usec * 1000UL) * ((X11_TIMEOUT_DEFAULT % 1000) * 1000000UL);
|
||||
if(timeout.tv_nsec >= 1000000000UL)
|
||||
{
|
||||
FreeArray(sel.data);
|
||||
sel.data = [];
|
||||
|
||||
sel.target = w.atoms[Atoms.Utf8String];
|
||||
xcb_convert_selection(w.conn, w.window, sel.xmode, sel.target, sel.xmode, XCB_CURRENT_TIME);
|
||||
xcb_flush(w.conn);
|
||||
|
||||
gettimeofday(&now, null);
|
||||
|
||||
timeout.tv_sec = now.tv_sec + (X11_TIMEOUT_DEFAULT / 1000);
|
||||
timeout.tv_nsec = (now.tv_usec * 1000UL) * ((X11_TIMEOUT_DEFAULT % 1000) * 1000000UL);
|
||||
if(timeout.tv_nsec >= 1000000000UL)
|
||||
{
|
||||
timeout.tv_sec += timeout.tv_nsec / 1000000000UL;
|
||||
timeout.tv_nsec = timeout.tv_nsec % 1000000000UL;
|
||||
}
|
||||
|
||||
while(pret == 0 && sel.data.length == 0)
|
||||
{
|
||||
pret = PThreadCondTimedWait(&w.thread.cond, &w.thread.mut, &timeout);
|
||||
}
|
||||
|
||||
GetClipboardSelection(w, sel);
|
||||
timeout.tv_sec += timeout.tv_nsec / 1000000000UL;
|
||||
timeout.tv_nsec = timeout.tv_nsec % 1000000000UL;
|
||||
}
|
||||
|
||||
Lock(&w.cb_mut);
|
||||
Unlock(&w.cb_mut);
|
||||
|
||||
GetClipboardSelection(w, sel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -934,8 +929,11 @@ SetClipboard(PlatformWindow* w, u8[] data, ClipboardMode mode)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if(data.length > 0 && TryLock(&w.cb_mut))
|
||||
if(data.length > 0)
|
||||
{
|
||||
Lock(&w.cb_mut);
|
||||
scope(exit) Unlock(&w.cb_mut);
|
||||
|
||||
Selection* sel = &w.selections[mode];
|
||||
if(sel.data.length > 0)
|
||||
{
|
||||
@ -1043,8 +1041,10 @@ RetrieveSelection(PlatformWindow* w, xcb_selection_notify_event_t* ev)
|
||||
}
|
||||
}
|
||||
|
||||
if(buf != null && TryLock(&w.cb_mut))
|
||||
if(buf != null)
|
||||
{
|
||||
Lock(&w.cb_mut);
|
||||
|
||||
Selection* sel;
|
||||
foreach(i; CBM.min .. CBM.max)
|
||||
{
|
||||
@ -1082,8 +1082,10 @@ ClearSelection(PlatformWindow* w, xcb_selection_clear_event_t* ev)
|
||||
foreach(i; CBM.min .. CBM.max)
|
||||
{
|
||||
Selection* sel = &w.selections[i];
|
||||
if(sel.xmode == ev.selection && TryLock(&w.cb_mut))
|
||||
if(sel.xmode == ev.selection)
|
||||
{
|
||||
Lock(&w.cb_mut);
|
||||
|
||||
FreeArray(sel.data);
|
||||
sel.data = [];
|
||||
sel.owned = false;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user