Hi bogedo
Slick support sent me a fix to the timer callback code that crashed as mentioned in that other thread but I didn't get round to looking at it - just as well because I might have got the timer handle handling wrong. All it needed was a check for the timer callback function already being active. The code below seems to be reliable - it switches to the "minimal" layout for html file extension and otherwise to default layout. It has a global variable for the timer handle. I've used a prefix of "user_bogedo" as this is the recommended way to avoid name collisions. All global variables appear in the global names table regardless of whose code it is.
If you need any more help, let me know.
#include "slick.sh"
#import "sc/lang/ScopedValueGuard.e"
#pragma option(strictsemicolons,on)
#pragma option(strict,on)
#pragma option(autodecl,off)
#pragma option(strictparens,on)
// user_bogedo_my_layout_timer_handle is global because it handles a resource that must
// be freed when the module is loaded. Because it is global, the handle value is preserved
// by the reload.
int user_bogedo_my_layout_timer_handle = -1;
static bool layout_is_default;
static int my_layout_startup_counter;
static _str my_layout_current_buf_name;
static bool in_my_layout_timer_callback1 = false;
static void my_layout_timer_callback1() {
// we need to exit immediately if this function is already active
// It's possible that the call to load_named_layout can result in the slick c interpreter
// checking and running timer callbacks - this code crashes without this.
// A possible alternative is to kill the timer on entry, not tested though.
if ( in_my_layout_timer_callback1 ) {
return;
}
sc.lang.ScopedValueGuard guard(in_my_layout_timer_callback1);
// Note that guard will set in_my_layout_timer_callback1=false when
// this function falls out of scope (i.e on return or end-of-scope).
in_my_layout_timer_callback1 = true;
if (!_use_timers || user_bogedo_my_layout_timer_handle < 0)
return;
if (++my_layout_startup_counter < 6)
return;
my_layout_startup_counter = 6;
if (_no_child_windows()) {
return;
}
if ( get_extension(_mdi.p_child.p_buf_name) == "html" ) {
//say("html " :+ layout_is_default :+ " x " :+ oldbuffname );
if (layout_is_default)
load_named_layout("minimal");
layout_is_default = false;
} else {
//say("nothtml " :+ layout_is_default :+ " x " :+ oldbuffname );
if (!layout_is_default)
load_named_layout("default");
layout_is_default = true;
}
_kill_timer(user_bogedo_my_layout_timer_handle);
user_bogedo_my_layout_timer_handle = _set_timer(1000, my_layout_timer_callback1);
}
void _switchbuf_my_layout_timer() {
if (my_layout_startup_counter < 6)
return;
_kill_timer(user_bogedo_my_layout_timer_handle);
user_bogedo_my_layout_timer_handle = _set_timer(50, my_layout_timer_callback1);
}
definit() {
in_my_layout_timer_callback1 = false;
if (arg(1) == "L" && user_bogedo_my_layout_timer_handle != -1) {
_kill_timer(user_bogedo_my_layout_timer_handle);
}
else {
// this code does not run on every startup, only on some of them. If slickedit decides the module
// needs to be recompiled when it starts up, this code does not run.
// The decision on which state file to use has an effect on this.
user_bogedo_my_layout_timer_handle = -1;
}
user_bogedo_my_layout_timer_handle = _set_timer(1000, my_layout_timer_callback1);
my_layout_startup_counter = 0;
my_layout_current_buf_name = "";
}
Joe
Slick V23 introduced six functions
save-named-layout, load-named-layout
save-named-files, load-named-files
save-named-state, load-named-state
You are prompted for a name and you can delete existing names from the list.
One of the files shown in the code segment below is used to store the information, with the name you supply being the name of a "section" in the file. The data is in the same format as in vrestore.slk I think.
_command void save_named_state(_str sectionName="",bool save_files=true, bool save_layout=true) name_info(',')
{
// This really should have had a .ini extension. Too late now.
_str filename='windowstate.slk';
if (save_files) {
if (save_layout) {
filename='state.ini';
} else {
filename='windowstate.slk';
}
} else/* if (save_layout)*/ {
filename='layoutstate.ini';
}
gload_named_state_name=filename;
filename = _ConfigPath():+filename;
load-named-layout gets toolbars and tool-windows
load-named-files gets just a set of open files
load-named-state gets both layout and files, plus bookmarks and I don't know what else - probably floating edit windows and not the workspace.
I haven't tested the code below but if you create layouts for "midi" and "maxi" it might work.
_command void midi() name_info(',')
{
restore_mdi();
load_named_layout("midi");
}
_command void maxi() name_info(',')
{
maximise_mdi();
load_named_layout("maxi");
}
Clark told me recently that slick C code is single threaded but it seems that the call to load-named-state from within a timer callback can result in the slick interpreter re-running the timer callback so it has to check for re-entrancy. Maybe the call to the file-system to open a file does timer maintenance while waiting for the file operation.