Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Unified Diff: ui/base/clipboard/clipboard_gtk.cc

Issue 8501002: Use XFixes to update the clipboard sequence number. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/linux/system.gyp ('k') | ui/ui.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/base/clipboard/clipboard_gtk.cc
diff --git a/ui/base/clipboard/clipboard_gtk.cc b/ui/base/clipboard/clipboard_gtk.cc
index f51ba8a1a996d0581135f148d3b7a781dbbf4b39..e9af2f330d8fd5d95480ffb031ea595b1610ea36 100644
--- a/ui/base/clipboard/clipboard_gtk.cc
+++ b/ui/base/clipboard/clipboard_gtk.cc
@@ -5,6 +5,8 @@
#include "ui/base/clipboard/clipboard.h"
#include <gtk/gtk.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/Xatom.h>
#include <map>
#include <set>
#include <string>
@@ -12,9 +14,11 @@
#include "base/file_path.h"
#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
#include "base/utf_string_conversions.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/gtk/gtk_signal.h"
+#include "ui/base/x/x11_util.h"
#include "ui/gfx/canvas_skia.h"
#include "ui/gfx/gtk_util.h"
#include "ui/gfx/size.h"
@@ -23,6 +27,82 @@ namespace ui {
namespace {
+class SelectionChangeObserver {
+ public:
+ static SelectionChangeObserver* GetInstance();
+
+ uint64 clipboard_sequence_number() const {
+ return clipboard_sequence_number_;
+ }
+ uint64 primary_sequence_number() const { return primary_sequence_number_; }
+
+ private:
+ friend struct DefaultSingletonTraits<SelectionChangeObserver>;
+
+ SelectionChangeObserver();
+ ~SelectionChangeObserver();
+
+ CHROMEG_CALLBACK_1(SelectionChangeObserver, GdkFilterReturn, OnXEvent,
+ GdkXEvent*, GdkEvent*);
+
+ int event_base_;
+ Atom clipboard_atom_;
+ uint64 clipboard_sequence_number_;
+ uint64 primary_sequence_number_;
+
+ DISALLOW_COPY_AND_ASSIGN(SelectionChangeObserver);
+};
+
+SelectionChangeObserver::SelectionChangeObserver()
+ : event_base_(-1),
+ clipboard_atom_(None),
+ clipboard_sequence_number_(0),
+ primary_sequence_number_(0) {
+ int ignored;
+ if (XFixesQueryExtension(GetXDisplay(), &event_base_, &ignored)) {
+ clipboard_atom_ = XInternAtom(GetXDisplay(), "CLIPBOARD", false);
+ XFixesSelectSelectionInput(GetXDisplay(), GetX11RootWindow(),
+ clipboard_atom_,
+ XFixesSetSelectionOwnerNotifyMask |
+ XFixesSelectionWindowDestroyNotifyMask |
+ XFixesSelectionClientCloseNotifyMask);
+ // This seems to be semi-optional. For some reason, registering for any
+ // selection notify events seems to subscribe us to events for both the
+ // primary and the clipboard buffers. Register anyway just to be safe.
+ XFixesSelectSelectionInput(GetXDisplay(), GetX11RootWindow(),
+ XA_PRIMARY,
+ XFixesSetSelectionOwnerNotifyMask |
+ XFixesSelectionWindowDestroyNotifyMask |
+ XFixesSelectionClientCloseNotifyMask);
+ gdk_window_add_filter(NULL, &SelectionChangeObserver::OnXEventThunk, this);
+ }
+}
+
+SelectionChangeObserver::~SelectionChangeObserver() {
+}
+
+SelectionChangeObserver* SelectionChangeObserver::GetInstance() {
+ return Singleton<SelectionChangeObserver>::get();
+}
+
+GdkFilterReturn SelectionChangeObserver::OnXEvent(GdkXEvent* xevent,
+ GdkEvent* event) {
+ XEvent* xev = static_cast<XEvent*>(xevent);
+
+ if (xev->type == event_base_ + XFixesSelectionNotify) {
+ XFixesSelectionNotifyEvent* ev =
+ reinterpret_cast<XFixesSelectionNotifyEvent*>(xev);
+ if (ev->selection == clipboard_atom_) {
+ clipboard_sequence_number_++;
+ } else if (ev->selection == XA_PRIMARY) {
+ primary_sequence_number_++;
+ } else {
+ DLOG(ERROR) << "Unexpected selection atom: " << ev->selection;
+ }
+ }
+ return GDK_FILTER_CONTINUE;
+}
+
const char kMimeTypeBitmap[] = "image/bmp";
const char kMimeTypeMozillaURL[] = "text/x-moz-url";
const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
@@ -423,10 +503,10 @@ void Clipboard::ReadData(const std::string& format, std::string* result) {
}
uint64 Clipboard::GetSequenceNumber(Buffer buffer) {
- // TODO(cdn): implement this. For now this interface will advertise
- // that the Linux clipboard never changes. That's fine as long as we
- // don't rely on this signal.
- return 0;
+ if (buffer == BUFFER_STANDARD)
+ return SelectionChangeObserver::GetInstance()->clipboard_sequence_number();
+ else
+ return SelectionChangeObserver::GetInstance()->primary_sequence_number();
}
// static
« no previous file with comments | « build/linux/system.gyp ('k') | ui/ui.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698