Gtk3 keys bindings in css files - css

Where can I find an exhaustive list of available keybindings that a user can define in a CSS file for GTK+ 3?
I have already checked those resources:
https://developer.gnome.org/gtk3/stable/GtkCssProvider.html
https://developer.gnome.org/gtk3/stable/gtk3-Bindings.html
/usr/share/themes/Default/gtk-3.0/gtk-keys.css (which is empty)
/usr/share/themes/Emacs/gtk-3.0/gtk-keys.css
For example, how can a user make <Control>Space move the cursor to the end of the text in a GtkTextView?

It seems that there is no exhaustive documentation. Here is what I have found so far:
The list of the possible actions (from /usr/share/themes/Emacs/gtk-3.0/gtk-keys.css) :
move-cursor
delete-from-cursor
cut-clipboard
past-clipboard
start-interactive-search
move-current
Get the gtk+ code :
git clone git://git.gnome.org/gtk+
For example, the "move-cursor action":
bind "<ctrl>b" { "move-cursor" (logical-positions, -1, 0) };
If you do a :
grep -i logical gtk+/gtk/gtkenums.h
You will find a match and see that there are others possibilities :
/**
* GtkMovementStep:
* #GTK_MOVEMENT_LOGICAL_POSITIONS: Move forward or back by graphemes
* #GTK_MOVEMENT_VISUAL_POSITIONS: Move left or right by graphemes
* #GTK_MOVEMENT_WORDS: Move forward or back by words
* #GTK_MOVEMENT_DISPLAY_LINES: Move up or down lines (wrapped lines)
* #GTK_MOVEMENT_DISPLAY_LINE_ENDS: Move to either end of a line
* #GTK_MOVEMENT_PARAGRAPHS: Move up or down paragraphs (newline-ended lines)
* #GTK_MOVEMENT_PARAGRAPH_ENDS: Move to either end of a paragraph
* #GTK_MOVEMENT_PAGES: Move by pages
* #GTK_MOVEMENT_BUFFER_ENDS: Move to ends of the buffer
* #GTK_MOVEMENT_HORIZONTAL_PAGES: Move horizontally by pages
*/
For example the binding I wanted to do (move the cursor to the end of the text in a Gtk::TextView)
bind "<Control>KP_Space" { "move-cursor" (buffer-ends, 1, 0) }
The "template" is :
bind "key_combination" { "action" (action_param1, action_param2, ...)}
For the move-cursor action, the parameters are (step, count, extend_selection), where step is one of the above enum values. To note that for line-ends, paragraph-ends and buffer-ends a negative count means "beginning" and a positive value means "end". And extend_selection is simply 0 or 1 (for C-style "False" and "True").
In the same way, the options for the action "delete-from-cursor" are :
/**
* GtkDeleteType:
* #GTK_DELETE_CHARS: Delete characters.
* #GTK_DELETE_WORD_ENDS: Delete only the portion of the word to the
* left/right of cursor if we’re in the middle of a word.
* #GTK_DELETE_WORDS: Delete words.
* #GTK_DELETE_DISPLAY_LINES: Delete display-lines. Display-lines
* refers to the visible lines, with respect to to the current line
* breaks. As opposed to paragraphs, which are defined by line
* breaks in the input.
* #GTK_DELETE_DISPLAY_LINE_ENDS: Delete only the portion of the
* display-line to the left/right of cursor.
* #GTK_DELETE_PARAGRAPH_ENDS: Delete to the end of the
* paragraph. Like C-k in Emacs (or its reverse).
* #GTK_DELETE_PARAGRAPHS: Delete entire line. Like C-k in pico.
* #GTK_DELETE_WHITESPACE: Delete only whitespace. Like M-\ in Emacs.
*
* See also: #GtkEntry::delete-from-cursor.
*/
Now if you want all to see all the possible actions that are hard coded, then
here is a way :
find ./gtk+/ -type f | xargs grep -A 2 gtk_binding_entry_add_signal
You will see lot of things like this :
./gtk+/gtk/gtklabel.c: gtk_binding_entry_add_signal (binding_set, GDK_KEY_backslash, GDK_CONTROL_MASK,
./gtk+/gtk/gtklabel.c- "move-cursor", 3,
./gtk+/gtk/gtklabel.c- G_TYPE_ENUM, GTK_MOVEMENT_PARAGRAPH_ENDS,
--
./gtk+/gtk/gtklabel.c: gtk_binding_entry_add_signal (binding_set, GDK_KEY_c, GDK_CONTROL_MASK,
./gtk+/gtk/gtklabel.c- "copy-clipboard", 0);
./gtk+/gtk/gtklabel.c-
./gtk+/gtk/gtklabel.c: gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0,
./gtk+/gtk/gtklabel.c- "activate-current-link", 0);
./gtk+/gtk/gtklabel.c: gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0,
./gtk+/gtk/gtklabel.c- "activate-current-link", 0);
./gtk+/gtk/gtklabel.c: gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0,
./gtk+/gtk/gtklabel.c- "activate-current-link", 0);
./gtk+/gtk/gtklabel.c-
--
./gtk+/gtk/gtkdialog.c: gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0);
Then it should be easy to find what you were looking for.

My guess is you should find any signal with the G_SIGNAL_ACTION flag enabled. You could get this list programmatically from the Gtk gir file (/usr/share/gir-1.0/Gtk-3.0.gir on my system) by looking for every <glib:signal> entity with the action attribute set to 1.
I am not so fond on XPath to come out with a one-line solution though.

I've also been looking for proper documentation of possible key bindings for quite a while now and just stumbled over these docs of the single-line text widget GtkEntry. In this particular case, one can scroll all the way down to the end of the menu to find all other "keybinding signals" the widget offers, like insert_at_cursor, paste_clipboard etc. including the parameters these signals accept (such as the DeleteType in case of delete_from_cursor). It now shouldn't be too hard to find the signals for other GTK widgets.
Update: If the Vala docs provide a detailed description of the keybinding signals, one might assume that the regular Gtk3 docs do, too. Indeed. It's always easier to find what you're looking for if you know what you're looking for. :)

I think ultimately ntd has the most correct idea, but here is a more browsable solution, rather than grepping through the GIR file.
You should (assuming comprehensive documentation) be able to find this info by going to the documentation page for the widget of interest, then search that page for the term keybinding signal.
The available signals are documented along with the others on each widget's page and then qualified as whether or not they are for key bindings in the description.
Usually you can also identify them by the fact that their value in the 2nd column of the summary table of signals, i.e. signal type flags, is Action, as also pointed out by ntd.
For example, GtkComboBox:move-active:
[handler function signature]
The ::move-active signal is a keybinding signal which gets emitted to move the active selection.
[description of arguments]
As ntd indicated, this can probably be automated to a large extent. Like the GIR, the documentation is generated from the C source files, so if you lack a GIR file or just prefer this way, you can presumably do some clever use of grep, sed, et al. through those to pull out the info.

#ntd suggested looking at /usr/share/gir-1.0/Gtk-3.0.gir for
<glib:signal action="1"> entities. I don't have a Gtk-3.0.gir but I do have a Gtk-2.0.gir and these are the unique results I found using that approach:
cat /usr/share/gir-1.0/Gtk-2.0.gir \
| sed -n '/.*<glib:signal name="\([^"]*\)".* action="1".*/s//\1/p' \
| sort -u
abort-column-resize
accept-position
activate
activate-current
activate-cursor-item
activate-default
activate-focus
backspace
cancel
cancel-position
change-current-page
change-focus-row-expansion
change-value
clicked
close
composited-changed
copy-clipboard
cut-clipboard
cycle-focus
delete-from-cursor
end-selection
expand-collapse-cursor-row
extend-selection
focus-home-or-end
focus-tab
grab-focus
insert-at-cursor
kill-char
kill-line
kill-word
move
move-active
move-current
move-cursor
move-focus
move-focus-out
move-handle
move-page
move-scroll
move-slider
move-to-column
move-to-row
move-viewport
move-word
page-horizontally
paste-clipboard
popdown
popup
popup-menu
reorder-tab
row-activated
scroll-child
scroll-horizontal
scroll-vertical
select-all
select-cursor-item
select-cursor-parent
select-cursor-row
select-page
set-anchor
set-editable
set-scroll-adjustments
show-help
start-interactive-search
start-selection
toggle-add-mode
toggle-cursor-item
toggle-cursor-row
toggle-cursor-visible
toggle-focus-row
toggle-overwrite
undo-selection
unselect-all

Related

SciTE Script - How to get inside a Tree Control to set checkboxes

I'm using AutoIt and SciTE to create an installation script. The problem I am running into is that there is a tree menu for selection of features. I can select the whole treeview (SysTreeView32), but am not sure how to get inside it to check the boxes without doing a mouse move and click (not a great option).
The Treeview looks like this:
The Control Info from AutoIT is like this:
I'm sure it is possible, just can't figure out how to do it. This is my first attempt a such a script. Creating a response file does not work for this exe for some reason. So - this appears to be my only way out to create a somewhat silent install (not silent anymore, but at least automated).
* EDIT - Current State of Things *
I did figure out how to do some of this, but I still can't figure out if the items is selected before accessing it. So - since it toggles, I could be turning off a feature I want!
$hWnd = WinWaitActive($WindowTitle, 'Select Features')
$tvCtl = ControlGetHandle($WindowTitle, '', 'SysTreeView321')
$firstItem = _GUICtrlTreeView_FindItem($tvCtl, 'eBooks')
_GUICtrlTreeView_SelectItem($tvCtl, $firstItem, $TVGN_FIRSTVISIBLE)
_GUICtrlTreeView_ClickItem($tvCtl, $firstItem, "left", True, 1)
Send('{SPACE}')
I wouldn't think I would have to send the space since I sent the ClickItem, but seems so.
I could also do this:
ControlTreeView($hWnd, '', $tvCtl, 'Select', '#0')
ControlSend($hWnd, '', $tvCtl, ' ')
That will toggle the first one. So - i can count them all up and do it that way.
But when I check for "IsEnabled" or "IsChecked", it always says NO. So - I can't check the ones I need only. I have to hope their status is what I expect.
Here is how I am checking "IsChecked" and "IsEnabled":
If ControlCommand($hWnd, '', $logTool, 'IsEnabled') then
ConsoleWrite('Log Tool - IsEnabled' & #CRLF)
Else
ConsoleWrite('Log Tool - NOTEnabled' & #CRLF)
EndIf
and
If ControlCommand($hWnd, '', $logTool, 'IsChecked') then
ConsoleWrite('Log Tool - IsChecked' & #CRLF)
Else
ConsoleWrite('Log Tool - NOTChecked' & #CRLF)
EndIf
It always comes back NOTEnabled and NOTChecked. I made sure that I ran the same procedure above: FindItem, SelectItem, ClickItem. And, the correct item is highlighted/selected when this procedure is run - I can see that. So - it just isn't returning a proper value.
Opt('WinTitleMatchMode', 2)
$hWnd = WinGetHandle("InstallShield Wizard") ; Notice the correct title
$hTree = ControlGetHandle($hWnd, '', "[CLASS:SysTreeView32;INSTANCE:1]")
; == Now you can interact with the treeview with functions from "GuiTreeView.au3"
EDIT:
Try this
; Select the item so:
_GUICtrlTreeView_SelectItem($hTree, $hItem, $TVGN_CARET)
; Get checked state:
_GUICtrlTreeView_GetChecked($hTree, $hItem)
For more deatails read the AutoIt 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).

Python and Qt : Retrieving branch names in multi-leveled QMenu

Having trouble finalizing a dynamic QMenu tree.
The structure and format is perfect, but what remains missing is the return of all branch names when triggering the end-action.
The only implement I have tried with ANY trend toward a solution is the use of self.sender(); which returns only the name of the end-action.
Before adding a ton of the lengthy code snips - starting by conceptualizing the question seemed best in case there is some (obvious) means I am over-looking.
Example;
The ideal return based on the footer figure would be something along the lines of...
Top Image:
'Single Results' - 'Head Results'
Middle Image:
'Batch Results' - 'testBatch_vr3' - 'Run-1' - 'Budget Results'
Bottom Image:
'Single Results' - 'testBatch_vr3' - 'Run-3' - 'Particle Tracks'
To the point;
How can all names in a multi-leveled set of QMenus be retrieved when triggering end-action?
The following complex bits resolved my problem. It might be a bit obscure way to go about it (hovered signal from menu to search for dictionary menu entry) - but it works well for now.
# checks batch processing folder for existing directories and publishes the contents
# into the batch results menu comboBox
def populateBatchResults(self):
self.batchMenuDict = {}
self.runMenuDict = {}
self.runBatchResultsPopup.clear()
self.batchDirNamesMenu.clear()
batchModDir = self.estabBatchModelDir()
for batch in os.listdir(batchModDir):
fullBatchDir = batchModDir+str(batch)
if os.path.isdir(fullBatchDir):
self.batchMenuDict[batch] = QMenu(self.iface.mainWindow())
self.batchMenuDict[batch].setTitle(str(batch))
self.runBatchResultsPopup.addMenu(self.batchMenuDict[batch])
for run in os.listdir(fullBatchDir):
fullRunDir = fullBatchDir+'\\'+str(run)
if os.path.isdir(fullRunDir):
self.runMenuDict[run] = QMenu(self.iface.mainWindow())
self.runMenuDict[run].setTitle(str(run))
self.batchMenuDict[batch].addMenu(self.runMenuDict[run])
self.runMenuDict[run].hovered.connect(self.assertBatchMenuSelection)
# get all current cursor hovered menu names
def assertBatchMenuSelection(self):
self.selectedBatch = self.runBatchResultsPopup.activeAction().text()
self.selectedRun = self.batchMenuDict.get(self.selectedBatch).activeAction().text()
self.selectedAction = self.runMenuDict.get(self.selectedRun).activeAction().text()

Correct parameter binding for SELECT WHERE .. LIKE using fmdb?

First time user of fmdb here, trying to start off doing things correctly. I have a simple single table that I wish to perform a SELECT WHERE .. LIKE query on and after trying several of the documented approaches, I can't get any to yield the correct results.
e.g.
// 'filter' is an NSString * containing a fragment of
// text that we want in the 'track' column
NSDictionary *params =
[NSDictionary dictionaryWithObjectsAndKeys:filter, #"filter", nil];
FMResultSet *results =
[db executeQuery:#"SELECT * FROM items WHERE track LIKE '%:filter%' ORDER BY linkNum;"
withParameterDictionary:params];
Or
results = [db executeQuery:#"SELECT * FROM items WHERE track LIKE '%?%' ORDER BY linkNum;", filter];
Or
results = [db executeQuery:#"SELECT * FROM items WHERE track LIKE '%?%' ORDER BY linkNum;" withArgumentsInArray:#[filter]];
I've stepped through and all methods converge in the fmdb method:
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args
Depending on the approach, and therefore which params are nil, it then either calls sqlite3_bind_parameter_count(pStmt), which always returns zero, or, for the dictionary case, calls sqlite3_bind_parameter_index(..), which also returns zero, so the parameter doesn't get slotted into the LIKE and then the resultSet from the query is wrong.
I know that this is absolutely the wrong way to do it (SQL injection), but it's the only way I've managed to have my LIKE honoured:
NSString *queryString = [NSString stringWithFormat:#"SELECT * FROM items WHERE track LIKE '%%%#%%' ORDER BY linkNum;", filter];
results = [db executeQuery:queryString];
(I've also tried all permutations but with escaped double-quotes in place of the single quotes shown here)
Update:
I've also tried fmdb's own …WithFormat variant, which should provide convenience and protection from injection:
[db executeQueryWithFormat:#"SELECT * FROM items WHERE track LIKE '%%%#%%' ORDER BY linkNum;", filter];
Again, stepping into the debugger I can see that the LIKE gets transformed from this:
… LIKE '%%%#%%' ORDER BY linkNum;
To this:
… LIKE '%%?%' ORDER BY linkNum;
… which also goes on to return zero from sqlite3_bind_parameter_count(), where I would expect a positive value equal to "the index of the largest (rightmost) parameter." (from the sqlite docs)
The error was to include any quotes at all:
[db executeQuery:#"SELECT * FROM items WHERE track LIKE ? ORDER BY linkNum;", filter];
… and the % is now in the filter variable, rather than in the query.

I am having trouble adding elements to a referenced vector of a map

EDIT: Forgot to mention that my programming language is C++, and my IDE is Qt Creator.
I don't understand why I am having trouble adding elements to a referenced vector of a map (i.e. sometimes it works and sometimes it fails).
For example:
class C_html4_tags {
public:
C_html4_tags();
//.......
typedef std::vector<S_html_attr_value> TYPE_attr_values;
//.....
};
//...
C_html4_tags::C_html4_tags() {
//........
map<S_browser, TYPE_attr_values> attr_supported_attr_values_map;
S_browser dummy_browser; //a fake browser key for referencing a fully Html 4.01-compliant supported attr values list
dummy_browser.name = "Dummy";
//.....
TYPE_attr_values& attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
//......
**attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];**
//...
**attr_supported_attr_values.clear();
attr_supported_attr_values_map.clear();**
//......
**attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];**
//...
**attr_supported_attr_values.clear();
attr_supported_attr_values_map.clear();**
}
I do the bolded lines multiple times with a bunch of different attributes, with very little difference between them, without a problem until reaching this one attribute (a_tabindex_attr), in which the IDE doesn't report anything wrong when running it normally (except "The program has unexpectedly finished." However, when debugging it, it now reports:
Signal received
The inferior stopped because it received a signal from the Operating
System.
Signal name : SIGSEGV Signal meaning : Segmentation fault
And the backtrace points to the attribute I mentioned above, on the line of code which does this:
attr_supported_attr_values.clear();
Now, after adding some debugging cout lines to the code, I learned that what's happening is, for some reason, even after doing:
attr_supported_attr_values.push_back(attr_value);
the vector object which is the returned mapped value of:
attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
is not actually being changed when I push_back an S_html_attr_value object to the referenced vector. Now, I don't why that is, since I do pretty much the exact same thing in a bunch of other attributes' code before this one, without any problem, but for some reason now, on this one, it ain't adding the object to attr_supported_attr_values (which is a reference to the returned mapped value of 'dummy_browser'). And I know this for a fact, because I outputted the size of the internal mapped value object of the map (using an iterator for the map), and it was 0 after the call to push_back(). However, what is even more odd is, I ALSO outputted attr_supported_attr_values.size() after the call to push_back(), and that was 1! Now how could that be since they're both supposed to be the same object??
Note:
The full code of what I'm talking about is below (or at least the attribute code, minus the debugging statements...):
//a_tabindex_attr:
attr_desc = "Specifies the position of an <a> element in the\n"
"tabbing order for the current document.\n"
"The tabbing order defines the order in which\n"
"elements will receive focus when navigated by\n"
"the user via the keyboard. The tabbing order\n"
"may include elements nested within other elements.\n"
"Elements that may receive focus based on tabindex\n"
"adhere to the following rules:\n\n"
"1. Those elements that support this attribute and\n"
"assign a positive value to it are navigated first.\n"
"Navigation proceeds from the element with the\n"
"lowest tabindex value to the element with the\n"
"highest value. Values need not be sequential\n"
"nor must they begin with any particular value.\n"
"Elements that have identical tabindex values\n"
"should be navigated in the order they appear\n"
"in the character stream.\n"
"2. Those elements that do not support this\n"
"attribute or support it and assign it a value\n"
"of \"0\" are navigated next. These elements are\n"
"navigated in the order they appear in the\n"
"character stream.\n"
"3. Elements that are disabled do not participate\n"
"in the tabbing order.";
attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
attr_value_desc = "A number you specify for the tab index/order.\n"
"It must be a value between 0 and 32767.";
attr_value_content = "<i>number</i>";
attr_value = C_html4_attributes_obj.getAttrValue(attr_value_desc, attr_value_content,
attr_value_supported_browsers,
attr_value_required, attr_value_deprecated,
attr_value_notes, attr_value_tips);
attr_value.is_relative = true;
attr_supported_attr_values.push_back(attr_value);
try {
N_init_class_members::initAttr(C_html4_attributes::attr_tabindex, a_tabindex_attr, attr_desc,
attr_supported_browsers, attr_supported_attr_values_map, attr_required,
attr_deprecated, attr_notes, attr_tips);
}
catch (const char* exc) {
string exc_str = "Error! Call to N_init_class_members::initAttr() from\n"
"constructor of C_html4_tags class. That function\n"
"reported the following exception:\n\n";
exc_str += exc;
throw (exc_str.c_str()); //re-throw exception
}
a_tabindex_attr.is_standard_attr = true;
a_tabindex_attr.is_optional_attr = true;
//cleanup from attribute operations so we can begin working on the next attribute:
C_html4_attributes_obj.clear(); //wipes the slate clean for all the supported attributes' properties except content
attr_desc.clear();
attr_supported_attr_values.clear();
attr_supported_attr_values_map.clear();
attr_value_desc.clear();
attr_value_content.clear();

Resources