Made event selection a little more robust. Also fixed failure

to marshall clipboard data when updating primary clipboards.
This commit is contained in:
crs 2002-04-29 14:08:48 +00:00
parent 6299eea7b6
commit 6a9a180688
7 changed files with 43 additions and 7 deletions

View File

@ -319,7 +319,7 @@ void CXWindowsSecondaryScreen::onOpenDisplay()
// as the cursor enters the screen or the display's real cursor is // as the cursor enters the screen or the display's real cursor is
// moved. // moved.
XSetWindowAttributes attr; XSetWindowAttributes attr;
attr.event_mask = LeaveWindowMask | PropertyChangeMask; attr.event_mask = LeaveWindowMask;
attr.do_not_propagate_mask = 0; attr.do_not_propagate_mask = 0;
attr.override_redirect = True; attr.override_redirect = True;
attr.cursor = createBlankCursor(); attr.cursor = createBlankCursor();
@ -349,6 +349,14 @@ void CXWindowsSecondaryScreen::onCloseDisplay()
m_window = None; m_window = None;
} }
long CXWindowsSecondaryScreen::getEventMask(Window w) const
{
if (w == m_window)
return LeaveWindowMask;
else
return NoEventMask;
}
void CXWindowsSecondaryScreen::leaveNoLock(Display* display) void CXWindowsSecondaryScreen::leaveNoLock(Display* display)
{ {
assert(display != NULL); assert(display != NULL);

View File

@ -34,6 +34,7 @@ class CXWindowsSecondaryScreen : public CXWindowsScreen, public ISecondaryScreen
// CXWindowsScreen overrides // CXWindowsScreen overrides
virtual void onOpenDisplay(); virtual void onOpenDisplay();
virtual void onCloseDisplay(); virtual void onCloseDisplay();
virtual long getEventMask(Window) const;
private: private:
struct KeyCodeMask { struct KeyCodeMask {

View File

@ -950,6 +950,8 @@ void CServer::updatePrimaryClipboard(ClipboardID id)
// if clipboard changed then other screens have an // if clipboard changed then other screens have an
// out-of-date clipboard. // out-of-date clipboard.
if (time != clipboard.m_clipboard.getTime()) { if (time != clipboard.m_clipboard.getTime()) {
log((CLOG_DEBUG "clipboard %d changed", id));
clipboard.m_clipboardData = clipboard.m_clipboard.marshall();
clearGotClipboard(id); clearGotClipboard(id);
m_primaryInfo->m_gotClipboard[id] = true; m_primaryInfo->m_gotClipboard[id] = true;
} }

View File

@ -406,6 +406,17 @@ void CXWindowsPrimaryScreen::onCloseDisplay()
m_window = None; m_window = None;
} }
long CXWindowsPrimaryScreen::getEventMask(Window w) const
{
if (w == m_window)
return PointerMotionMask |// PointerMotionHintMask |
ButtonPressMask | ButtonReleaseMask |
KeyPressMask | KeyReleaseMask |
KeymapStateMask;
else
return PointerMotionMask | SubstructureNotifyMask;
}
void CXWindowsPrimaryScreen::selectEvents( void CXWindowsPrimaryScreen::selectEvents(
Display* display, Window w) const Display* display, Window w) const
{ {
@ -419,8 +430,7 @@ void CXWindowsPrimaryScreen::selectEvents(
return; return;
// select events of interest // select events of interest
XSelectInput(display, w, PointerMotionMask | SubstructureNotifyMask | XSelectInput(display, w, PointerMotionMask | SubstructureNotifyMask);
PropertyChangeMask);
// recurse on child windows // recurse on child windows
Window rw, pw, *cw; Window rw, pw, *cw;

View File

@ -29,6 +29,7 @@ class CXWindowsPrimaryScreen : public CXWindowsScreen, public IPrimaryScreen {
// CXWindowsScreen overrides // CXWindowsScreen overrides
virtual void onOpenDisplay(); virtual void onOpenDisplay();
virtual void onCloseDisplay(); virtual void onCloseDisplay();
virtual long getEventMask(Window) const;
private: private:
void selectEvents(Display*, Window) const; void selectEvents(Display*, Window) const;

View File

@ -672,7 +672,7 @@ void CXWindowsScreen::processClipboardRequest(
clipboard.m_requests.erase(index); clipboard.m_requests.erase(index);
delete list; delete list;
} }
XSelectInput(m_display, requestor, NoEventMask); XSelectInput(m_display, requestor, getEventMask(requestor));
} }
// request has been serviced // request has been serviced
@ -765,9 +765,12 @@ bool CXWindowsScreen::sendClipboardData(
list->push_back(request); list->push_back(request);
// start watching requestor for property changes and // start watching requestor for property changes and
// destruction // destruction, in addition to other events required by
XSelectInput(m_display, requestor, StructureNotifyMask | // the subclass.
PropertyChangeMask); XSelectInput(m_display, requestor,
getEventMask(requestor) |
StructureNotifyMask |
PropertyChangeMask);
// FIXME -- handle Alloc errors (by returning false) // FIXME -- handle Alloc errors (by returning false)
// set property to INCR // set property to INCR
@ -968,6 +971,11 @@ Time CXWindowsScreen::getCurrentTime(Window window) const
Time CXWindowsScreen::getCurrentTimeNoLock( Time CXWindowsScreen::getCurrentTimeNoLock(
Window window) const Window window) const
{ {
// select property events on window
// note -- this will break clipboard transfer if used on a requestor
// window, so don't do that.
XSelectInput(m_display, window, getEventMask(window) | PropertyChangeMask);
// do a zero-length append to get the current time // do a zero-length append to get the current time
unsigned char dummy; unsigned char dummy;
XChangeProperty(m_display, window, m_atomSynergyTime, XChangeProperty(m_display, window, m_atomSynergyTime,
@ -992,6 +1000,9 @@ Time CXWindowsScreen::getCurrentTimeNoLock(
assert(xevent.xproperty.window == window); assert(xevent.xproperty.window == window);
assert(xevent.xproperty.atom == m_atomSynergyTime); assert(xevent.xproperty.atom == m_atomSynergyTime);
// restore event mask
XSelectInput(m_display, window, getEventMask(window));
return xevent.xproperty.time; return xevent.xproperty.time;
} }

View File

@ -101,6 +101,9 @@ class CXWindowsScreen {
// called by closeDisplay() to // called by closeDisplay() to
virtual void onCloseDisplay() = 0; virtual void onCloseDisplay() = 0;
// get the X event mask required by the subclass for the given window
virtual long getEventMask(Window) const = 0;
private: private:
struct CPropertyNotifyInfo { struct CPropertyNotifyInfo {
public: public: