Implement the different copy buffer...
...for mouse selection and keyboard copy under X11 systems. The old widget library doesn't use it the new one does.
This commit is contained in:
parent
f130a87cb1
commit
174966c394
6 changed files with 83 additions and 48 deletions
|
@ -4,6 +4,9 @@ Version 1.5.0+svn:
|
|||
* terrains:
|
||||
* Reorganisation of the terrain macros including more consistent image naming.
|
||||
The old macros are kept for now for compatibility.
|
||||
* miscellaneous and bug fixes:
|
||||
* Implemented the option to use the mouse selection clipboard in X11
|
||||
the new widget library also uses it.
|
||||
|
||||
Version 1.5.0:
|
||||
* campaigns:
|
||||
|
|
|
@ -178,6 +178,12 @@ public:
|
|||
*/
|
||||
static std::string clipboard_string;
|
||||
|
||||
/**
|
||||
The following string is used for the mouse selection aka PRIMARY
|
||||
Unix behaviour is mouse selection is stored in primary
|
||||
active selection goes to CLIPBOARD.
|
||||
*/
|
||||
static std::string primary_string;
|
||||
|
||||
void handle_system_event(const SDL_Event& event)
|
||||
{
|
||||
|
@ -221,15 +227,19 @@ void handle_system_event(const SDL_Event& event)
|
|||
// The encoding of XA_TEXT and XA_COMPOUND_TEXT is not specified
|
||||
// by the ICCCM... So we assume wesnoth native/utf-8 for simplicity.
|
||||
// Modern apps are going to use UTF8_STRING anyway.
|
||||
if (xev.xselectionrequest.target == x11->XA_TEXT() ||
|
||||
xev.xselectionrequest.target == x11->XA_COMPOUND_TEXT() ||
|
||||
xev.xselectionrequest.target == x11->UTF8_STRING()) {
|
||||
if (xev.xselectionrequest.target == x11->XA_TEXT()
|
||||
|| xev.xselectionrequest.target == x11->XA_COMPOUND_TEXT()
|
||||
|| xev.xselectionrequest.target == x11->UTF8_STRING()) {
|
||||
|
||||
responseEvent.xselection.property = xev.xselectionrequest.property;
|
||||
|
||||
std::string& selection = (xev.xselectionrequest.selection == XA_PRIMARY) ?
|
||||
primary_string : clipboard_string;
|
||||
|
||||
XChangeProperty(x11->dpy(), responseEvent.xselection.requestor,
|
||||
xev.xselectionrequest.property,
|
||||
xev.xselectionrequest.target, 8, PropModeReplace,
|
||||
reinterpret_cast<const unsigned char*>(clipboard_string.c_str()), clipboard_string.length());
|
||||
reinterpret_cast<const unsigned char*>(selection.c_str()), selection.length());
|
||||
}
|
||||
|
||||
XSendEvent(x11->dpy(), xev.xselectionrequest.requestor, False, NoEventMask,
|
||||
|
@ -238,34 +248,38 @@ void handle_system_event(const SDL_Event& event)
|
|||
}
|
||||
|
||||
if (xev.type == SelectionClear) {
|
||||
//We no longer own the clipboard, don't try in-process C&P
|
||||
UseX x11;
|
||||
|
||||
if (xev.xselectionclear.selection == x11->XA_CLIPBOARD()
|
||||
|| xev.xselectionclear.selection == XA_PRIMARY) {
|
||||
|
||||
clipboard_string = ""; //We no longer own the clipboard, don't try in-process C&P
|
||||
if(xev.xselectionclear.selection == x11->XA_CLIPBOARD()) {
|
||||
clipboard_string.clear();
|
||||
} else if(xev.xselectionclear.selection == XA_PRIMARY) {
|
||||
primary_string.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void copy_to_clipboard(const std::string& text)
|
||||
void copy_to_clipboard(const std::string& text, const bool mouse)
|
||||
{
|
||||
if (text.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
clipboard_string = text;
|
||||
|
||||
UseX x11;
|
||||
|
||||
XSetSelectionOwner(x11->dpy(), XA_PRIMARY, x11->window(), CurrentTime);
|
||||
XSetSelectionOwner(x11->dpy(), x11->XA_CLIPBOARD(), x11->window(), CurrentTime);
|
||||
if(mouse) {
|
||||
primary_string = text;
|
||||
XSetSelectionOwner(x11->dpy(), XA_PRIMARY, x11->window(), CurrentTime);
|
||||
} else {
|
||||
clipboard_string = text;
|
||||
XSetSelectionOwner(x11->dpy(), x11->XA_CLIPBOARD(), x11->window(), CurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Tries to grab a given target.
|
||||
//! Returns true if successful, false otherwise.
|
||||
static bool try_grab_target(Atom target, std::string& ret)
|
||||
static bool try_grab_target(Atom source, Atom target, std::string& ret)
|
||||
{
|
||||
UseX x11;
|
||||
|
||||
|
@ -276,7 +290,7 @@ static bool try_grab_target(Atom target, std::string& ret)
|
|||
//std::cout<<"We request target:"<<XGetAtomName(x11->dpy(), target)<<"\n";
|
||||
|
||||
// Request information
|
||||
XConvertSelection(x11->dpy(), x11->XA_CLIPBOARD(), target,
|
||||
XConvertSelection(x11->dpy(), source, target,
|
||||
x11->WES_PASTE(), x11->window(), CurrentTime);
|
||||
|
||||
// Wait (with timeout) for a response SelectionNotify
|
||||
|
@ -324,25 +338,31 @@ static bool try_grab_target(Atom target, std::string& ret)
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string copy_from_clipboard()
|
||||
{
|
||||
if (!clipboard_string.empty())
|
||||
return clipboard_string; // in-wesnoth copy-paste
|
||||
|
||||
std::string ret;
|
||||
std::string copy_from_clipboard(const bool mouse)
|
||||
{
|
||||
// in-wesnoth copy-paste
|
||||
if(mouse && !primary_string.empty()) {
|
||||
return primary_string;
|
||||
}
|
||||
if (!mouse && !clipboard_string.empty()) {
|
||||
return clipboard_string;
|
||||
}
|
||||
|
||||
UseX x11;
|
||||
|
||||
if (try_grab_target(x11->UTF8_STRING(), ret))
|
||||
std::string ret;
|
||||
const Atom& source = mouse ? XA_PRIMARY : x11->XA_CLIPBOARD();
|
||||
|
||||
if (try_grab_target(source, x11->UTF8_STRING(), ret))
|
||||
return ret;
|
||||
|
||||
if (try_grab_target(x11->XA_COMPOUND_TEXT(), ret))
|
||||
if (try_grab_target(source, x11->XA_COMPOUND_TEXT(), ret))
|
||||
return ret;
|
||||
|
||||
if (try_grab_target(x11->XA_TEXT(), ret))
|
||||
if (try_grab_target(source, x11->XA_TEXT(), ret))
|
||||
return ret;
|
||||
|
||||
if (try_grab_target(XA_STRING, ret)) // acroread only provides this
|
||||
if (try_grab_target(source, XA_STRING, ret)) // acroread only provides this
|
||||
return ret;
|
||||
|
||||
|
||||
|
@ -358,7 +378,7 @@ std::string copy_from_clipboard()
|
|||
void handle_system_event(const SDL_Event& )
|
||||
{}
|
||||
|
||||
void copy_to_clipboard(const std::string& text)
|
||||
void copy_to_clipboard(const std::string& text, const bool)
|
||||
{
|
||||
if(text.empty())
|
||||
return;
|
||||
|
@ -393,7 +413,7 @@ void copy_to_clipboard(const std::string& text)
|
|||
CloseClipboard();
|
||||
}
|
||||
|
||||
std::string copy_from_clipboard()
|
||||
std::string copy_from_clipboard(const bool)
|
||||
{
|
||||
if(!IsClipboardFormatAvailable(CF_TEXT))
|
||||
return "";
|
||||
|
@ -427,7 +447,7 @@ std::string copy_from_clipboard()
|
|||
|
||||
#define CLIPBOARD_FUNCS_DEFINED
|
||||
|
||||
void copy_to_clipboard(const std::string& text)
|
||||
void copy_to_clipboard(const std::string& text, const bool)
|
||||
{
|
||||
BMessage *clip;
|
||||
if (be_clipboard->Lock())
|
||||
|
@ -442,7 +462,7 @@ void copy_to_clipboard(const std::string& text)
|
|||
}
|
||||
}
|
||||
|
||||
std::string copy_from_clipboard()
|
||||
std::string copy_from_clipboard(const bool)
|
||||
{
|
||||
const char* data;
|
||||
ssize_t size;
|
||||
|
@ -464,7 +484,7 @@ std::string copy_from_clipboard()
|
|||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
void copy_to_clipboard(const std::string& text)
|
||||
void copy_to_clipboard(const std::string& text, const bool)
|
||||
{
|
||||
std::string new_str;
|
||||
new_str.reserve(text.size());
|
||||
|
@ -486,7 +506,7 @@ void copy_to_clipboard(const std::string& text)
|
|||
PutScrapFlavor(scrap, kScrapFlavorTypeText, kScrapFlavorMaskNone, text.size(), new_str.c_str());
|
||||
}
|
||||
|
||||
std::string copy_from_clipboard()
|
||||
std::string copy_from_clipboard(const bool)
|
||||
{
|
||||
ScrapRef curscrap = kScrapRefNone;
|
||||
Size scrapsize = 0;
|
||||
|
@ -515,11 +535,11 @@ void handle_system_event(const SDL_Event& event)
|
|||
|
||||
#ifndef CLIPBOARD_FUNCS_DEFINED
|
||||
|
||||
void copy_to_clipboard(const std::string& text)
|
||||
void copy_to_clipboard(const std::string& text, const bool)
|
||||
{
|
||||
}
|
||||
|
||||
std::string copy_from_clipboard()
|
||||
std::string copy_from_clipboard(const bool)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -21,8 +21,20 @@
|
|||
#include <string>
|
||||
#include "SDL.h"
|
||||
#include "serialization/string_utils.hpp"
|
||||
void copy_to_clipboard(const std::string& text);
|
||||
std::string copy_from_clipboard();
|
||||
//! Copies text to the clipboard.
|
||||
//!
|
||||
//! @param text The text to copy.
|
||||
//! @param mouse Is the selection done by the mouse? On UNIX systems there
|
||||
//! are multiple clipboards and the mouse selction uses a
|
||||
//! different clipboard. Ignored on other systems.
|
||||
void copy_to_clipboard(const std::string& text, const bool mouse);
|
||||
|
||||
//! Copies text from the clipboard.
|
||||
//!
|
||||
//! @param mouse Is the pasting done by the mouse?
|
||||
//!
|
||||
//! @returns String on clipbaord.
|
||||
std::string copy_from_clipboard(const bool mouse);
|
||||
|
||||
#if defined(_X11) && !defined(__APPLE__)
|
||||
void handle_system_event(const SDL_Event& ev);
|
||||
|
|
|
@ -53,7 +53,7 @@ void ttext_::set_cursor(const size_t offset, const bool select)
|
|||
|
||||
#ifdef __unix__
|
||||
// selecting copies on UNIX systems.
|
||||
copy_selection();
|
||||
copy_selection(true);
|
||||
#endif
|
||||
set_canvas_text();
|
||||
set_dirty();
|
||||
|
@ -106,7 +106,7 @@ void ttext_::mouse_middle_button_click(tevent_handler&)
|
|||
DBG_G_E << "Text_box: middle mouse button click.\n";
|
||||
#ifdef __unix__
|
||||
// pastes on UNIX systems.
|
||||
paste_selection();
|
||||
paste_selection(true);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ void ttext_::key_press(tevent_handler& /*event*/, bool& handled, SDLKey key, SDL
|
|||
|
||||
// atm we don't care whether there is something to copy or paste
|
||||
// if nothing is there we still don't want to be chained.
|
||||
copy_selection();
|
||||
copy_selection(false);
|
||||
handled = true;
|
||||
break;
|
||||
|
||||
|
@ -212,7 +212,7 @@ void ttext_::key_press(tevent_handler& /*event*/, bool& handled, SDLKey key, SDL
|
|||
break;
|
||||
}
|
||||
|
||||
copy_selection();
|
||||
copy_selection(false);
|
||||
delete_selection();
|
||||
handled = true;
|
||||
break;
|
||||
|
@ -223,7 +223,7 @@ void ttext_::key_press(tevent_handler& /*event*/, bool& handled, SDLKey key, SDL
|
|||
break;
|
||||
}
|
||||
|
||||
paste_selection();
|
||||
paste_selection(false);
|
||||
handled = true;
|
||||
break;
|
||||
|
||||
|
@ -257,7 +257,7 @@ void ttext_::set_state(tstate state)
|
|||
}
|
||||
|
||||
//! Copies the current selection.
|
||||
void ttext_::copy_selection()
|
||||
void ttext_::copy_selection(const bool mouse)
|
||||
{
|
||||
int len = sel_len();
|
||||
unsigned start = sel_start();
|
||||
|
@ -269,13 +269,13 @@ void ttext_::copy_selection()
|
|||
|
||||
const wide_string& wtext = utils::string_to_wstring(text_);
|
||||
const std::string& text = utils::wstring_to_string(wide_string(wtext.begin() + start, wtext.begin() + start +len));
|
||||
copy_to_clipboard(text);
|
||||
copy_to_clipboard(text, mouse);
|
||||
}
|
||||
|
||||
//! Pastes the current selection.
|
||||
void ttext_::paste_selection()
|
||||
void ttext_::paste_selection(const bool mouse)
|
||||
{
|
||||
const std::string& text = copy_from_clipboard();
|
||||
const std::string& text = copy_from_clipboard(mouse);
|
||||
if(text.empty()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -85,10 +85,10 @@ protected:
|
|||
virtual void delete_selection() = 0;
|
||||
|
||||
//! Copies the current selection.
|
||||
virtual void copy_selection();
|
||||
virtual void copy_selection(const bool mouse);
|
||||
|
||||
//! Pastes the current selection.
|
||||
virtual void paste_selection();
|
||||
virtual void paste_selection(const bool mouse);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -554,7 +554,7 @@ void textbox::handle_event(const SDL_Event& event)
|
|||
if(is_selection())
|
||||
erase_selection();
|
||||
|
||||
std::string str = copy_from_clipboard();
|
||||
std::string str = copy_from_clipboard(false);
|
||||
|
||||
//cut off anything after the first newline
|
||||
str.erase(std::find_if(str.begin(),str.end(),utils::isnewline),str.end());
|
||||
|
@ -580,7 +580,7 @@ void textbox::handle_event(const SDL_Event& event)
|
|||
|
||||
wide_string ws = wide_string(text_.begin() + beg, text_.begin() + end);
|
||||
std::string s = utils::wstring_to_string(ws);
|
||||
copy_to_clipboard(s);
|
||||
copy_to_clipboard(s, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue