tk2combobox: how to control response to up/down arrow keys - r

I've got a UI in R using tk2combobox.
If the control has focus, and I hit the "down-arrow" key, it expands the list, rather than changing the selection.
It doesn't actually change the selection until I arrow down and hit "enter" or click with the mouse.
Is there any way I can get it to change the selection immediately with the arrow key?

This is how you do it in Tcl. I could not get the very first
key-down to work, as somehow the interactions in bindings caused
the second key-press to disappear.
package require Tk
proc ::lbarrowhandler { w } {
set currselidx [$w curselection]
regsub {\.popdown\.f\.l$} $w {} cb
$cb current $currselidx
return -code ok
}
set ::x cc
ttk::combobox .c -values {aa bb cc dd ee ff} -textvariable ::x
pack .c
bind ComboboxListbox <<ListboxSelect>> +[list ::lbarrowhandler %W]
Edit:
Another possibility is to use the ttk::spinbox with the -values option.
I don't know your exact use case, but this will give the user a limited
selection of values. The disadvantage here is that the complete list
is not visible.
set ::x cc
ttk::spinbox .sp -values {aa bb cc dd ee ff} -state readonly \
-wrap true -textvariable ::x
pack .sp
The -state readonly prevent the user from typing anything in, and the
-wrap option will have the arrow controls wrap from end to beginning and
vice-versa.
References: http://www.tcl-lang.org/man/tcl/TkCmd/ttk_spinbox.htm

Related

AwesomeWm I need advice on mapping more modifier keys

I need to find another couple modifiers for key mappings. The Awesome Docs state that valid modifiers are Any, Mod1, Mod2, Mod3, Mod4, Mod5, Shift, Lock and Control, I am unclear of some of these but I have tried Capslock and Tab and it didn't work well. While the binding seems to work I found that you can still trigger the function by using just the "key" portion as if the modifier was being ignored. I know I will have to map these more than likely and I was hoping I could get some advice on where to start, thanks in advance for any help
I am using awesome 4.3 on Manjaro/Arch thanks
clear mod4
add mod4 = Super_L Hyper_L
add mod3 = Super_R Menu
keycode 135 = Super_R Menu
and the output of cli xmodmap
xmodmap: up to 3 keys per modifier, (keycodes in parentheses):
shift Shift_L (0x32), Shift_R (0x3e)
lock Caps_Lock (0x42)
control Control_L (0x25), Control_R (0x69)
mod1 Alt_L (0x40), Alt_R (0x6c), Meta_L (0xcd)
mod2 Num_Lock (0x4d)
mod3 Super_R (0x86), Super_R (0x87)
mod4 Super_L (0x85), Super_L (0xce), Hyper_L (0xcf)
mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
You can see current modifiers with xmodmap in a terminal.
You can add Tab key to mod1 with:
$ xmodmap -e "add mod1 = Tab"
Then you can use Mod1 in rc.lua, for example:
root.buttons = gears.table.join(
...
...
awful.button({"Mod1"}, 1, function() naughty.notification({text="ok"}) end),
...
...
)
With holding Tab and pressing left mouse button, you pop up the notification.
Nevertheless, Tab will continue to tabulate... but if you want to change this behaviour, you may need to consider a xmodmap tutorial like this one.
In awesomeWM, you can find a table with your current modifiers. Below we can see that Tab has been added to the Mod1 table:
$ awesome-client "return awesome._modifiers.Mod1[1].keysym"
string "Tab"
$ awesome-client "return awesome._modifiers.Mod1[1].keycode"
double 23
Edit
With xmodmap to reassign Menu key to mod3:
clear mod1
add mod1 = Alt_L Meta_L
add Mod3 = Menu
More on xmodmap
The way that Xorg keeps track of these keys, is by storing a table of keycodes. You can view what keycodes are assigned to which modifier keys with xmodmap.
> xmodmap
shift Shift_L (0x32), Shift_R (0x3e)
lock Caps_Lock(0x42)
...
Some of these keys are also used for other things. In my case, I wanted to use my Capslock as my main modifier key, without triggering capslock. What I did to achieve that was remove the lock keybind, then rebind the keycode of my CapsLock key to Hyper_R and assign that to a mod key using xmodmap.
~/.Xmodmap
clear lock
keycode 66 = Hyper_R
add mod3 = Hyper_R
After doing this, in my rc.lua I changed the modkey to mod3:
modkey = "Mod3"
Be warned that Hyper_R might be bound on your system, so if a key stops working after doing this, that might be the reason.

How to expand a tree view using AutoIt

The UI is as following:
The tool "AutoIt Window Info" can only locate the elements in red (red rectangle area), the sub items can not be located.
So how can I expand or operate these items?
Usually Windows controls can be accessed using keystrokes as well.
In the screen-dump the Farmtt element is selected. That would be your starting point.
You may try:
Send("{DOWN}") Move down an element.
Send("{TAB}") Navigate to next control (button, checkbox, etc)
Send("{NumPadMult}") Recursively expands folders in a SysTreeView32.
Send("{ENTER}") ENTER key on the main keyboard
etc.
Reference:
https://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm
There are two things over here:
1) Use the following code snippet:
;Gets the handle for the text
Func readFirstlevelTreeNodes($hWndCtrl)
Local $firstItemHandle = _GUICtrlTreeView_GetFirstItem ($hWndCtrl)
Local $iCount = _GUICtrlTreeView_GetSiblingCount( $hWndCtrl, $firstItemHandle )
Dim $aRet[$iCount]
$aRet[0] = $firstItemHandle
For $index = 1 To $iCount - 1
$aRet[$index] = _GUICtrlTreeView_GetNextSibling ( $hWndCtrl, $firstItemHandle )
$firstItemHandle = $aRet[$index]
Next
getTreeNodeTextList($hWndCtrl,$aRet)
EndFunc
; Gets the text for given sibling node handle lists
Func getTreeNodeTextList($hWndCtrl,$aRet)
ConsoleWrite("Tree Node first level list"&#CRLF)
For $index = 0 To Ubound($aRet) -1
ConsoleWrite(_GUICtrlTreeView_GetText ( $hWndCtrl, $aRet[$index] )&#CRLF)
Next
EndFunc
You may see the output for the first level tree nodes.
2) If you still dont see the output then please verify the control handle values and window handles. If they are correct and it still doesnt show the first level tree nodes then try running your sciTE editor as administrator.
I think this should help.

"Down arrow" moves cursor to end of line - how to turn it off

In IPython Notebook / Jupyter, arrow up/down keystrokes within a cell are handled by CodeMirror (as far as I can tell). I use these actions a lot (re-bound to control-p / control-n) to move between cells; but at the end of every cell, the cursor moves to end of line first before jumping to the next cell. This is counter-intuitive and, to me, rather distracting.
Is there any way to configure CodeMirror to make this move down to be just that - a move down?
Thanks!
The moving-to-next-cell behavior is defined by IPython wrapper code, which probably checks whether the cursor is at the end of the current cell, and overrides the default CodeMirror behavior in that case. You'll have to find that handler and somehow replace it with one that checks whether the cursor is on the last line. (I don't know much about IPython, only about CodeMirror, so I can't point you at the proper way to find and override the relevant code. They might have bound the Down key, or they might have overridden the goLineDown command.)
Knowing that I wasn't alone in wanting to skip the "going to end of line" behavior when going down from the last line of a code cell, I investigated that behavior and found out that:
it's CodeMirror that goes to the end of line when you type down in the last line of a code cell (file: codemirror.js ; "methods": findPosV and moveV)
and it's IPython that decides what to do with the "down" event after it has been handled by CodeMirror (file: cell.js ; class: Cell ; method: handle_codemirror_keyevent) ; looking at the code, I saw that IPython ignores the event when not at the last character of the last line.
This essentially confirms Marijin's answer.
The primary goal being to jump to the next cell, I think there's no need to prevent CodeMirror from going to the end of that line. The point is to force IPython to handle the event anyway.
My solution was to change the code from Cell.prototype.handle_codemirror_keyevent to this:
Cell.prototype.handle_codemirror_keyevent = function (editor, event) {
var shortcuts = this.keyboard_manager.edit_shortcuts;
var cur = editor.getCursor();
if((cur.line !== 0) && event.keyCode === 38){
// going up, but not from the first line
// don't do anything more with the event
event._ipkmIgnore = true;
}
var nLastLine = editor.lastLine();
if ((event.keyCode === 40) &&
((cur.line !== nLastLine))
) {
// going down, but not from the last line
// don't do anything more with the event
event._ipkmIgnore = true;
}
// if this is an edit_shortcuts shortcut, the global keyboard/shortcut
// manager will handle it
if (shortcuts.handles(event)) {
return true;
}
return false;
};
This code provides the desired behavior for the "down-arrow" key (almost: the cursor still goes to the end of the line, except that we don't see it, as we're already in another cell at that point), and also handles the "up-arrow" key similarly.
To modify the handle_codemirror_keyevent prototype, you have two possibilities:
You edit the cell.js file and change the code of the prototype to the code I gave above. The file is in <python>/Lib/site-packages/IPython/html/static/notebook/js or something similar depending on you distro
Much better, after the page is loaded, you change that prototype dynamically by doing this:
IPython.Cell.prototype.handle_codemirror_keyevent = function (editor, event) {
<same code as above>
};
You can do that in your custom.js for example, or create an extension to do it (that's what I did).

Non editable box with tcl tk and R

I am looking for some way to forbid users to change value in a text box with tcltk and R.
Here is what I have done : I want to forbid users to change the value in the first box.
library(tcltk)
tt <- tktoplevel()
v <- tclVar("32 200 700")
entry.1 <-tkentry(tt, width = "50", textvariable = v)
tkbind(entry.1, "<Key>", function()tkfocus(entry.2))
tkgrid(entry.1, row=1, column=0)
v2 <- tclVar("")
entry.2 <-tkentry(tt, width = "50", textvariable = v2)
tkgrid(entry.2, row=2, column=0)
It seems to work but key's native action is done before bound action.
How can I solve this problem ?
I don't want to use tklabel because it can't bring borders to the text.
This is plain Tcl, not R syntax, but you want to set the widget's state to readonly. That will forbid the user from modifying the value, but it still respects changes to the text variable. You don't need to bind anything, the user cannot focus on the widget.
set value 0
entry .e -textvariable value -state readonly
button .b -text incr -command {incr value}
pack .e .b

Sticky key activation (shift 5 times) doesn't work by hotkey ::Send {LShift 5}

I would like to activate sticky keys by pressing 1 button, instead of pressing shift 5 times, which is the default way.
If I were to do
F9::Send {LShift 5}
pressing F9 will yield nothing.
I also tried
F9::
Send {LShift}
sleep 50
Send {LShift}
sleep 50
Send {LShift}
sleep 50
Send {LShift}
sleep 50
Send {LShift}
sleep 50
return
Are there any reasons as to why it's not working?
While there is most likely a way to do a dll call or something complicated, it is also possibly to program similar functionality using AutoHotkey. This would also avoid the sticky keys prompt, and you can do a traytip instead.
stickykeys = 0
F9::
stickykeys:=!stickykeys
Traytip, Sticky Keys, % (stickykeys) ? "On" : "Off"
return
#If stickykeys
*$Shift::
key = 0
Input, key, L1 M
SendInput {Shift Down}{%key%}{Shift Up}
return
*$Ctrl::
key = 0
Input, key, L1 M
SendInput {Ctrl Down}{%key%}{Ctrl Up}
Return
*$Alt::
key = 0
Input, key, L1 M
SendInput {Alt Down}{%key%}{Alt Up}
Return
#If
F9 simply toggles sticky keys on and off.
Note: This is using AHK_L which supports #If
SPI_GETSTICKYKEYS:=0x003A
SPI_SETSTICKYKEYS:=0x003B
SKF_STICKYKEYSON:=0x1
VarSetCapacity(STICKYKEYS,8) ; DWORD cbSize;DWORD dwFlags;
NumPut(8,&STICKYKEYS,"UInt")
F9::
DllCall("SystemParametersInfo","UInt",SPI_GETSTICKYKEYS,"UInt",8,"PTR",&STICKYKEYS,"UInt",0)
dwFlags:=NumGet(&STICKYKEYS,4,"Uint")
If (dwFlags & SKF_STICKYKEYSON)
dwFlags-=SKF_STICKYKEYSON
else dwFlags|=SKF_STICKYKEYSON
ToolTip % "STICKYKEYS are " (dwFlags & SKF_STICKYKEYSON ? "ON" : "OFF")
SetTimer,ToolTipOff,-1000
NumPut(dwFlags,&STICKYKEYS,4,"UInt")
DllCall("SystemParametersInfo","UInt",SPI_SETSTICKYKEYS,"UInt",8,"PTR",&STICKYKEYS,"UInt",0)
Return
ToolTipOff:
The code is from the Autohotkey forums at http://www.autohotkey.com/community/viewtopic.php?f=1&t=93650
A note for anyone wanting to use the code: I think you have to put it at the top of your script for it to work. In my script of hotkeys, placing it in the middle, and pressing F9 to activate sticky keys caused some weird things to happen: The cursor jumped around, some folders were launched, the script exited, etc. I'm guessing that it activated other hotkeys nearby?

Resources