GtkAccelMap paths - discussion

BlitzMax Forums/Brucey's Modules/GtkAccelMap paths - discussion

Brucey(Posted 2008) [#1]
I thought I'd put this up for discussion before I dive in and start to hack the code apart.

Mr Tiffany notes that accelerator groups, once set, can't be modified. The other alternative are accelerator maps. However, these require you to provide some kind of unique "path" reference for each accelerator you add.

Notes from the docs :

The accelerator path must consist of "<WINDOWTYPE>/Category1/Category2/.../Action", where <WINDOWTYPE> should be a unique application-specific identifier, that corresponds to the kind of window the accelerator is being used in, e.g. "Gimp-Image", "Abiword-Document" or "Gnumeric-Settings". The Category1/.../Action portion is most appropriately chosen by the action the accelerator triggers, i.e. for accelerators on menu items, choose the item's menu path, e.g. "File/Save As", "Image/View/Zoom" or "Edit/Select All". So a full valid accelerator path may look like: "<Gimp-Toolbox>/File/Dialogs/Tool Options...".



Now, I dunno how closely these guidelines are meant to be followed, or if it is just a guideline, and we can please ourselves, but from what I understand, the GtkAccelMap is some kind of system-wide singleton...

So... any ideas?

Remember, this is MaxGUI, which is generic, so we are coding below the exposed APIs...

:o)


Mark Tiffany(Posted 2008) [#2]
Remember, this is MaxGUI, which is generic, so we are coding below the exposed APIs...

Stating the obvious for any other readers - ths also means that the need to change current behaviour arises because current GTK behaviour differs from other maxgui implementations.

So... any ideas?

First a question, then some thoughts - is this information used anywhere? It almost looks like the purpose of this is for there to exist a single system-wide app that is used to define hotkeys - is that the case? (Not aware of one). Is this information ever visible to anyone to the best of our knowledge?

Okay, so there's no means to pass additional data in to use for the key maps, so it will have to be generated from existing information.

The most obvious starting point is the AppTitle - use this as at least part of the <WINDOWTYPE>. I guess ideally we would categorise all other windows used by an app, but no idea how we could do that. So maybe just use the window title used when first created? Or would it be simpler to use some kind of window ID (if such a concept exists in gtk?).

As for categories, a hotkey can always be linked to a gadget, e.g. a menu, a button, or for non specific hotkeys, presumably in effect linked to the base window? So category could be type of gadget.

Finally, the action can be derived from the gadget text, e.g. interrogate the menu structure to determine the menu item the key relates to is "File/Save As...", or just take the text of a button "Ok" or "Cancel". the problem will be what to name these...maybe just the name of the keyboard combo?

The issue with some of the above is that it could vary during runtime (e.g. window tile changes). Is that an issue? You'd probably have to track changes to the names of all the gadgets that could be affected and amend the hotkeys then - yuck:

Anyway, in summary:

<WINDOWTYPE> = AppTitle-WindowName
Category1 = GadgetType
Category2 = ~GadgetText

Examples:

MaxIDE-MaxIDE/Menu/File/Save As...
MaxIDE-Find/Button/Find Next
MaxIDE-MaxIDE/Window/Ctrl-Tab


Brucey(Posted 2008) [#3]
It almost looks like the purpose of this is for there to exist a single system-wide app that is used to define hotkeys - is that the case?

I can't seem to find any information on that, so who knows. It certainly implies something when it states "a unique application-specific identifier".

Maybe we can use the appname, rather than apptitle? (I think that's the first entry of appargs? Which could get us around AppTitle change issues.

You are right in saying it might be hard to track gadget titles for paths during runtime. Perhaps we can hang onto the initial value and use that forever.

I wonder if the path even is a proper path, or is just there as some "help" to indicate a unique string. Perhaps one can get away with generating unique ids...


Brucey(Posted 2008) [#4]
Ah. I see...

gtk_accel_map_save() : Saves current accelerator specifications (path, key and modifiers) to filename. The file is written in a format suitable to be read back in by gtk_accel_map_load().

So, the paths are good for persisting your customised hotkey settings between runs of your app.

But I we'll not be needing that for MaxGUI.

Maybe we can do :

<appname>-<windowtitle>/<gadget>/<some-generated-id>

I wonder if we shouldn't follow child heirarchy in the path? Perhaps that's a wee bit of overkill though :-)

<appname>-<windowtitle>/<panel1>/<panel2>/<gadget>/<some-generated-id>


Mark Tiffany(Posted 2008) [#5]
probably overkill to worry about all of the hierarchy.

As the concept is to persist across ultiple runs, the other (unmentioned above) thought of using object refs wouldn't be entirely consistent, even if it would yield a simple unique and persistent "name" for each item.

It probably is best to go with storing the original name of the gadget in every gadget that can gain a hotkey (I'm guessing it only holds the current text at present), and then use that stored value whenever you set the hotkey on the gadget.

Another alternative option could be to change the maxgui API, add a "hotkeyid" tag to SetGadgetHotkey, and then add a "HotkeySave" and "HotkeyLoad" function across all platforms - neatly solving the gtk issue, but creating one for other platforms (albeit that once implemented enables users to very easily save & load hotkeys?

Not convinced, but worth a passing thought...


Brucey(Posted 2008) [#6]
Not sure we want to affect changes to the core API... am always wary of tinkering with things like that if I can help it.

Although Seb seems to enjoy throwing in a new function here or there ;-)

Perhaps if all the platforms gained something in its addition, but otherwise, I suppose I'm happy (interesting choice of word?) enough to try it out by only changing GTK.

Doing my head in at the moment tho... I think I'll start again :-p


Brucey(Posted 2008) [#7]
Well, I made the acceleration errors go away from the CEIDE... but there's lots more I notice... plenty of noise in the treeview, by the looks, and it seg-faults with ease elsewhere too...

It's a start, I suppose...


Mark Tiffany(Posted 2008) [#8]
I wouldn't be surprised about errors in the treeview. I think treeviews could do with some cross-platform love, as there's code in there to deal with macos working differently...so wouldn't be surprised if that hack for macos is also needed for gtk?

The seg faults are weird - first of all it used to do it every time when calling bmk (for version info in startup), and commenting it out would get it working fully. Then Seb fixed freeprocess, and that error went away, but then I'd added hotkey config, and it errored on hotkeys, and then hangs regardless of whether I turned off the hotkey stuff. I think I then hacked out all treeview business (I think the easiest way was to Return immediately inside the datanode Sync code), but even then it was still unstable...


Brucey(Posted 2008) [#9]
But I thought the whole point of MaxGUI was we didn't have to hack in anything ;-)

Anyhoo. There's one small caveat to this new accelerator implementation... which is the shortcuts don't appear in the menus. I've as yet been unable to work out how to get them back in there *sigh*. (although I've found GtkAction, which seems to be yet another way of doing this kind of thing...)

Checked in anyway, for your amusement.


Brucey(Posted 2008) [#10]
I think the only problem I have with tracking down these errors, is knowing whereto start :-p

I'll try to have a rummage anyway.


Mark Tiffany(Posted 2008) [#11]
Ta. I'll take a look at ce ide on gtk later, but probably not the best place for you to start when trying to find a bug. Does the official IDE compile okay with gtk?


Brucey(Posted 2008) [#12]
I'm running the official IDE as my IDE now, so yes, it all seems to work fine. I've not had any issues with it since I sorted out those other things. :-)

Even the splash screen works :-p


SebHoll(Posted 2008) [#13]
Wow, you've certainly been busy.

But I thought the whole point of MaxGUI was we didn't have to hack in anything ;-)

Precisely, which is why I don't think I like the idea of having to tweak SetGadgetHotKey() just for GTK. If we could get away with it, I think it would be better to keep the same API the other platforms use.

Am I missing something here? Is all this work needed just to remove a gadget hot key? Couldn't we just re-assign it to a internal invisible gadget (effectively disabling it) or am I being stupid?

I wouldn't be surprised about errors in the treeview. I think treeviews could do with some cross-platform love

This is probably because of the different ways each platform handles treeviews. Win32 API has a dedicated treeview control (nice and simple!), Cocoa uses an NSTableView control and so is really a table with a few extras for hiding/showing indented items. FLTK (lol), well that doesn't actually have a treeview control, so it is actually a listbox with some of Skid's magic code that hide and shows items, recreating lists, and intercepting events to process item collapsing/expansion.

You're right though, Mark, the platform behavior should be consistent in MaxGUI, so if you get a chance, could you post some bug reports?


Mark Tiffany(Posted 2008) [#14]

Am I missing something here? Is all this work needed just to remove a gadget hot key? Couldn't we just re-assign it to a internal invisible gadget (effectively disabling it) or am I being stupid?

There are (at least) two ways of assigning a hotkey to a gadget in gtk. Either when you create the gadget (in which case gtk does not let you change it in any way whatsoever after creating it), or by using the above mentioned gtk api. So yes, it's painful, but unfortunately it appears to be necessary to duplicate behaviour on other platforms.

And I basically agree on the "don't change the API" point, just thought I'd offer up the thought in case it sounded like an easier way through.

And apologies, but I didn't get time to fire up linux this evening (finally decided to sit down and watch atonement on DVD with the wife - she might stop moaning about time on the computer for a couple of days now...)

As for treeview bug reports, not sure where to start, and have never really dug into it to be honest : but I've seen enough to have my suspicions! The one thing I know for sure causes some kind of issue is free-ing / removing nodes. Look in the official ide code for wherever it sync's datanodes & treenodes. I think you'll find a FreeTreeViewNode wrapped in a ?macos construct. TBH, I've tended to leave well alone, so never tried to isolate the problem, which doesn't help you I'm afraid...


SebHoll(Posted 2008) [#15]
There are (at least) two ways of assigning a hotkey to a gadget in gtk. Either when you create the gadget (in which case gtk does not let you change it in any way whatsoever after creating it), or by using the above mentioned gtk api. So yes, it's painful, but unfortunately it appears to be necessary to duplicate behaviour on other platforms.

OK, well couldn't we just get GTKMaxGUI to free the gadget and recreate an identical one without a hot key? Would that not be easier and would avoid all this low-level accelerator map stuff?


Brucey(Posted 2008) [#16]
Well, the gadget hotkey stuff appears to be working, sort of, maybe... at least the errors in the CEIDE went away.

I could probably do with a small example for any issues, rather than trying to debug a big app - you know how it is ;-)

Sure, it might be possible to drop and create the gadget, but that seems to be a bit overkill, plus you'll need to remember location/size/etc to get it back into the same place - which may, or may not work as expected.

But everything should be able to be done without a change to the API.. which perhaps wasn't clear above?
"all this low-level" stuff is already being done in the GTK wrapper anyway :-p What's a little more?
Funny though, that those bloody little angle-brackets <MyApp-Window> are actually a requirement in the path :-p


I had a go at digging out the treeview errors for CEIDE/GTK, but I got lost along the way, so rolled back my first attempt (one of the joys of SVN!)...
I wonder what the CEIDE is up to that the official IDE doesn't have issues with - since it works apparently perfectly using GTK in its current form.


Mark Tiffany(Posted 2008) [#17]
I wonder what the CEIDE is up to that the official IDE doesn't have issues with - since it works apparently perfectly using GTK in its current form.

I rewrote a chunk of code in the treeviewnode stuff as it was (is) a real spiders web of horribleness. Major issues found with the order things were freed in and memory leaks from nodes not being freed when they should be, etc, not to mention very poor performance because it would often re-build everything every time. I still don't like that area of code one little bit, but it is stable on Windows now.

Possible causes of errors I can think of without going into the code:
- Trying to do something to a treeview node that has been freed
- Trying to do something to a treeview node that has bene hidden
- hiding / showing / collapsing nodes

The above could probably be tested in a simple app (may be worth extending the treeview sample code a bit to create a test harness we can prove across all four gui implementations.


SebHoll(Posted 2008) [#18]
Sure, it might be possible to drop and create the gadget, but that seems to be a bit overkill, plus you'll need to remember location/size/etc to get it back into the same place - which may, or may not work as expected.

Well size and location is stored inside the TGadget instance anyway. TGTKGadget appears to store its visibility and style, font and tooltip. The text could be retrieved and temporary stored by the gadget before it is recreated. All doable, and perhaps worthy of consideration if this other method becomes too difficult. Arguably, all these maps seen overkill for just a few simple hotkeys. Ah well, it's up to you. ;-)


Brucey(Posted 2008) [#19]
Trying to do something to a treeview node that has been freed

That's probably not a good idea.

Should I be checking for this myself, or should an app have more sense?
I would prefer the latter...


SebHoll(Posted 2008) [#20]
Trying to do something to a treeview node that has been freed

You're right, MaxGUI apps should not attempt to access gadgets once they have been freed. If anything, its bad practice.

Mark T:

Look in the official ide code for wherever it sync's datanodes & treenodes. I think you'll find a FreeTreeViewNode wrapped in a ?macos construct.

Just had a look now, and can't seem to find anything like that in maxide.bmx. Maybe it was one of the things that I ripped out when I replaced the debugger tree stuff, although I can't remember my changes having anything to do with the the creation/freeing of nodes (this was handled automatically by TNode iirc).


Mark Tiffany(Posted 2008) [#21]
That's probably not a good idea.

Should I be checking for this myself, or should an app have more sense?
I would prefer the latter...

Agreed, but I recall it failing silently on Windows, but gtk is (rightly) more noisy about it.


Just had a look now, and can't seem to find anything like that in maxide.bmx


I was utterly convinced this was in the original maxide code, but can't see it in current versions. May no longer be necessary?

?MacOS ' MacOS doesn't allow "adding" TreeView nodes by "inserting" them after the last node