diff --git a/backends/x/event.go b/backends/x/event.go index 4c0e4de..f5b7570 100644 --- a/backends/x/event.go +++ b/backends/x/event.go @@ -245,7 +245,17 @@ func (window *window) handleSelectionNotify ( // Follow: // https://tronche.com/gui/x/icccm/sec-2.html#s-2.4 if window.selectionRequest == nil { return } - die := func (err error) { window.selectionRequest(nil, err) } + die := func (err error) { + window.selectionRequest(nil, err) + window.selectionRequest = nil + } + + // If the property argument is None, the conversion has been refused. + // This can mean either that there is no owner for the selection, that + // the owner does not support the conversion implied by the target, or + // that the server did not have sufficient space to accommodate the + // data. + if event.Property == 0 { die(nil); return } // When using GetProperty to retrieve the value of a selection, the // property argument should be set to the corresponding value in the diff --git a/backends/x/window.go b/backends/x/window.go index df9672b..080432f 100644 --- a/backends/x/window.go +++ b/backends/x/window.go @@ -290,7 +290,10 @@ func (window *window) Paste (accept data.Mime, callback func (io.Reader, error)) // Follow: // https://tronche.com/gui/x/icccm/sec-2.html#s-2.4 - die := func (err error) { callback(nil, err) } + die := func (err error) { + window.selectionRequest = nil + callback(nil, err) + } if window.selectionRequest != nil { // TODO: add the request to a queue and take care of it when the // current selection has completed @@ -299,8 +302,10 @@ func (window *window) Paste (accept data.Mime, callback func (io.Reader, error)) selectionName := "CLIPBOARD" propertyName := "TOMO_SELECTION" - // TODO: change based on mime type - targetName := "TEXT" + targetName := accept.String() + if accept == data.M("text", "plain") { + targetName = "UTF8_STRING" + } // get atoms selectionAtom, err := xprop.Atm(window.backend.connection, selectionName) diff --git a/data/data.go b/data/data.go index e47497e..c92eeca 100644 --- a/data/data.go +++ b/data/data.go @@ -16,6 +16,16 @@ type Mime struct { Type, Subtype string } +// M is shorthand for creating a MIME type. +func M (ty, subtype string) Mime { + return Mime { ty, subtype } +} + +// String returns the string representation of the MIME type. +func (mime Mime) String () string { + return mime.Type + "/" + mime.Subtype +} + var MimePlain = Mime { "text", "plain" } var MimeFile = Mime { "text", "uri-list" } diff --git a/examples/clipboard/main.go b/examples/clipboard/main.go index 391e66d..12a4535 100644 --- a/examples/clipboard/main.go +++ b/examples/clipboard/main.go @@ -26,16 +26,24 @@ func run () { pasteButton := basicElements.NewButton("Paste") pasteButton.SetIcon(theme.IconPaste) - clipboardCallback := func (clipboard io.Reader, err error) { + clipboardCallback := func (clipboard io.Reader, err error) { if err != nil { popups.NewDialog ( popups.DialogKindError, window, "Error", - "No text data in clipboard:\n" + err.Error()) + "Cannot get clipboard:\n" + err.Error()) + return + } + + if clipboard == nil { + popups.NewDialog ( + popups.DialogKindError, + window, + "Clipboard Empty", + "No text data in clipboard") return } - text, _ := io.ReadAll(clipboard) tomo.Do (func () {