This is a serious problem, because in order to achieve operating-system standard behaviour, I have to duplicate the same solution in every window that I write. Given that other GUI frameworks (e.g., Delphi VCL and .NET WinForms) do this automatically for me, it makes EiffelVision look weak. The solution that I'm using is as follows: feature {NONE} -- Initialization user_initialization is do add_shortcut (agent step_focused_notebook_tab (1), {EV_KEY_CONSTANTS}.key_tab, True, False) add_shortcut (agent step_focused_notebook_tab (-1), {EV_KEY_CONSTANTS}.key_tab, True, True) end add_shortcut (action: PROCEDURE [ANY, TUPLE]; key: INTEGER; ctrl, shift: BOOLEAN) -- Create a keyboard shortcut to execute `action'. require action_attached: action /= Void valid_key: (create {EV_KEY_CONSTANTS}).valid_key_code (key) local accelerator: EV_ACCELERATOR do create accelerator.make_with_key_combination (create {EV_KEY}.make_with_code (key), ctrl, False, shift) accelerator.actions.extend (action) accelerators.extend (accelerator) ensure accelerators_extended: accelerators.count = 1 + old accelerators.count end feature {NONE} -- Standard Windows behaviour that EiffelVision ought to be managing automatically step_focused_notebook_tab (step: INTEGER) -- Switch forward or back from the current tab page of the currently focused notebook. require valid_step: step.abs <= 1 local notebook: EV_NOTEBOOK widget: EV_WIDGET do notebook := notebook_containing_focused_widget if notebook /= Void then widget := notebook [1 + (step + notebook.selected_item_index - 1 + notebook.count) \\ notebook.count] notebook.select_item (widget) focus_first_widget (widget) end end notebook_containing_focused_widget: EV_NOTEBOOK -- The notebook, if any, containing the currently focused widget. local focused: EV_WIDGET container: EV_CONTAINER do focused := focused_widget if focused /= Void then from container := focused.parent until container = Void or Result /= Void loop Result ?= container container := container.parent end end end focus_first_widget (widget: EV_WIDGET) -- Set focus to `widget' or to its first child widget that accepts focus. require widget_attached: widget /= Void local container: EV_CONTAINER grid: EV_GRID label: EV_LABEL widgets: LINEAR [EV_WIDGET] do container ?= widget grid ?= widget if container /= Void and grid = Void then from widgets := container.linear_representation widgets.start until widgets.off or container.has_recursive (focused_widget) loop focus_first_widget (widgets.item) widgets.forth end elseif widget.is_displayed and widget.is_sensitive then label ?= widget if label = Void then widget.set_focus end end end focused_widget: EV_WIDGET -- The currently focused widget, if any. local window_imp: EV_WINDOW_IMP widget_imp: EV_ANY_I do window_imp ?= implementation if window_imp /= Void and then window_imp.focus_on_widget /= Void then widget_imp := window_imp.focus_on_widget.item if widget_imp /= Void then Result ?= widget_imp.interface end end ensure focused: Result /= Void implies Result.has_focus end