Skip to content

Commit 1a12806

Browse files
committed
system clipboard paste for widgets
1 parent 58477f3 commit 1a12806

8 files changed

Lines changed: 125 additions & 41 deletions

File tree

Engine/system/api/x11api.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,21 @@ static Atom& _NET_WM_STATE_FULLSCREEN(){
7676
return w;
7777
}
7878

79+
static Atom& CLIPBOARD(){
80+
static Atom w = XInternAtom( dpy, "CLIPBOARD", 0);
81+
return w;
82+
}
83+
84+
static Atom& UTF8_STRING(){
85+
static Atom w = XInternAtom( dpy, "UTF8_STRING", 0);
86+
return w;
87+
}
88+
89+
static Atom& XSEL_DATA(){
90+
static Atom w = XInternAtom( dpy, "XSEL_DATA", 0);
91+
return w;
92+
}
93+
7994
static bool nativeIsFullscreen(SystemApi::Window *iw) {
8095
HWND w(iw);
8196

@@ -627,7 +642,19 @@ void X11Api::implProcessEvents(SystemApi::AppCallBack &cb) {
627642
uint32_t scan = xev.xkey.keycode;
628643
// printf("%s\n",txt);
629644

630-
Tempest::KeyEvent e(Event::KeyType(key),uint32_t(u16.size()>0 ? u16[0] : 0),Event::M_NoModifier,(xev.type==KeyPress) ? Event::KeyDown : Event::KeyUp);
645+
Tempest::KeyEvent e(
646+
Event::KeyType(key),
647+
uint32_t(u16.size()>0 ? u16[0] : 0),
648+
xev.xkey.state & ControlMask ? Event::M_Ctrl : Event::M_NoModifier,
649+
(xev.type==KeyPress) ? Event::KeyDown : Event::KeyUp
650+
);
651+
652+
// Ctrl+V - Request clipboard insert
653+
if (e.modifier == Event::M_Ctrl and e.type() == Event::KeyDown and e.key == Event::K_V) {
654+
XConvertSelection(dpy, CLIPBOARD(), UTF8_STRING(), XSEL_DATA(), hWnd, CurrentTime);
655+
break;
656+
}
657+
631658
if(xev.type==KeyPress)
632659
SystemApi::dispatchKeyDown(cb,e,scan); else
633660
SystemApi::dispatchKeyUp (cb,e,scan);
@@ -643,6 +670,27 @@ void X11Api::implProcessEvents(SystemApi::AppCallBack &cb) {
643670
SystemApi::dispatchFocus(cb, e);
644671
break;
645672
}
673+
case SelectionNotify: {
674+
if (xev.xselection.property != None) {
675+
Atom actual_type;
676+
int actual_format;
677+
unsigned long nitems, bytes_after;
678+
unsigned char* data;
679+
680+
XGetWindowProperty(xev.xselection.display, xev.xselection.requestor,
681+
xev.xselection.property, 0L, ~0L, False, AnyPropertyType,
682+
&actual_type, &actual_format, &nitems, &bytes_after, &data);
683+
684+
if (actual_type == UTF8_STRING() || actual_type == XA_STRING) {
685+
ClipboardEvent e(std::string(reinterpret_cast<char*>(data)));
686+
SystemApi::dispatchClipboardPaste(cb,e);
687+
XFree(data);
688+
}
689+
690+
XDeleteProperty(dpy, xev.xselection.requestor, xev.xselection.property);
691+
}
692+
break;
693+
}
646694
}
647695

648696
std::this_thread::yield();

Engine/system/eventdispatcher.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,21 @@ void EventDispatcher::dispatchDestroyWindow(SystemApi::Window* w) {
257257
overlays[i]->dispatchDestroyWindow(w);
258258
}
259259

260+
void EventDispatcher::dispatchClipboardPaste(Widget& wnd, ClipboardEvent& event) {
261+
for(auto i:overlays) {
262+
if(!i->bind(wnd))
263+
continue;
264+
265+
Widget* w = i;
266+
while(w->astate.focus!=nullptr) {
267+
w = w->astate.focus;
268+
}
269+
if(w->wstate.focus || i==w) {
270+
w->clipboardInsertEvent(event);
271+
}
272+
}
273+
}
274+
260275
std::shared_ptr<Widget::Ref> EventDispatcher::implDispatch(Widget& w, MouseEvent &event) {
261276
if(!w.isVisible()) {
262277
event.ignore();

Engine/system/eventdispatcher.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,24 @@ class EventDispatcher final {
1212
EventDispatcher();
1313
EventDispatcher(Widget& root);
1414

15-
void dispatchMouseDown (Widget& wnd, Tempest::MouseEvent& event);
16-
void dispatchMouseUp (Widget& wnd, Tempest::MouseEvent& event);
17-
void dispatchMouseMove (Widget& wnd, Tempest::MouseEvent& event);
18-
void dispatchMouseWheel(Widget& wnd, Tempest::MouseEvent& event);
15+
void dispatchMouseDown (Widget& wnd, Tempest::MouseEvent& event);
16+
void dispatchMouseUp (Widget& wnd, Tempest::MouseEvent& event);
17+
void dispatchMouseMove (Widget& wnd, Tempest::MouseEvent& event);
18+
void dispatchMouseWheel (Widget& wnd, Tempest::MouseEvent& event);
1919

20-
void dispatchKeyDown (Widget& wnd, Tempest::KeyEvent& event, uint32_t scancode);
21-
void dispatchKeyUp (Widget& wnd, Tempest::KeyEvent& event, uint32_t scancode);
20+
void dispatchKeyDown (Widget& wnd, Tempest::KeyEvent& event, uint32_t scancode);
21+
void dispatchKeyUp (Widget& wnd, Tempest::KeyEvent& event, uint32_t scancode);
2222

23-
void dispatchResize (Widget& wnd, Tempest::SizeEvent& event);
24-
void dispatchClose (Widget& wnd, Tempest::CloseEvent& event);
23+
void dispatchResize (Widget& wnd, Tempest::SizeEvent& event);
24+
void dispatchClose (Widget& wnd, Tempest::CloseEvent& event);
2525

26-
void dispatchFocus (Widget& wnd, Tempest::FocusEvent& event);
26+
void dispatchFocus (Widget& wnd, Tempest::FocusEvent& event);
27+
void dispatchClipboardPaste (Widget& wnd, Tempest::ClipboardEvent& event);
2728

28-
void dispatchRender (Window& wnd);
29-
void dispatchOverlayRender(Window& wnd,Tempest::PaintEvent& e);
30-
void addOverlay (UiOverlay* ui);
31-
void takeOverlay (UiOverlay* ui);
29+
void dispatchRender (Window& wnd);
30+
void dispatchOverlayRender (Window& wnd,Tempest::PaintEvent& e);
31+
void addOverlay (UiOverlay* ui);
32+
void takeOverlay (UiOverlay* ui);
3233

3334
void dispatchDestroyWindow(SystemApi::Window* w);
3435

Engine/system/systemapi.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ void SystemApi::dispatchFocus(Tempest::Window& cb, FocusEvent& e) {
152152
dispatcher.dispatchFocus(cb,e);
153153
}
154154

155+
void SystemApi::dispatchClipboardPaste(Tempest::Window& cb, ClipboardEvent& e) {
156+
dispatcher.dispatchClipboardPaste(cb,e);
157+
}
158+
155159
bool SystemApi::isRunning() {
156160
return inst().implIsRunning();
157161
}

Engine/system/systemapi.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class KeyEvent;
1515
class CloseEvent;
1616
class PaintEvent;
1717
class FocusEvent;
18+
class ClipboardEvent;
1819

1920
class Widget;
2021
class Window;
@@ -90,20 +91,21 @@ class SystemApi {
9091
static void setCursorPosition(SystemApi::Window *w, int x, int y);
9192
static void showCursor(SystemApi::Window *w, CursorShape c);
9293

93-
static void dispatchOverlayRender(Tempest::Window &w, Tempest::PaintEvent& e);
94-
static void dispatchRender (Tempest::Window& cb);
95-
static void dispatchMouseDown (Tempest::Window& cb, MouseEvent& e);
96-
static void dispatchMouseUp (Tempest::Window& cb, MouseEvent& e);
97-
static void dispatchMouseMove (Tempest::Window& cb, MouseEvent& e);
98-
static void dispatchMouseWheel(Tempest::Window& cb, MouseEvent& e);
94+
static void dispatchOverlayRender (Tempest::Window &w, Tempest::PaintEvent& e);
95+
static void dispatchRender (Tempest::Window& cb);
96+
static void dispatchMouseDown (Tempest::Window& cb, MouseEvent& e);
97+
static void dispatchMouseUp (Tempest::Window& cb, MouseEvent& e);
98+
static void dispatchMouseMove (Tempest::Window& cb, MouseEvent& e);
99+
static void dispatchMouseWheel (Tempest::Window& cb, MouseEvent& e);
99100

100-
static void dispatchKeyDown (Tempest::Window& cb, KeyEvent& e, uint32_t scancode);
101-
static void dispatchKeyUp (Tempest::Window& cb, KeyEvent& e, uint32_t scancode);
101+
static void dispatchKeyDown (Tempest::Window& cb, KeyEvent& e, uint32_t scancode);
102+
static void dispatchKeyUp (Tempest::Window& cb, KeyEvent& e, uint32_t scancode);
102103

103-
static void dispatchResize (Tempest::Window& cb, SizeEvent& e);
104-
static void dispatchClose (Tempest::Window& cb, CloseEvent& e);
104+
static void dispatchResize (Tempest::Window& cb, SizeEvent& e);
105+
static void dispatchClose (Tempest::Window& cb, CloseEvent& e);
105106

106-
static void dispatchFocus (Tempest::Window& cb, FocusEvent& e);
107+
static void dispatchFocus (Tempest::Window& cb, FocusEvent& e);
108+
static void dispatchClipboardPaste (Tempest::Window& cb, ClipboardEvent& e);
107109

108110
static SystemApi& inst();
109111

Engine/ui/event.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <Tempest/Size>
44
#include <cstdint>
5+
#include <string>
56

67
namespace Tempest {
78

@@ -40,6 +41,7 @@ class Event {
4041
Close,
4142
Polish,
4243
Gesture,
44+
Clipboard,
4345

4446
Custom = 512
4547
};
@@ -291,4 +293,11 @@ class PolishEvent: public Event {
291293
public:
292294
PolishEvent() { setType(Polish); }
293295
};
296+
297+
class ClipboardEvent: public Event {
298+
public:
299+
ClipboardEvent(const std::string& text) : text(text) { setType(Clipboard); }
300+
301+
const std::string text;
302+
};
294303
}

Engine/ui/widget.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,3 +680,7 @@ void Widget::closeEvent(CloseEvent& e) {
680680

681681
void Widget::polishEvent(PolishEvent&) {
682682
}
683+
684+
void Widget::clipboardInsertEvent(ClipboardEvent& e) {
685+
e.ignore();
686+
}

Engine/ui/widget.h

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -129,22 +129,23 @@ class Widget {
129129

130130
virtual void mouseDoubleClickEvent(Tempest::MouseEvent& event);
131131

132-
virtual void mouseDownEvent (Tempest::MouseEvent& event);
133-
virtual void mouseUpEvent (Tempest::MouseEvent& event);
134-
virtual void mouseMoveEvent (Tempest::MouseEvent& event);
135-
virtual void mouseDragEvent (Tempest::MouseEvent& event);
136-
virtual void mouseWheelEvent(Tempest::MouseEvent& event);
137-
138-
virtual void keyDownEvent (Tempest::KeyEvent& event);
139-
virtual void keyRepeatEvent (Tempest::KeyEvent& event);
140-
virtual void keyUpEvent (Tempest::KeyEvent& event);
141-
142-
virtual void mouseEnterEvent(Tempest::MouseEvent& event);
143-
virtual void mouseLeaveEvent(Tempest::MouseEvent& event);
144-
145-
virtual void focusEvent (Tempest::FocusEvent& event);
146-
virtual void closeEvent (Tempest::CloseEvent& event);
147-
virtual void polishEvent (Tempest::PolishEvent& event);
132+
virtual void mouseDownEvent (Tempest::MouseEvent& event);
133+
virtual void mouseUpEvent (Tempest::MouseEvent& event);
134+
virtual void mouseMoveEvent (Tempest::MouseEvent& event);
135+
virtual void mouseDragEvent (Tempest::MouseEvent& event);
136+
virtual void mouseWheelEvent (Tempest::MouseEvent& event);
137+
138+
virtual void keyDownEvent (Tempest::KeyEvent& event);
139+
virtual void keyRepeatEvent (Tempest::KeyEvent& event);
140+
virtual void keyUpEvent (Tempest::KeyEvent& event);
141+
142+
virtual void mouseEnterEvent (Tempest::MouseEvent& event);
143+
virtual void mouseLeaveEvent (Tempest::MouseEvent& event);
144+
145+
virtual void focusEvent (Tempest::FocusEvent& event);
146+
virtual void closeEvent (Tempest::CloseEvent& event);
147+
virtual void polishEvent (Tempest::PolishEvent& event);
148+
virtual void clipboardInsertEvent (Tempest::ClipboardEvent& event);
148149

149150
private:
150151
struct Iterator final {

0 commit comments

Comments
 (0)