SUMMARY: Original plan for split-screen design in Konsole AUTHOR: Robert Knight < robertknight@gmail.com > UPDATED: Tuesday 26/12/06 Konsole Split-View Design Plan ============================== The ability to split the view, so that more than one session can be viewed at once is Konsole's most requested feature. This document discusses the proposed design which aims to clean up the code in the main Konsole class, make handling of settings from all sorts of sources easier and ultimately allow for a clean implementation of split view in Konsole. UI Design ========= The UI involves two menu items and a splitter widget. When Konsole starts up, it will look the same as it does in KDE 3.x To split the view, the user selects the new 'View -> Split Horizontally' menu option. To the user, Konsole then appears to duplicate the existing display area (tabs + display widgets) and put one in the top half of the Konsole window, and one in the bottom half. A standard splitter appears between the two which the user can drag with the mouse (or possibly move using a keyboard shortcut) to alter the relative size of each display area. To close one of the views, the user selects the new 'View -> Close Active View' menu option. The display area which currently has the focus is then removed. If a user creates a new session whilst there are multiple views, a new tab will be added to each view in the same window. Each view can be scrolled independantly, that is, it should be possible to display the most recent output from a session in one view area at the bottom of the Konsole window. and older output from that same session in another view area at the top of the Konsole window. A view can be detached from the window so that it appears in a new window by right-clicking on the tab and selecting 'Detach Session'. In this case the session disappears from the view containing that tab and reappears in a new Konsole window which contains just that session. Other views in the 'old' window are not affected (ie. the session tab will still be visible in them). In this way it is possible to display the same session in different windows. Cleaner Session Management ========================== As already mentioned in the code, creation and management of new sessions will be moved into a new class, SessionManager. There is one SessionManager per application. The SessionManager provides a method to set default settings for new sessions that are created. These methods will also have a parameter that specifies where the setting came from. When a new session is created, for each setting, SessionManager will pick the one from the most important source. The idea is that the application will behave consistantly and follow the principle of least surprise. eg. if the following code was executed: sessionManager()->addSetting( SessionManager::DefaultFont , SessionManager::CommandLine , fontA ); sessionManager()->addSetting( SessionManager::DefaultFont , SessionManager::SessionConfig , fontB ); sessionManager()->addSetting( SessionManager::DefaultFont , SessionManager::GlobalSettings , fontC ); when session manager came to create a new session, it would use fontA, because that setting came from the source with the highest priority. It is also possible to have single-shot sources of settings which are only considered for the next session which is created and then discarded after that. eg. sessionManager()->addSetting( SessionManager::InitialDir , SessionManager::KonsoleDefault , getenv("HOME") ); sessionManager()->addSetting( SessionManager::SingleShot , path ); If two sessions were created after this, the first would start in directory 'path', and the second would start in the user's home directory. The code which supplies the setting does not have to check whether there is already a setting there and whether that setting came from a more important source or not. The priority given to various sources of settings should be consistant for all settings. If a setting is added with the same source as an existing setting, it over-writes that setting. Connecting Multiple Views to a Running Session ============================================== Konsole for KDE 3.x allows one view to be connected to each session. Extending this proved fairly simple since the display widget and the terminal emulation are nicely decoupled already. One slightly tricky issue is what to do if there are multiple views of the same session which are different sizes and visible at the same time - since the terminal emulation assumes a single screen image and therefore a single size. My current thought is that the size of the smallest visible display would be used in such a case. For simplicity, the same font settings, colour schemes and keyboard setups should be used for all views of the same session. The new API for creating sessions looks like this: TESession* session = sessionManager()->createSession( configPath ); TEWidget* display = new TEWidget(parent); session->addView(display); As with KDE 3.x, the display does not know anything about the emulations to which it is connected and from whom it receives screen image updates. View Splitters and Containers ================================= In the old design there is a single tab widget per Konsole window which holds all of the terminal displays in that window In the new design the main window contains a view splitter (ViewSplitter class) derived from QSplitter. A view splitter widget can contain one or more view containers (ViewContainer interface). View containers are widgets which hold one or more terminal displays and provide some means for the user to navigate between them (such as tabs or a list). View splitter widgets can also hold view splitter children, allowing for a hierarchy of view splitters and containers. --> [ Terminal Display ] --> ViewContainer --> [ Terminal Display ] --> [ Terminal Display ] --> ViewContainer --> [ Terminal Display ] ViewSplitter --> ViewSplitter --> ViewContainer --> [ Terminal Display ] The existing tab widget which is used to navigate between displays in a Konsole window will be replaced with a TabbedViewContainer class. The reason for allowing different types of view container is that tabs have some shortcomings as a way of viewing the active terminal displays and switching between them - it would be useful to have the possibility of introducing a replacement or alternative in the future. Moving the view management out of the main window should cut down lots of code related to handling signals and slots for various UI actions in the main Konsole window. Related Cleanup =============== The API for color schemes and keyboard setups may be changed as part of this. I don't plan to touch the internals yet though. If changes do happen, will be post-KDE 4.x. As a result, color schemes and keytab files from Konsole for KDE 3.x should work (at least to some extent) in KDE 4.0, even though the code in keytab.cpp is responsible for the death of many cute and fluffy creatures.