refactor: use Mutex to protect vars in XWindowClipboard

This commit is contained in:
sithlord48 2026-06-18 20:30:04 -04:00 committed by Chris Rizzitello
parent 81e6e13d94
commit 0042b43bac
2 changed files with 15 additions and 1 deletions

View file

@ -231,6 +231,7 @@ Atom XWindowsClipboard::getSelection() const
bool XWindowsClipboard::empty() bool XWindowsClipboard::empty()
{ {
std::scoped_lock lock{m_mutex};
assert(m_open); assert(m_open);
LOG_DEBUG("empty clipboard %d", m_id); LOG_DEBUG("empty clipboard %d", m_id);
@ -277,6 +278,7 @@ void XWindowsClipboard::add(Format format, const std::string &data)
bool XWindowsClipboard::open(Time time) const bool XWindowsClipboard::open(Time time) const
{ {
std::scoped_lock lock{m_mutex};
if (m_open) { if (m_open) {
LOG_WARN("failed to open clipboard: already opened"); LOG_WARN("failed to open clipboard: already opened");
return false; return false;
@ -318,6 +320,7 @@ void XWindowsClipboard::close() const
LOG_DEBUG("close clipboard %d", m_id); LOG_DEBUG("close clipboard %d", m_id);
std::scoped_lock lock{m_mutex};
// unlock clipboard // unlock clipboard
if (m_motif) { if (m_motif) {
motifUnlockClipboard(); motifUnlockClipboard();
@ -330,6 +333,7 @@ void XWindowsClipboard::close() const
IClipboard::Time XWindowsClipboard::getTime() const IClipboard::Time XWindowsClipboard::getTime() const
{ {
checkCache(); checkCache();
std::scoped_lock lock{m_mutex};
return m_timeOwned; return m_timeOwned;
} }
@ -382,6 +386,7 @@ IXWindowsClipboardConverter *XWindowsClipboard::getConverter(Atom target, bool o
void XWindowsClipboard::checkCache() const void XWindowsClipboard::checkCache() const
{ {
std::scoped_lock lock{m_mutex};
if (!m_checkCache) { if (!m_checkCache) {
return; return;
} }
@ -413,6 +418,7 @@ void XWindowsClipboard::clearCache() const
void XWindowsClipboard::doClearCache() void XWindowsClipboard::doClearCache()
{ {
std::scoped_lock lock{m_mutex};
m_checkCache = false; m_checkCache = false;
m_cached = false; m_cached = false;
for (int32_t index = 0; index < static_cast<int>(Format::TotalFormats); ++index) { for (int32_t index = 0; index < static_cast<int>(Format::TotalFormats); ++index) {
@ -432,6 +438,7 @@ void XWindowsClipboard::fillCache() const
void XWindowsClipboard::doFillCache() void XWindowsClipboard::doFillCache()
{ {
std::scoped_lock lock{m_mutex};
if (m_motif) { if (m_motif) {
motifFillCache(); motifFillCache();
} else { } else {
@ -517,6 +524,7 @@ bool XWindowsClipboard::icccmGetSelection(Atom target, Atom *actualTarget, std::
assert(actualTarget != nullptr); assert(actualTarget != nullptr);
assert(data != nullptr); assert(data != nullptr);
std::scoped_lock lock{m_mutex};
// request data conversion // request data conversion
if (CICCCMGetClipboard getter(m_window, m_time, m_atomData); if (CICCCMGetClipboard getter(m_window, m_time, m_atomData);
!getter.readClipboard(m_display, m_selection, target, actualTarget, data)) { !getter.readClipboard(m_display, m_selection, target, actualTarget, data)) {
@ -977,6 +985,7 @@ bool XWindowsClipboard::sendReply(Reply *reply)
} }
if (!reply->m_replied) { if (!reply->m_replied) {
std::scoped_lock lock{m_mutex};
sendNotify(reply->m_requestor, m_selection, reply->m_target, None, reply->m_time); sendNotify(reply->m_requestor, m_selection, reply->m_target, None, reply->m_time);
// don't wait for any reply (because we're not expecting one) // don't wait for any reply (because we're not expecting one)
@ -1002,6 +1011,7 @@ bool XWindowsClipboard::sendReply(Reply *reply)
// nothing to log // nothing to log
if (CLOG->getFilter() < LogLevel::Level::Verbose) { if (CLOG->getFilter() < LogLevel::Level::Verbose) {
std::scoped_lock lock{m_mutex};
sendNotify( sendNotify(
reply->m_requestor, m_selection, reply->m_target, reply->m_property, static_cast<unsigned int>(reply->m_time) reply->m_requestor, m_selection, reply->m_target, reply->m_property, static_cast<unsigned int>(reply->m_time)
); );
@ -1050,7 +1060,7 @@ bool XWindowsClipboard::sendReply(Reply *reply)
if (props != nullptr) { if (props != nullptr) {
XFree(props); XFree(props);
} }
std::scoped_lock lck{m_mutex};
sendNotify(reply->m_requestor, m_selection, reply->m_target, reply->m_property, reply->m_time); sendNotify(reply->m_requestor, m_selection, reply->m_target, reply->m_property, reply->m_time);
// wait for delete notify // wait for delete notify
@ -1092,6 +1102,7 @@ bool XWindowsClipboard::wasOwnedAtTime(::Time time) const
{ {
// not owned if we've never owned the selection // not owned if we've never owned the selection
checkCache(); checkCache();
std::scoped_lock lock{m_mutex};
if (m_timeOwned == 0) { if (m_timeOwned == 0) {
return false; return false;
} }
@ -1147,6 +1158,7 @@ Atom XWindowsClipboard::getTimestampData(std::string &data, int *format) const
assert(format != nullptr); assert(format != nullptr);
checkCache(); checkCache();
std::scoped_lock lock{m_mutex};
XWindowsUtil::appendTimeData(data, m_timeOwned); XWindowsUtil::appendTimeData(data, m_timeOwned);
*format = 32; *format = 32;
return m_atomInteger; return m_atomInteger;

View file

@ -15,6 +15,7 @@
#include <list> #include <list>
#include <map> #include <map>
#include <mutex>
#include <vector> #include <vector>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -286,6 +287,7 @@ private:
Window m_window; Window m_window;
ClipboardID m_id; ClipboardID m_id;
Atom m_selection; Atom m_selection;
mutable std::mutex m_mutex;
mutable bool m_open = false; mutable bool m_open = false;
mutable Time m_time = 0; mutable Time m_time = 0;
bool m_owner = false; bool m_owner = false;