Bug 100443 - Copy/Cut/Paste shortcut keys not recognized
Summary: Copy/Cut/Paste shortcut keys not recognized
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: LibreOffice (show other bugs)
Version:
(earliest affected)
4.2 all versions
Hardware: x86 (IA32) Linux (All)
: medium minor
Assignee: Caolán McNamara
URL:
Whiteboard: target:5.3.0
Keywords:
Depends on:
Blocks:
 
Reported: 2016-06-16 20:58 UTC by Charles Lindsey
Modified: 2016-09-24 16:27 UTC (History)
3 users (show)

See Also:
Crash report or crash signature:


Attachments
A new version of GetKeyCode() to insert into gtksalframe.cxx (10.14 KB, text/plain)
2016-06-30 19:38 UTC, Charles Lindsey
Details
A new version of SalDisplay::GetKeyName() to insert into accfg.cxx (5.94 KB, text/plain)
2016-06-30 19:43 UTC, Charles Lindsey
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Charles Lindsey 2016-06-16 20:58:01 UTC
Using a Sun Type 6 keyboard on an i86 Linux system.
Keys such as SunFront and Find (indeed most keysyms in /usr/lib/X11/keysymdef.h) can be used, but the Copy key, in xev, shows
        state 0x0, keycode 141 (keysym 0x1008ff57, XF86Copy), same_screen YES,
where that keysym is defined in /usr/lib/X11/XF86keysym.h. Likewise Cut and Paste. These keys are not recognized.

Realizing that this Bug is likely to be of low priority in getting fixed, I have been poking around in the Source Code in docs.libreoffice.org, and I am willing to poke around further if someone here will provide a little assistance; but at the moment I am lost "in a maze of little twisty passages, all alike". Here is what I have established so far:

Using gdb on soffice.bin, with a breakpoint at svt::AcceleratorExecute::execute and pressing the SunProps key (which is recognized but not attached to any shortcut) I get the stacktrace:

#0  0xb5a0f716 in svt::AcceleratorExecute::execute(KeyCode const&) ()
   from /usr/lib/libreoffice/program/libmergedlo.so
#1  0xb579f950 in ?? () from /usr/lib/libreoffice/program/libmergedlo.so
#2  0xb579fa47 in SfxViewShell::KeyInput(KeyEvent const&) ()
   from /usr/lib/libreoffice/program/libmergedlo.so
#3  0xaa36d17e in ?? () from /usr/lib/libreoffice/program/../program/libswlo.so
#4  0xb681372f in ?? () from /usr/lib/libreoffice/program/libmergedlo.so
#5  0xb68165e5 in ?? () from /usr/lib/libreoffice/program/libmergedlo.so
#6  0xaf920b1c in ?? () from /usr/lib/libreoffice/program/libvclplug_gtklo.so
#7  0xaf92284d in ?? () from /usr/lib/libreoffice/program/libvclplug_gtklo.so
#8  0xb356febe in ?? () from /usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0
#9  0xb3abfa7e in g_closure_invoke ()
   from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
#10 0xb3ad2029 in ?? () from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
#11 0xb3ad968f in g_signal_emit_valist ()
   from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
#12 0xb3ad9bf3 in g_signal_emit () from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
#13 0xb369ca03 in ?? () from /usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0
#14 0xb356e36c in gtk_propagate_event ()
   from /usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0
#15 0xb356e690 in gtk_main_do_event ()
   from /usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0
#16 0xb33e81b8 in ?? () from /usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0
#17 0xb40411e3 in g_main_context_dispatch ()
   from /lib/i386-linux-gnu/libglib-2.0.so.0
#18 0xb4041468 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
#19 0xb4041528 in g_main_context_iteration ()
   from /lib/i386-linux-gnu/libglib-2.0.so.0
#20 0xaf90230c in ?? () from /usr/lib/libreoffice/program/libvclplug_gtklo.so
#21 0xaf902c9c in ?? () from /usr/lib/libreoffice/program/libvclplug_gtklo.so
#22 0xb6501271 in Application::Yield() ()
   from /usr/lib/libreoffice/program/libmergedlo.so
#23 0xb650130d in Application::Execute() ()
   from /usr/lib/libreoffice/program/libmergedlo.so
#24 0xb57ca8b7 in ?? () from /usr/lib/libreoffice/program/libmergedlo.so
#25 0xb6508132 in ?? () from /usr/lib/libreoffice/program/libmergedlo.so
#26 0xb650815d in SVMain() () from /usr/lib/libreoffice/program/libmergedlo.so
#27 0xb57e9765 in soffice_main () from /usr/lib/libreoffice/program/libmergedlo.so
#28 0x0804858d in ?? ()
#29 0xb431da83 in __libc_start_main (main=0x8048560, argc=3, argv=0xbfe48494, 
    init=0x8048690, fini=0x8048700, rtld_fini=0xb777e180 <_dl_fini>, 
    stack_end=0xbfe4848c) at libc-start.c:287
#30 0x080485be in ?? ()
(clearly, my binaries are stripped, hence a lot of "in ??").

Evidently (frame 12) Gtk has emitted a signal for a Keypress Event with the keysym Sunprops with is caught somewhere in the module libvclplug_gtklo.so.
Evidently also Libreoffice (presumably Openoffice also) uses its own internal respresentation of what it calls "Keycodes", see https://docs.libreoffice.org/vcl/html/keycodes_8hxx_source.html in which I find:
  131 #define KEY_CUT         ((sal_uInt16)css::awt::Key::CUT)
  132 #define KEY_COPY        ((sal_uInt16)css::awt::Key::COPY)
  133 #define KEY_PASTE       ((sal_uInt16)css::awt::Key::PASTE)
  134 #define KEY_UNDO        ((sal_uInt16)css::awt::Key::UNDO)
  135 #define KEY_REPEAT      ((sal_uInt16)css::awt::Key::REPEAT)
  136 #define KEY_FIND        ((sal_uInt16)css::awt::Key::FIND)
  137 #define KEY_PROPERTIES  ((sal_uInt16)css::awt::Key::PROPERTIES)
so it appears that Libreoffice is comfortable to deal with Copy/Cut/Paste keys if it manages to see them.

Finding the values of css::awt::Key::CUT and friends is much harder. Yesterday I found them by legitimate means, but I could not repeat that trail today, and the best I can do is point you to https://cgit.freedesktop.org/libreoffice/core/tree/offapi/com/sun/star/awt/Key.idl where you will find:
 module com {  module sun {  module star {  module awt {
.....
published constants Key
{
.....
    const short CUT = 1297;
    const short COPY = 1298;
    const short PASTE = 1299;
    const short UNDO = 1300;
    const short REPEAT = 1301;
    const short FIND = 1302;
    const short PROPERTIES = 1303;
and I could see from gdb (see earlier stacktrace) that pressing the SunProps key had produced a "Keycode" with the value 1303 inside it. Copy/Cut/Paste just produced the Keycode zero.

It is obvious that, somewhere in the system, there must be some engine that converts keysyms into "keycodes", but I have been unable to locate it. I have found, within the vcl module,
   a Class GtkSalFrame and, within it,
   a Struct GtkSalFrame::IMHandler which has a field
   bool GtkSalFrame::IMHandler::handleKeyEvent (GdkEventKey * pEvent)
(see https://docs.libreoffice.org/vcl/html/gtkframe_8hxx_source.html) which looks like the required tool, but that is only a .hxx file, and I have found no corresponding .cxx file, nor any clue as to how to initialize a GtkSalFrame (which presumably would provide an inplemented function to plug into that field). There is also a Class X11SalFrame with a similar handleKeyEvent() which takes a raw XEvent, but again with no identifiable function to implement it.

So there I am stuck. If anyone can point me to an implementation of handleKeyEvent, then I would be happy to investigate further, and maybe suggest a fix, or at least a workaround. So Thanks in advance for any help that can be provided.
Comment 1 Buovjaga 2016-06-17 18:26:31 UTC
You might get advice from the #libreoffice-dev IRC channel. I recommend asking during weekdays, European office hours. https://wiki.documentfoundation.org/Website/IRC
Comment 2 Charles Lindsey 2016-06-30 19:38:20 UTC
Created attachment 126009 [details]
A new version of GetKeyCode() to insert into gtksalframe.cxx

See 2nd comment to Bug Report
Comment 3 Charles Lindsey 2016-06-30 19:43:14 UTC
Created attachment 126010 [details]
A new version of SalDisplay::GetKeyName() to insert into accfg.cxx

See 2nd comment to Bug Report
Comment 4 Charles Lindsey 2016-06-30 19:45:49 UTC
OK, I think I have cracked it. I took your advice and consulted the people on the #libreoffice-dev IRC channel, and they pointed me at gtksalframe.cxx.

But first some history:
In the beginning, there was X-Windows, which introduced an initial set of keysyms (see keysym.h and keysymdef.h).
Then various vendors (DEC, Apollo, HP, Sun) added new keys to their products, and invented new keysyms to go with them, with numbers of the form
    0x1000xxxx see DECkeysym.h, ap_keysym.h and HPkeysym.h
    0x1004xxxx see HPkeysym.h (which includes also OSF_Keysyms)
    0x1005xxxx see Sunkeysym.h
all totally incompatible (for example, there are three versions of Copy/Cut/Paste in there)
Finally, XFree86 invented a grand new list to encompass the lot:
    0x1008xxxx see XF86keysym.h
(so now there are four versions of Copy/Cut/Paste).

Modern Linux systems (certainly Ubuntu, probably Debian, no experience of Redhat) seem to map keys to XF86 keysyms where possible. In both gtk-2.0 and gtk-3.0, gdk/gdkkeysyms.h always uses them where available. Even gdk/gdkkeysyms-compat.h uses them. So it seems the XF86 keysyms (using 0x1008xxxx) are here to stay, and all the older ones (using 0x100[045]xxxx) and to be deprecated and reserved to legacy systems (and yes, I realise I have just relegated Solaris to legacy :-) ).

But Libreoffice (and doubtless Openoffice too) have not got around to accepting XF86 keysyms yet, and that is the cause of the present bug. However, it is easily fixed. Within gtksalframe.cxx you will find the function GetKeyCode(), which I have rewritten (see attached file, which can be included in gtksalframe.cxx as it stands, provided you attend to the comments about #include files at the start). It should be OK for either gtk-2.0 or gtk-3.0.

I have not tested this (beyond ensuring that it compiles correctly), but what I have done is to hack the library
    /usr/lib/libreoffice/program/libvclplug_gtklo.so
with a binary editor to achieve the same effect, and it works like a charm.

Note that the Sun keys Props and Front do not have suitable XF86 forms, so they remain in the 0x1005xxxx form (and Ubuntu, at least, still maps them that way). Also the Sun key Stop (which gets mapped to the keysym Cancel) has no obvious KeyCode on the Libreoffice side. You will see that I have mapped it to KEY_ESCAPE as a temporary measure, but I would strongly recommend that you guys should invent a KeyCode KEY_CANCEL to make a proper job of it.

I expected some difficulty in binding these keys to their proper functions, because they did not appear in the Customize-Keyboard popup, but it turns out that KEY_OPEN, KEY_COPY, KEY_CUT and KEY_PASTE are, by default, bound to their respective actions as expected and so my personal problem is solved.

Nevertheless, I decided to investigate why they were not appearing in that popup. It appears that accfg.cxx contains a list
    static const sal_uInt16 KEYCODE_ARRAY[] =
    { ... }
which contains all the KeyCodes (with modifiers) that are allowed to appear in the Customize-Keyboard popup, and from that list it chooses those which appear to be supported by the hardware. So it uses a huge switch in SalDisplay::GetKeyName(), which can be found in saldisp.cxx, to obtain a keysym, then calls XKeysymToKeycode() to get an X11-KeyCode, and if that succeeds (indicating that such a binding exists), uses XKeysymToString() to find its name. The trouble is that mapping, say, KEY_COPY to a keysym (the inverse of what GetKeyCode() does) is one-to-many, so should it try 0x1005FF72 or should it try 0x1008FF57 (or even 0x1000FF02 0x1004FF02). Currently it just tries 0x1005FF72, which is fine for Solaris, but not for Linux.

I attach a revised version of SalDisplay::GetKeyName(), which calls GetServerVendor() to discover whether the local system is running Solaris, and hence which keysyms to use. An alternative would be to use an
    #if defined(SOLARIS) ... #endif
to achieve the same effect. I have not tested this code in any way, but I am sure that it (or something pretty close to it) will solve the problem.

So that's two bugs fixed for you, hopefully, and I hope time can be found to implement them into your main trunk.
Comment 5 Buovjaga 2016-07-01 10:37:36 UTC
(In reply to Charles Lindsey from comment #4)
> So that's two bugs fixed for you, hopefully, and I hope time can be found to
> implement them into your main trunk.

Could you submit patches to gerrit for review? https://wiki.documentfoundation.org/Development/gerrit

Otherwise they will unfortunately just sit here and be ignored.
Comment 6 Charles Lindsey 2016-07-02 19:17:34 UTC
I'm Sorry. But I have had a look at Gerrit, and it seems like one large system to have to learn how to use, and it presumes much familiarity with the structure of Libreoffice and how to compile new versions/branches/whatever, and I just have not the time to devote to such an activity.

I have demonstrated that the bug exists (it is evident that the current code just does not handle keysyms in the XF86 keysym set, which is what modern Linux systems seem to generate). I have hacked my way around the problem on my own system. If anyone else encounters the same problem, Google will soon lead them to this bug (the same bug was also reported on Openoffice some years ago, but many things have changed since then). Si sadly I must just leave it at that.
Comment 7 jani 2016-07-07 07:33:37 UTC
(In reply to Charles Lindsey from comment #6)
> I'm Sorry. But I have had a look at Gerrit, and it seems like one large
> system to have to learn how to use, and it presumes much familiarity with
> the structure of Libreoffice and how to compile new
> versions/branches/whatever, and I just have not the time to devote to such
> an activity.
> 
> I have demonstrated that the bug exists (it is evident that the current code
> just does not handle keysyms in the XF86 keysym set, which is what modern
> Linux systems seem to generate). I have hacked my way around the problem on
> my own system. If anyone else encounters the same problem, Google will soon
> lead them to this bug (the same bug was also reported on Openoffice some
> years ago, but many things have changed since then). Si sadly I must just
> leave it at that.

Hi, I am sorry that you feel like that, we have made a step-by-step guide to make it easy to submit a patch:
https://wiki.documentfoundation.org/Development/GetInvolved
Because as you say, learning all of Gerrit and LibreOffice is a bit overwhelming.

Use the step by step guide, then you do not
- need to learn about branches etc
- learn all of gerrit (only 1 command logerrit)

I am mentoring new people, so please let me know if I can help you.

rgds
jan I.
Comment 8 Commit Notification 2016-09-07 21:19:14 UTC
Caolán McNamara committed a patch related to this issue.
It has been pushed to "master":

http://cgit.freedesktop.org/libreoffice/core/commit/?id=cb6fc75c5433b826afdbbb60259c0d6c658f8e14

Related: tdf#100443 don't use deprecated gtk keysym defines

It will be available in 5.3.0.

The patch should be included in the daily builds available at
http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
http://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 9 Commit Notification 2016-09-07 21:19:19 UTC
Caolán McNamara committed a patch related to this issue.
It has been pushed to "master":

http://cgit.freedesktop.org/libreoffice/core/commit/?id=1c2ac71f80e271a6352384e0bce8c8f432bf37f6

Resolves: tdf#100443 handle sun keyboard copy/cut/paste keys

It will be available in 5.3.0.

The patch should be included in the daily builds available at
http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
http://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 10 Caolán McNamara 2016-09-07 21:24:24 UTC
I see ancient code that mapped 0x0000FF69 (XK_Cancel) to F11 for the "generic" X11 case so reused the same (odd) mapping in the gtk[2|3] in the absence of a KEY_CANCEL.
Comment 11 Charles Lindsey 2016-09-16 18:38:08 UTC
I am the original reporter of the bug, so thanks for fixing it. Two Issues:

1. I ought to try out the fix, but Daily Builds seem to be available for Linux i86-64bit systems, and my system is using 186-32-bit (yes, the hardware understands 64-bit addresses, but for historical reasons it uses the Linux 32-bit core, and yes I ought to fix it ... someday). So I guess I cannot run that daily build. I am not sure whether accessing a 64-bit version via ssh would work, if someone could make one available to me, because I am not sure whether ssh is smart enough to pass the keyboard configuration across. Is there someone else out there who is actually using a Sun Keyboard on a non-sun system?

Or any other bright ideas for workaround this?

2. I am not sure that mapping the Cancel Key to F11 is a good idea. On most systems F11 means "expand this page to full screen", and having the Cancel Key do that might startle some folk.

Perhaps better to write the code as if KEY_CANCEL actually existed, and then comment it out with a remark explaining why it should remain so unless KEY_CANCEL came to exist.

For the record, the usage of that key (which is actually labelled "Stop") in Solaris was for use it you had created some complicated selection, and were perhaps even in the process of dragging it with a view to dropping it, and you were still holding assorted keys and buttons down, then you could press that key (assuming you had a spare finger left) to abandon the whole thing. In GTK, the ESC key is used with drag'n'drop for that purpose.
Comment 12 Buovjaga 2016-09-17 19:44:52 UTC
Rejoice, for the 32-bit Linux builds are here again! http://dev-builds.libreoffice.org/daily/master/Linux-rpm_deb-x86@71-TDF/current/
Comment 13 Charles Lindsey 2016-09-24 16:27:03 UTC
I rejoiced initially, but then I had a battle with dpkg - but that's another story.

Yes, everything seems to work as advertised. The Customize popup shows the various XF86* keys, and they were all bound, by default, to the correct actions. But I observed a few oddities:

1. Ctrl-F is shown in the popup as bound to the action 'Find', which is fine and dandy, except that no such Action is listed in the available functions as shown. This seems like a Bug to me (and has been present for a long time). Naturally, I wanted to bind the Find key to this action, and after various ugly hacks I managed to do so. Admittedly this action is slightly odd, insofar as its effect is to show the Find toolbar. Nevertheless, such hacks should not be necessary, so I hope it can be fixed.

2. The 'Cancel' key duly produced the same effect as 'F11' (i.e. it popped up the Style Menu), which is somehwhat silly. So if you do not intend to introduce an official KEY_CANCEL (and I accept there is no compelling argument for doing so), then it would be much better to leave it unbound rather than to generate such surprises.

3. OTOH, in the available Action Functions, under the Edit group, there does exist a 'Cancel' action, though I could not work out what it was supposed to do. So maybe there IS a case for KEY_CANCEL after all.