diff --git a/ivette/src/dome/src/renderer/data/settings.ts b/ivette/src/dome/src/renderer/data/settings.ts
index e6e3a8a246e453da738b9ec83e2798b058924b97..3cf6d7cd231d0554031d60b11f9e239fdc42329e 100644
--- a/ivette/src/dome/src/renderer/data/settings.ts
+++ b/ivette/src/dome/src/renderer/data/settings.ts
@@ -345,7 +345,13 @@ export function useGlobalSettings<A>(S: GlobalSettings<A>) {
 // --- Settings Synchronization
 // --------------------------------------------------------------------------
 
-/*@ internal */
+/* @ internal */
+export const window = WindowDriver.evt;
+
+/* @ internal */
+export const global = GlobalDriver.evt;
+
+/* @ internal */
 export function synchronize() {
   ipcRenderer.sendSync(
     'dome.ipc.settings.sync',
@@ -354,7 +360,8 @@ export function synchronize() {
       GlobalDriver.sync(globals);
       const settings: patch[] = data.settings ?? [];
       WindowDriver.sync(settings);
-    });
+    },
+  );
 }
 
 // --------------------------------------------------------------------------
diff --git a/ivette/src/dome/src/renderer/dome.ts b/ivette/src/dome/src/renderer/dome.ts
index ab451cbafcb378f968e2188e9794c8f5d9e51c1f..aac7877c772d10758b62330df706dd11d6b9bfb0 100644
--- a/ivette/src/dome/src/renderer/dome.ts
+++ b/ivette/src/dome/src/renderer/dome.ts
@@ -1,26 +1,24 @@
 /**
-   @packageDocumentation
-   @module dome(renderer)
-   @description
-
-   ## Dome Application (Renderer Process)
+   Dome Application (Renderer Process)
 
    This modules manages your main application window
    and its interaction with the main process.
 
    Example:
 
-   ```typescript
-   // File 'src/renderer/index.js':
-   import Application from './Application.js' ;
-   Dome.setContent( Application );
-   ```
+   * ```ts
+   *   // File 'src/renderer/index.js':
+   *   import Application from './Application.js' ;
+   *   Dome.setContent( Application );
+   * ```
+
+   @packageDocumentation
+   @module dome
  */
 
 import _ from 'lodash';
 import React from 'react';
 import ReactDOM from 'react-dom';
-import type Emitter from 'events';
 import { AppContainer } from 'react-hot-loader';
 import { remote, ipcRenderer } from 'electron';
 import SYS, * as System from 'dome/system';
@@ -33,14 +31,14 @@ import './style.css';
 // --------------------------------------------------------------------------
 
 // main window focus
-var focus = true;
+let windowFocus = true;
 
 function setContextAppNode() {
   const node = document.getElementById('app');
   if (node) {
     node.className =
-      'dome-container dome-platform-' + System.platform +
-      (focus ? ' dome-window-active' : ' dome-window-inactive');
+      `dome-container dome-platform-${System.platform
+      }${windowFocus ? ' dome-window-active' : ' dome-window-inactive'}`;
   }
   return node;
 }
@@ -50,7 +48,7 @@ function setContextAppNode() {
 // --------------------------------------------------------------------------
 
 /** Configured to be `'true'` when in development mode. */
-export const DEVEL = System.DEVEL;
+export const { DEVEL } = System;
 
 export type PlatformKind = 'linux' | 'macos' | 'windows';
 
@@ -61,50 +59,147 @@ export const platform: PlatformKind = (System.platform as PlatformKind);
 // --- Application Emitter
 // --------------------------------------------------------------------------
 
-/** Register a callback on Dome event. */
-export function on(
-  evt: string,
-  job: (...args: any[]) => void,
-) { System.emitter.on(evt, job); }
+/** Typed Dome Event.
+
+    To register an event with no argument, simply use `new Event('myEvent')`.
+*/
+export class Event<A = void> {
+
+  private name: string;
+
+  constructor(name: string) {
+    this.name = name;
+    this.emit = this.emit.bind(this);
+  }
+
+  on(callback: (arg: A) => void) {
+    System.emitter.on(this.name, callback);
+  }
+
+  off(callback: (arg: A) => void) {
+    System.emitter.off(this.name, callback);
+  }
+
+  /**
+     Notify all listeners with the provided argument.
+     This methods is bound to the event, so you may use `myEvent.emit`
+     as a callback function, instead of eg. `(arg) => myEvent.emit(arg)`.
+  */
+  emit(arg: A) {
+    System.emitter.emit(this.name, arg);
+  }
+
+  /**
+     Number of currenty registered listeners.
+   */
+  listenerCount() {
+    return System.emitter.listenerCount(this.name);
+  }
 
-/** Register a callback on Dome event. */
-export function off(
-  evt: string,
-  job: (...args: any[]) => void,
-) { System.emitter.off(evt, job); }
+}
 
-/** Emit a Dome event (Same as [[dome/misc/system.event]]). */
-export function emit(
-  evt: string,
-  ...args: any[]
-) { System.emitter.emit(evt, ...args); }
+export function useEvent<A>(
+  evt: Event<A>,
+  callback: (arg: A) => void,
+) {
+  return React.useEffect(() => {
+    evt.on(callback);
+    return () => evt.off(callback);
+  });
+}
 
 // --------------------------------------------------------------------------
 // --- Application Events
 // --------------------------------------------------------------------------
 
-/** Emits the `dome.update` event. */
-export function update() { emit('dome.update'); }
-
-/** Update event handler. */
-export function onUpdate(job: () => void) { on('dome.update', job); }
+/**
+   Dome update event.
+   It is emitted when a general re-rendering is required, typically when
+   the window frame is resized.
+   You can use it for your own components as an easy-to-use global
+   re-render event.
+*/
+export const update = new Event('dome.update');
 
-/** Unregister an update event handler. */
-export function offUpdate(job: () => void) { off('dome.update', job); }
+/**
+   Dome reload event.
+   It is emitted when the entire window is reloaded.
+*/
+export const reload = new Event('dome.reload');
 
-/** Reload event handler. */
-export function onReload(job: () => void) { on('dome.reload', job); }
-ipcRenderer.on('dome.ipc.reload', () => emit('dome.reload'));
+ipcRenderer.on('dome.ipc.reload', () => reload.emit());
 
 /** Command-line arguments event handler. */
 export function onCommand(
-  job: (argv: string[], workingDir: string) => void
-) { on('dome.command', job); }
+  job: (argv: string[], workingDir: string) => void,
+) {
+  System.emitter.on('dome.command', job);
+}
+
 ipcRenderer.on('dome.ipc.command', (_event, argv, wdir) => {
   SYS.SET_COMMAND(argv, wdir);
-  emit('dome.command', argv, wdir);
+  System.emitter.emit('dome.command', argv, wdir);
+});
+
+/** Window Settings event.
+    Emitted when window settings are reset or restored. */
+export const windowSettings = new Event(Settings.window);
+
+/** Global Settings event.
+    Emiited when global settings are updated. */
+export const globalSettings = new Event(Settings.global);
+
+// --------------------------------------------------------------------------
+// --- Closing
+// --------------------------------------------------------------------------
+
+ipcRenderer.on('dome.ipc.closing', System.doExit);
+
+/** Register a callback to be executed when the window is closing. */
+export function atExit(callback: () => void) {
+  System.atExit(callback);
+}
+
+// --------------------------------------------------------------------------
+// --- Focus Management
+// --------------------------------------------------------------------------
+
+/** Window focus event. */
+export const focus = new Event<boolean>('dome.focus');
+
+/** Current focus state of the main window. See also [[useWindowFocus]]. */
+export function isFocused() { return windowFocus; }
+
+ipcRenderer.on('dome.ipc.focus', (_sender, value) => {
+  windowFocus = value;
+  setContextAppNode();
+  focus.emit(value);
 });
 
+/** Return the current window focus. See [[isfocused]]. */
+export function useWindowFocus(): boolean {
+  useUpdate(focus);
+  return windowFocus;
+}
+
+// --------------------------------------------------------------------------
+// --- Web Navigation
+// --------------------------------------------------------------------------
+
+/**
+   DOM href events for internal URLs.
+
+   This event is emitted whenever some `<a href/>` DOM element
+   is clicked with an internal link. External links will be automatically
+   opened with the user's default Web navigator.
+ */
+export const navigate = new Event<string>('dome.href');
+
+ipcRenderer.on(
+  'dome.ipc.href',
+  (_sender, href) => navigate.emit(href),
+);
+
 // --------------------------------------------------------------------------
 // --- Window Management
 // --------------------------------------------------------------------------
@@ -137,7 +232,7 @@ export function setTitle(title: string) {
 // --------------------------------------------------------------------------
 
 function setContainer(
-  Component: React.FunctionComponent | React.ComponentClass
+  Component: React.FunctionComponent | React.ComponentClass,
 ) {
   Settings.synchronize();
   const appNode = setContextAppNode();
@@ -153,16 +248,16 @@ function setContainer(
 /**
    Defines the user's main window content.
 
-   Binds the component to the main window.
-   <strong>Notes:</strong> a `<Component/>` instance is generated and rendered in the `#app`
-   window element. Its class name is set to `dome-platform-<platform>` with
-   the `<platform>` set to the `Dome.platform` value. This class name can be used
-   as a CSS selector for platform-dependent styling.
+   Binds the component to the main window.  A `<Component/>` instance is
+   generated and rendered in the `#app` window element. Its class name is set to
+   `dome-platform-<platform>` with the `<platform>` set to the `Dome.platform`
+   value. This class name can be used as a CSS selector for platform-dependent
+   styling.
 
    @param Component - to be rendered in the main window
 */
 export function setApplicationWindow(
-  Component: React.FunctionComponent | React.ComponentClass
+  Component: React.FunctionComponent | React.ComponentClass,
 ) {
   if (isApplicationWindow()) setContainer(Component);
 }
@@ -174,15 +269,15 @@ export function setApplicationWindow(
 /**
    Defines the user's preferences window content.
 
-   <strong>Notes:</strong> a `<Component/>` instance is generated and rendered in the `#app`
-   window element. Its class name is set to `dome-platform-<platform>` with
-   the `<platform>` set to the `Dome.platform` value. This class name can be used
-   as a CSS selector for platform-dependent styling.
+   A `<Component/>` instance is generated and rendered in the `#app` window
+   element. Its class name is set to `dome-platform-<platform>` with the
+   `<platform>` set to the `Dome.platform` value. This class name can be used as
+   a CSS selector for platform-dependent styling.
 
    @param Component - to be rendered in the preferences window
 */
 export function setPreferencesWindow(
-  Component: React.FunctionComponent | React.ComponentClass
+  Component: React.FunctionComponent | React.ComponentClass,
 ) {
   if (isPreferencesWindow()) setContainer(Component);
 }
@@ -191,7 +286,8 @@ export function setPreferencesWindow(
 // --- MenuBar Management
 // --------------------------------------------------------------------------
 
-const customItemCallbacks = new Map<string, (() => void)>();
+type callback = () => void;
+const customItemCallbacks = new Map<string, callback>();
 
 /**
    Create a new custom menu in the menu bar.
@@ -293,7 +389,7 @@ export function setMenuItem(options: MenuItemOptions) {
 
 ipcRenderer.on('dome.ipc.menu.clicked', (_sender, id: string) => {
   const callback = customItemCallbacks.get(id);
-  callback && callback();
+  if (callback) callback();
 });
 
 // --------------------------------------------------------------------------
@@ -343,19 +439,19 @@ export function popupMenu(
 ) {
   const { Menu, MenuItem } = remote;
   const menu = new Menu();
-  var selected = '';
-  var kid = 0;
+  let selected = '';
+  let kid = 0;
   items.forEach((item) => {
     if (item === 'separator')
       menu.append(new MenuItem({ type: 'separator' }));
     else if (item) {
       const { display = true, enabled, checked } = item;
       if (display) {
-        const label = item.label || '#' + (++kid);
+        const label = item.label || `#${++kid}`;
         const id = item.id || label;
         const click = () => {
           selected = id;
-          item.onClick && item.onClick();
+          if (item.onClick) item.onClick();
         };
         const type = checked !== undefined ? 'checkbox' : 'normal';
         menu.append(new MenuItem({ label, enabled, type, checked, click }));
@@ -366,53 +462,6 @@ export function popupMenu(
   menu.popup({ window: remote.getCurrentWindow(), callback: job });
 }
 
-// --------------------------------------------------------------------------
-// --- Closing
-// --------------------------------------------------------------------------
-
-ipcRenderer.on('dome.ipc.closing', System.doExit);
-
-// --------------------------------------------------------------------------
-// --- Focus Management
-// --------------------------------------------------------------------------
-
-/** Current focus state of the main window. See also [[useWindowFocus]]. */
-export function isFocused() { return focus; }
-
-ipcRenderer.on('dome.ipc.focus', (_sender, value) => {
-  focus = value;
-  setContextAppNode();
-  System.emitter.emit('dome.focus', value);
-});
-
-/** Return the current window focus. See [[isfocused]]. */
-export function useWindowFocus(): boolean {
-  useUpdate('dome.focus');
-  return focus;
-}
-
-// --------------------------------------------------------------------------
-// --- Web Navigation
-// --------------------------------------------------------------------------
-
-ipcRenderer.on(
-  'dome.ipc.href',
-  (href) => System.emitter.emit('dome.href', href)
-);
-
-/**
-   Register a callback to handle clicks on a local `<a href=...>`
-   with non-http protocoles.
-
-   URL with an `http://` protocole are opened externally
-   by the user's default browser.
-
-   Other URLs shall be treated by the application _via_ this callback.
-*/
-export function onDOMhref(callback: (href: string) => void) {
-  System.emitter.on('dome.href', callback);
-}
-
 // --------------------------------------------------------------------------
 // --- React Hooks
 // --------------------------------------------------------------------------
@@ -430,65 +479,15 @@ export function useForceUpdate() {
    Hook to re-render on Dome events (Custom React Hook).
    @param events - event names, defaults to a single `'dome.update'`.
 */
-export function useUpdate(...events: string[]) {
-  const update = useForceUpdate();
+export function useUpdate(...events: Event<any>[]) {
+  const fn = useForceUpdate();
   React.useEffect(() => {
-    const trigger = () => setImmediate(update);
-    if (events.length == 0) events.push('dome.update');
-    events.forEach((evt) => System.emitter.on(evt, trigger));
-    return () => events.forEach((evt) => System.emitter.off(evt, trigger));
-  });
-}
-
-/**
-   Hook to register callbacks to Dome events (Custom React Hook).
-
-   Register the callback on event until the component is unmount.
-   Do not force the component to re-render (unless the callback does).
-
-   @param event - Event to register on
-   @param callback - The callback to register
-*/
-export function useEvent(event: string, callback: () => void) {
-  React.useEffect(() => {
-    System.emitter.on(event, callback);
-    return () => { System.emitter.off(event, callback); };
-  });
-}
-
-/**
-   Hook to register callbacks to events on an emitter (Custom React Hook).
-   Similar to [[useEvent]].
-*/
-export function useEmitter(
-  emitter: Emitter,
-  evt: string,
-  callback: () => void,
-) {
-  React.useEffect(() => {
-    emitter.on(evt, callback);
-    return () => { emitter.off(evt, callback); };
-  });
-}
-
-// --------------------------------------------------------------------------
-// --- Commands Hooks
-// --------------------------------------------------------------------------
-
-/**
-   Hook for command-line interface (Custom React Hook).
-   Returns the command-line arguments and working directory for the application
-   instance running in the window. Automatically updated on `dome.command` events.
-
-   @returns `[argv,wdir]` command-line arguments and working directory
-
-   See also [[onCommand]] event handler.
-*/
-export function useCommand(): [string[], string] {
-  useUpdate('dome.command');
-  const wdir = System.getWorkingDir();
-  const argv = System.getArguments();
-  return [argv, wdir];
+    const trigger = () => setImmediate(fn);
+    if (events.length === 0) events.push(update);
+    events.forEach((evt) => evt.on(trigger));
+    return () => events.forEach((evt) => evt.off(trigger));
+  }, [fn, ...events]); // eslint-disable-line react-hooks/exhaustive-deps
+  // The rule signals events is missing, probably because of « … »
 }
 
 // --------------------------------------------------------------------------
@@ -501,12 +500,12 @@ interface Clock {
   time: number; // Ellapsed time since firts pending
   event: string; // Tic events
   period: number; // Period
-};
+}
 
 // Collection of clocks indexed by period
 const CLOCKS = new Map<number, Clock>();
 
-const CLOCKEVENT = (period: number) => 'dome.clock.' + period;
+const CLOCKEVENT = (period: number) => `dome.clock.${period}`;
 
 const TIC_CLOCK = (clk: Clock) => () => {
   if (0 < clk.pending) {
@@ -521,8 +520,8 @@ const TIC_CLOCK = (clk: Clock) => () => {
 const INC_CLOCK = (period: number) => {
   let clk = CLOCKS.get(period);
   if (!clk) {
-    let event = CLOCKEVENT(period);
-    let time = (new Date()).getTime();
+    const event = CLOCKEVENT(period);
+    const time = (new Date()).getTime();
     clk = { pending: 0, time, period, event };
     clk.timer = setInterval(TIC_CLOCK(clk), period);
     CLOCKS.set(period, clk);
@@ -532,7 +531,7 @@ const INC_CLOCK = (period: number) => {
 };
 
 const DEC_CLOCK = (period: number) => {
-  let clk = CLOCKS.get(period);
+  const clk = CLOCKS.get(period);
   if (clk) clk.pending--;
 };
 
@@ -582,9 +581,8 @@ export function useClock(period: number, initStart: boolean): Timer {
         System.emitter.off(event, callback);
         DEC_CLOCK(period);
       };
-    } else
-      return undefined;
-  }, [running]);
+    } return undefined;
+  }, [period, running]);
   return { time, running, start, stop };
 }
 
@@ -606,11 +604,11 @@ export function useBoolSettings(
   defaultValue = false,
 ): FlipState {
   const [state, setState] = Settings.useWindowSettings(
-    key, Json.jBoolean, defaultValue
+    key, Json.jBoolean, defaultValue,
   );
   const flipState = React.useCallback(
     (v) => setState(v === undefined ? !state : v),
-    [state, setState]
+    [state, setState],
   );
   return [state, flipState];
 }
@@ -618,26 +616,26 @@ export function useBoolSettings(
 /** Number window settings helper. Default is `0` unless specified. */
 export function useNumberSettings(key: string | undefined, defaultValue = 0) {
   return Settings.useWindowSettings(
-    key, Json.jNumber, defaultValue
+    key, Json.jNumber, defaultValue,
   );
 }
 
 /** String window settings. Default is `''` unless specified). */
 export function useStringSettings(key: string | undefined, defaultValue = '') {
   return Settings.useWindowSettings(
-    key, Json.jString, defaultValue
+    key, Json.jString, defaultValue,
   );
 }
 
 /** Optional string window settings. Default is `undefined`. */
 export function useStringOptSettings(key: string | undefined) {
   return Settings.useWindowSettings(
-    key, Json.jString, undefined
+    key, Json.jString, undefined,
   );
 }
 
 /** Direct shortcut to [[dome/data/settings.useWindowSettings]]. */
-export const useWindowSettings = Settings.useWindowSettings;
+export const { useWindowSettings } = Settings;
 
 /**
    Utility shortcut to [[dome/data/settings.useGlobalSettings]]
@@ -646,11 +644,11 @@ export const useWindowSettings = Settings.useWindowSettings;
 export function useGlobalSettings<A extends Json.json>(
   globalKey: string,
   decoder: Json.Loose<A>,
-  defaultValue: A
+  defaultValue: A,
 ) {
   // Object creation is cheaper than useMemo...
   const G = new Settings.GlobalSettings(
-    globalKey, decoder, Json.identity, defaultValue
+    globalKey, decoder, Json.identity, defaultValue,
   );
   return Settings.useGlobalSettings(G);
 }
@@ -664,15 +662,22 @@ export class Debug {
   constructor(moduleName: string) {
     this.moduleName = moduleName;
   }
+
+  /* eslint-disable no-console */
+
   log(...args: any) {
     if (DEVEL) console.log(`[${this.moduleName}]`, ...args);
   }
+
   warn(...args: any) {
     if (DEVEL) console.warn(`[${this.moduleName}]`, ...args);
   }
+
   error(...args: any) {
     if (DEVEL) console.error(`[${this.moduleName}]`, ...args);
   }
+
+  /* eslint-enable */
 }
 
 // --------------------------------------------------------------------------
diff --git a/ivette/src/dome/src/renderer/layout/boxes.tsx b/ivette/src/dome/src/renderer/layout/boxes.tsx
index 2d98e79fd1753cd726bf857c092db42f18cb9f52..d95a01e940833421a464cd9844ebd4b14ffd900a 100644
--- a/ivette/src/dome/src/renderer/layout/boxes.tsx
+++ b/ivette/src/dome/src/renderer/layout/boxes.tsx
@@ -180,12 +180,13 @@ export const Folder = (props: FolderProps) => {
     indent = 18,
     label, title, children,
   } = props;
-  const [unfold, onClick] = Dome.useSwitch(settings, defaultUnfold);
+  const [unfold, onClick] = Dome.useBoolSettings(settings, defaultUnfold);
+  const foldUnfold = React.useCallback(() => onClick(), [onClick]);
   const icon = unfold ? 'TRIANGLE.DOWN' : 'TRIANGLE.RIGHT';
   const display = unfold ? 'none' : 'block';
   return (
     <Vpack>
-      <Hpack onClick={onClick}>
+      <Hpack onClick={foldUnfold}>
         <Title icon={icon} label={label} title={title} />
       </Hpack>
       <Vpack style={{ display, marginLeft: indent }}>
diff --git a/ivette/src/dome/src/renderer/table/views.tsx b/ivette/src/dome/src/renderer/table/views.tsx
index 1020db211e4783c372277ea0de322ae2ec2a2931..1adb34a0f4873bfa36115555c614ca388c52d0e9 100644
--- a/ivette/src/dome/src/renderer/table/views.tsx
+++ b/ivette/src/dome/src/renderer/table/views.tsx
@@ -259,7 +259,7 @@ function makeDataRenderer(
 type TableSettings = {
   resize?: Json.dict<number>;
   visible?: Json.dict<boolean>;
-}
+};
 
 const jTableSettings = Json.jObject({
   resize: Json.jDict(Json.jNumber),
@@ -1094,7 +1094,7 @@ export function Table<Key, Row>(props: TableProps<Key, Row>) {
     state.onContextMenu = props.onContextMenu;
     return state.unwind;
   });
-  Dome.useEvent('dome.settings.window', state.reloadSettings);
+  Dome.useEvent(Dome.windowSettings, state.reloadSettings);
   return (
     <div className="dome-xTable">
       <React.Fragment key="columns">
diff --git a/ivette/src/frama-c/LabViews.tsx b/ivette/src/frama-c/LabViews.tsx
index 84f97ec9f14bb70cf38fda5c7077a1a5ee9dafc7..e1465dda5981e8a5a7deeb60ecad5c9a0c40d059 100644
--- a/ivette/src/frama-c/LabViews.tsx
+++ b/ivette/src/frama-c/LabViews.tsx
@@ -38,6 +38,8 @@ class Library {
   collection: {};
   items: any[];
 
+  static update = new Dome.Event('labview.library');
+
   constructor() {
     this.modified = false;
     this.virtual = {};
@@ -50,7 +52,7 @@ class Library {
       this.collection = { ...this.virtual };
       this.items = _.sortBy(this.collection, ['order', 'id']);
       this.modified = false;
-      Dome.emit('labview.library');
+      Library.update.emit();
     }
   }
 
@@ -351,13 +353,12 @@ const makeGridItem = (customize: any, onClose: any) => (comp: any) => {
 // --- Customization Views
 // --------------------------------------------------------------------------
 
-const Stock = new Settings.GDefault('frama-c.labView', Json.jAny, {});
-
 function CustomViews({ settings, shape, setShape, views: libViews }: any) {
   const [local, setLocal] = Settings.useWindowSettings(
     settings, Json.jAny, {},
   ) as any;
-  const [customs, setCustoms] = Settings.useGlobalSettings(Stock) as any;
+  const [customs, setCustoms] =
+    Dome.useGlobalSettings<any>('frama-c.labview', Json.jAny, {});
   const [edited, setEdited]: any = React.useState();
   const triggerDefault = React.useRef();
   const { current, shapes = {} } = local;
@@ -571,7 +572,7 @@ function CustomGroup({
 function CustomizePanel(
   { dnd, settings, library, shape, setShape, setDragging }: any,
 ) {
-  Dome.useUpdate('labview.library');
+  Dome.useUpdate(Library.update);
   const { items } = library;
   const views = getItems(items, 'views');
   const groups = getItems(items, 'groups');
@@ -640,9 +641,9 @@ export function LabView(props: any) {
   const settingPanel = settings && `${settings}.panel`;
   // Hooks & State
   Dome.useUpdate(
-    'labview.library',
-    'dome.settings.window',
-    'dome.settings.global',
+    Library.update,
+    Dome.windowSettings,
+    Dome.globalSettings,
   );
   const dnd = React.useMemo(() => new DnD(), []);
   const lib = React.useMemo(() => new Library(), []);
diff --git a/ivette/src/frama-c/server.ts b/ivette/src/frama-c/server.ts
index 51190f03fdc8debdf08ab53104736a44a02d1a76..33591e19bacfb0e8656c34cc45cede650c7d1525 100644
--- a/ivette/src/frama-c/server.ts
+++ b/ivette/src/frama-c/server.ts
@@ -32,7 +32,7 @@ const D = new Dome.Debug('Server');
 
  *  This event is emitted whenever the server status changes.
  */
-const STATUS = 'frama-c.server.status';
+const STATUS = new Dome.Event<Status>('frama-c.server.status');
 
 /**
  *  Server is actually started and running.
@@ -40,7 +40,7 @@ const STATUS = 'frama-c.server.status';
  *  This event is emitted when ther server _enters_ the `ON` state.
  *  The server is now ready to handle requests.
  */
-const READY = 'frama-c.server.ready';
+const READY = new Dome.Event('frama-c.server.ready');
 
 /**
  *  Server Status Notification Event
@@ -48,21 +48,18 @@ const READY = 'frama-c.server.ready';
  *  This event is emitted when ther server _leaves_ the `ON` state.
  *  The server is no more able to handle requests until restart.
  */
-const SHUTDOWN = 'frama-c.server.shutdown';
+const SHUTDOWN = new Dome.Event('frama-c.server.shutdown');
 
 /**
- *  Server Signal Prefix
+ *  Server Signal event constructor.
 
  *  Event `frama-c.server.signal.<id>'` for signal `<id>`.
  */
-const SIGNAL = 'frama-c.server.signal.';
-
-/**
- *  Server Signal Activity Prefix
-
- *  Event `frama-c.server.activity.<id>'` for signal `<id>`.
- */
-const ACTIVITY = 'frama-c.server.activity.';
+export class SIGNAL extends Dome.Event {
+  constructor(signal: string) {
+    super(`frama-c.server.signal.${signal}`);
+  }
+}
 
 // --------------------------------------------------------------------------
 // --- Server Status
@@ -200,22 +197,13 @@ export function getPending(): number {
  *  Register callback on `READY` event.
  *  @param {function} callback Invoked when the server enters [[ON]] stage.
  */
-export function onReady(callback: any) { Dome.on(READY, callback); }
+export function onReady(callback: () => void) { READY.on(callback); }
 
 /**
  *  Register callback on `SHUTDOWN` event.
  *  @param {function} callback Invoked when the server leaves [[ON]] stage.
  */
-export function onShutdown(callback: any) { Dome.on(SHUTDOWN, callback); }
-
-/**
- *  Register callback on a signal `ACTIVITY` event.
- *  @param {string} id The signal identifier to listen to.
- *  @param {function} callback Invoked with `callback(signal, active)`.
- */
-export function onActivity(signal: string, callback: any) {
-  Dome.on(ACTIVITY + signal, callback);
-}
+export function onShutdown(callback: () => void) { SHUTDOWN.on(callback); }
 
 // --------------------------------------------------------------------------
 // --- Status Update
@@ -229,9 +217,9 @@ function _status(newStatus: Status) {
   if (newStatus !== status) {
     const oldStatus = status;
     status = newStatus;
-    Dome.emit(STATUS);
-    if (oldStatus.stage === Stage.ON) Dome.emit(SHUTDOWN);
-    if (newStatus.stage === Stage.ON) Dome.emit(READY);
+    STATUS.emit(newStatus);
+    if (oldStatus.stage === Stage.ON) SHUTDOWN.emit();
+    if (newStatus.stage === Stage.ON) READY.emit();
   }
 }
 
@@ -368,12 +356,9 @@ export function restart() {
 export function clear() {
   switch (status.stage) {
     case Stage.FAILURE:
-      buffer.clear();
-      _status(okStatus(Stage.OFF));
-      return;
     case Stage.OFF:
       buffer.clear();
-      Dome.emit(STATUS);
+      _status(okStatus(Stage.OFF));
       return;
     default:
       return;
@@ -587,7 +572,7 @@ function _exit(error?: Error) {
 
 class SignalHandler {
   id: any;
-  event: string;
+  event: Dome.Event;
   active: boolean;
   listen: boolean;
 
@@ -601,18 +586,20 @@ class SignalHandler {
     this.unplug = this.unplug.bind(this);
   }
 
-  on(callback: any) {
-    const n = System.emitter.listenerCount(this.event);
-    Dome.on(this.event, callback);
+  on(callback: () => void) {
+    const e = this.event;
+    const n = e.listenerCount();
+    e.on(callback);
     if (n === 0) {
       this.active = true;
       if (isRunning()) this.sigon();
     }
   }
 
-  off(callback: any) {
-    Dome.off(this.event, callback);
-    const n = System.emitter.listenerCount(this.event);
+  off(callback: () => void) {
+    const e = this.event;
+    e.off(callback);
+    const n = e.listenerCount();
     if (n === 0) {
       this.active = false;
       if (isRunning()) this.sigoff();
@@ -622,7 +609,6 @@ class SignalHandler {
   /* Bound to this */
   sigon() {
     if (this.active && !this.listen) {
-      Dome.emit(ACTIVITY + this.id, true);
       this.listen = true;
       queueCmd.push('SIGON', this.id);
       _flush();
@@ -632,7 +618,6 @@ class SignalHandler {
   /* Bound to this, Debounced */
   sigoff() {
     if (!this.active && this.listen) {
-      Dome.emit(ACTIVITY + this.id, false);
       if (isRunning()) {
         this.listen = false;
         queueCmd.push('SIGOFF', this.id);
@@ -699,13 +684,13 @@ export function useSignal(s: Signal, callback: any) {
 
 // --- Server Synchro
 
-Dome.on(READY, () => {
+READY.on(() => {
   signals.forEach((h: SignalHandler) => {
     h.sigon();
   });
 });
 
-Dome.on(SHUTDOWN, () => {
+SHUTDOWN.on(() => {
   signals.forEach((h: SignalHandler) => {
     h.unplug();
     (h.sigoff as unknown as _.Cancelable).cancel();
@@ -854,7 +839,7 @@ async function _send() {
       // No pending command nor pending response
       rqCount = 0;
     }
-    Dome.emit(STATUS);
+    STATUS.emit(status);
   }
 }
 
@@ -891,7 +876,7 @@ function _receive(resp: any) {
           break;
         case 'SIGNAL':
           rid = shift();
-          Dome.emit(SIGNAL + rid);
+          (new SIGNAL(rid)).emit();
           break;
         case 'WRONG':
           err = shift();
diff --git a/ivette/src/frama-c/states.ts b/ivette/src/frama-c/states.ts
index edad69f58074965555c2f6984d374ebefb3eb722..b37f0fd7d97e0aab0d47bb80d029adcac818b50e 100644
--- a/ivette/src/frama-c/states.ts
+++ b/ivette/src/frama-c/states.ts
@@ -18,8 +18,12 @@ import { useModel } from 'dome/table/models';
 import { CompactModel } from 'dome/table/arrays';
 import * as Server from './server';
 
-const PROJECT = 'frama-c.project';
-const STATE_PREFIX = 'frama-c.state.';
+const PROJECT = new Dome.Event('frama-c.project');
+class STATE extends Dome.Event {
+  constructor(id: string) {
+    super(`frama-c.state.${id}`);
+  }
+}
 
 // --------------------------------------------------------------------------
 // --- Pretty Printing (Browser Console)
@@ -43,7 +47,7 @@ Server.onReady(async () => {
     };
     const current: { id?: string } = await Server.send(sr, null);
     currentProject = current.id;
-    Dome.emit(PROJECT);
+    PROJECT.emit();
   } catch (error) {
     D.error(`Fail to retrieve the current project. ${error.toString()}`);
   }
@@ -51,7 +55,7 @@ Server.onReady(async () => {
 
 Server.onShutdown(() => {
   currentProject = '';
-  Dome.emit(PROJECT);
+  PROJECT.emit();
 });
 
 // --------------------------------------------------------------------------
@@ -83,7 +87,7 @@ export async function setProject(project: string) {
       };
       await Server.send(sr, project);
       currentProject = project;
-      Dome.emit(PROJECT);
+      PROJECT.emit();
     } catch (error) {
       D.error(`Fail to set the current project. ${error.toString()}`);
     }
@@ -219,20 +223,20 @@ interface Handler<A> {
 
 // shared for all projects
 class SyncState<A> {
-  UPDATE: string;
+  UPDATE: Dome.Event;
   handler: Handler<A>;
   upToDate: boolean;
   value?: A;
 
   constructor(h: Handler<A>) {
     this.handler = h;
-    this.UPDATE = STATE_PREFIX + h.name;
+    this.UPDATE = new STATE(h.name);
     this.upToDate = false;
     this.value = undefined;
     this.update = this.update.bind(this);
     this.getValue = this.getValue.bind(this);
     this.setValue = this.setValue.bind(this);
-    Dome.on(PROJECT, this.update);
+    PROJECT.on(this.update);
   }
 
   getValue() {
@@ -248,7 +252,7 @@ class SyncState<A> {
       this.value = v;
       const setter = this.handler.getter;
       if (setter) await Server.send(setter, v);
-      Dome.emit(this.UPDATE);
+      this.UPDATE.emit();
     } catch (error) {
       D.error(
         `Fail to set value of syncState '${this.handler.name}'.`,
@@ -262,7 +266,7 @@ class SyncState<A> {
       this.upToDate = true;
       const v = await Server.send(this.handler.getter, null);
       this.value = v;
-      Dome.emit(this.UPDATE);
+      this.UPDATE.emit();
     } catch (error) {
       D.error(
         `Fail to update syncState '${this.handler.name}'.`,
diff --git a/ivette/src/renderer/Controller.tsx b/ivette/src/renderer/Controller.tsx
index 6ad7fc3b0222fcecb61b8cd6118d489a57ba1aad..853f8b06ccd78a2ffc1298cd05564707868228cb 100644
--- a/ivette/src/renderer/Controller.tsx
+++ b/ivette/src/renderer/Controller.tsx
@@ -98,7 +98,7 @@ function insertConfig(hs: string[], cfg: Server.Configuration) {
 
 let reloadCommand: string | undefined;
 
-Dome.onReload(() => {
+Dome.reload.on(() => {
   const [lastCmd] = Settings.getWindowSettings(
     'Controller.history', Json.jList(Json.jString), [],
   );
@@ -179,10 +179,14 @@ const RenderConsole = () => {
     'Controller.history', Json.jList(Json.jString), [],
   );
 
-  Dome.useEmitter(editor, 'change', () => {
-    const cmd = editor.getValue().trim();
-    setEmpty(cmd === '');
-    setNoTrash(cursor === 0 && history.length === 1 && cmd === history[0]);
+  React.useEffect(() => {
+    const callback = () => {
+      const cmd = editor.getValue().trim();
+      setEmpty(cmd === '');
+      setNoTrash(noTrash && cmd === history[0]);
+    };
+    editor.on('change', callback);
+    return () => { editor.off('change', callback); };
   });
 
   const doReload = () => {