Skip to content

Commit b8aa85c

Browse files
author
Tony Crisci
committed
XFixes: add XFixesSelectionNotify events
These events can be used to tell when the owner of the clipboard selection has changed. Add an example that demonstrates usage.
1 parent 8901e83 commit b8aa85c

2 files changed

Lines changed: 138 additions & 1 deletion

File tree

‎Xlib/ext/xfixes.py‎

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,22 @@
2222

2323
'''
2424
A partial implementation of the XFIXES extension. Only the HideCursor and
25-
ShowCursor requests are provided.
25+
ShowCursor requests and SelectionNotify events are provided.
2626
'''
2727

2828
from Xlib.protocol import rq
2929

3030
extname = 'XFIXES'
3131

32+
XFixesSelectionNotify = 0
33+
34+
XFixesSetSelectionOwnerNotifyMask = (1 << 0)
35+
XFixesSelectionWindowDestroyNotifyMask = (1 << 1)
36+
XFixesSelectionClientCloseNotifyMask = (1 << 2)
37+
38+
XFixesSetSelectionOwnerNotify = 0
39+
XFixesSelectionWindowDestroyNotify = 1
40+
XFixesSelectionClientCloseNotify = 2
3241

3342
class QueryVersion(rq.ReplyRequest):
3443
_request = rq.Struct(rq.Card8('opcode'),
@@ -80,8 +89,54 @@ def show_cursor(self):
8089
opcode=self.display.get_extension_major(extname),
8190
window=self)
8291

92+
class SelectSelectionInput(rq.Request):
93+
_request = rq.Struct(rq.Card8('opcode'),
94+
rq.Opcode(2),
95+
rq.RequestLength(),
96+
rq.Window('window'),
97+
rq.Card32('selection'),
98+
rq.Card32('mask')
99+
)
100+
101+
def select_selection_input(self, window, selection, mask):
102+
return SelectSelectionInput(opcode=self.display.get_extension_major(extname),
103+
display=self.display,
104+
window=window,
105+
selection=selection,
106+
mask=mask)
107+
108+
109+
class SelectionNotify(rq.Event):
110+
_code = None
111+
_fields = rq.Struct(rq.Card8('type'),
112+
rq.Card8('sub_code'),
113+
rq.Card16('sequence_number'),
114+
rq.Window('window'),
115+
rq.Window('owner'),
116+
rq.Card32('selection'),
117+
rq.Card32('timestamp'),
118+
rq.Card32('selection_timestamp'),
119+
rq.Pad(8))
120+
121+
122+
class SetSelectionOwnerNotify(SelectionNotify):
123+
pass
124+
125+
126+
class SelectionWindowDestroyNotify(SelectionNotify):
127+
pass
128+
129+
130+
class SelectionClientCloseNotify(SelectionNotify):
131+
pass
132+
83133

84134
def init(disp, info):
135+
disp.extension_add_method('display', 'xfixes_select_selection_input', select_selection_input)
85136
disp.extension_add_method('display', 'xfixes_query_version', query_version)
86137
disp.extension_add_method('window', 'xfixes_hide_cursor', hide_cursor)
87138
disp.extension_add_method('window', 'xfixes_show_cursor', show_cursor)
139+
140+
disp.extension_add_subevent(info.first_event + XFixesSelectionNotify, XFixesSetSelectionOwnerNotify, SetSelectionOwnerNotify)
141+
disp.extension_add_subevent(info.first_event + XFixesSelectionNotify, XFixesSelectionWindowDestroyNotify, SelectionWindowDestroyNotify)
142+
disp.extension_add_subevent(info.first_event + XFixesSelectionNotify, XFixesSelectionClientCloseNotify, SelectionClientCloseNotify)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/python3
2+
#
3+
# examples/xfixes-selection-notify.py -- demonstrate the XFIXES extension
4+
# SelectionNotify event.
5+
#
6+
# Copyright (C) 2019
7+
# Tony Crisci <tony@dubstepdish.com>
8+
#
9+
# This library is free software; you can redistribute it and/or
10+
# modify it under the terms of the GNU Lesser General Public License
11+
# as published by the Free Software Foundation; either version 2.1
12+
# of the License, or (at your option) any later version.
13+
#
14+
# This library is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17+
# See the GNU Lesser General Public License for more details.
18+
#
19+
# You should have received a copy of the GNU Lesser General Public
20+
# License along with this library; if not, write to the
21+
# Free Software Foundation, Inc.,
22+
# 59 Temple Place,
23+
# Suite 330,
24+
# Boston, MA 02111-1307 USA
25+
26+
# Python 2/3 compatibility.
27+
from __future__ import print_function
28+
29+
import sys
30+
import os
31+
import time
32+
33+
# Change path so we find Xlib
34+
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
35+
36+
from Xlib.display import Display
37+
from Xlib.ext import xfixes
38+
39+
def main(argv):
40+
if len(sys.argv) < 2 or len(sys.argv) > 3:
41+
sys.exit('usage: {0} SELECTION\n\n'
42+
'SELECTION is typically PRIMARY, SECONDARY or CLIPBOARD.\n'
43+
.format(sys.argv[0]))
44+
45+
display = Display()
46+
47+
sel_name = sys.argv[1]
48+
sel_atom = display.get_atom(sel_name)
49+
50+
if not display.has_extension('XFIXES'):
51+
if display.query_extension('XFIXES') is None:
52+
print('XFIXES extension not supported', file=sys.stderr)
53+
return 1
54+
55+
xfixes_version = display.xfixes_query_version()
56+
print('Found XFIXES version %s.%s' % (
57+
xfixes_version.major_version,
58+
xfixes_version.minor_version,
59+
), file=sys.stderr)
60+
61+
screen = display.screen()
62+
63+
mask = xfixes.XFixesSetSelectionOwnerNotifyMask | \
64+
xfixes.XFixesSelectionWindowDestroyNotifyMask | \
65+
xfixes.XFixesSelectionClientCloseNotifyMask
66+
67+
display.xfixes_select_selection_input(screen.root, sel_atom, mask)
68+
69+
while True:
70+
e = display.next_event()
71+
print(e)
72+
73+
if (e.type, e.sub_code) == display.extension_event.SetSelectionOwnerNotify:
74+
print('SetSelectionOwner: owner=0x{0:08x}'.format(e.owner.id))
75+
elif (e.type, e.sub_code) == display.extension_event.SelectionWindowDestroyNotify:
76+
print('SelectionWindowDestroy: owner=0x{0:08x}'.format(e.owner.id))
77+
elif (e.type, e.sub_code) == display.extension_event.SelectionClientCloseNotify:
78+
print('SelectionClientClose: owner=0x{0:08x}'.format(e.owner.id))
79+
80+
81+
if __name__ == '__main__':
82+
sys.exit(main(sys.argv))

0 commit comments

Comments
 (0)