/* This file is part of the KDE libraries
Copyright (C) 1997 Matthias Ettrich (ettrich@kde.org)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/*
* Kwm.h. Part of the KDE project.
*/
#ifndef KWM_H
#define KWM_H
#include <qstring.h>
#include <qapplication.h>
#include <qpixmap.h>
#include <X11/Xlib.h>
#ifdef raise
#undef raise
#endif
/**
* The class KWM allows usual X11 clients to get or modify window
* properties and to interact with the windowmanager. It also offers
* some high level functions to support the easy implementation of
* session managment.
* @short class for interaction with the window- and sessionmanager
* @author Matthias Ettrich (ettrich@kde.org)
*/
class KWM {
public:
/**
* Return all window properties needed to restore a window in
* a string. The string can be used as a command line argument
* for the session management (See setWmCommand below). */
static QString getProperties(Window w);
/**
* Apply properties from a property string to a window. This will
* have an immediate effect if the window is already managed by the
* window manager (that means it is either in Normal- or in
* IconicState). If the window is still WithDrawn, the windowmanager
* will apply the properties when the window is mapped (This happens
* for example with a QWidget::show() ). If setProperties is used
* for session management, you should call it first and map the
* window later, since this avoids unnecessary flickering.
*
* setProperties returns the geometry of the property string.
*
* Note: Some window managers may not understand all kwm properties,
* but all common properties such as geometry or IconicState should
* nevertheless work anyway.
*/
static QRect setProperties(Window w, const QString &props);
/**
* This will tell the windowmanager that your client is able to do
* session management. If you do this, your client MUST react on
* WM_SAVE_YOURSELF client messages by setting the XA_WM_COMMAND
* property. This can be easily done with a call to setWmCommand
* (see below). If your application has several top level windows
* which are not transient, you can enable session management only
* for the main toplevel window, but call setWmCommand for the
* others with an empty (not null) string as argument. You
* should/can do that already when you create these windows. It will
* prevent the session manager from believing that this window does
* not support session management at all. Whenever you react on
* WM_SAVE_YOURSELF, you will have to call setWmCommand. Passing an
* empty (not null) string is legal: The session manager will
* understand this as an indicator that everything is ok and that
* your application window may be restored by somebody else ;-)
*
* Note: If you enable session management although your client does
* not react correctly on WM_SAVE_YOURSELF client messages, the
* window manager cannot perform the logout process, that means
* the GUI will hang!
*
* Note 2: Session management needs a session manager. In KDE this is
* also done by the windowmanager kwm. Other windowmangers might not
* support this, so you may have to run a standalone session manager
* instead. Anyway, enabling session management does not harm in the
* case a user does not run a session manager. He/she simply will
* not have session management, but all other functionality.
*
* Note 3: PSEUDO SESSION MANAGEMENT
* There is also another way to do pseudo session management:
* 1) do NOT enable session management
* 2) call setWmCommand (see below) anyway and set the command
* which was used to start your application.
*
* This is exactly what old X11 applications like xterm, xedit or xv
* do. BTW setWmCommand will also set the WM_CLIENT_MACHINE
* property, which allows the session manager to restart the
* application on the correct machine.
*
* kwm will act similar to smproxy: the window properties will be
* stored and applied again when the window will be mapped after the
* restart. To avoid unnecessary flickering or jumping of windows it
* is important to call setWmCommand BEFORE your window is mapped!
*
* Anyway your application will appear in a warning box in kwm,
* which indicates that the user might have some data loss. If you
* do not want that (because your application does not contain any
* data to be lost, for example a clock), you may simply call
* setUnsavedDataHint with FALSE as value. Note that this hint is
* read only when the user logs out, so the last value will be
* used. You can also set it to TRUE to indicate that the user will
* certainly have some data loss. All these things may of course
* have no effect with other window- or session managers.
*
* Note 4: kwm also supports session management for toplevel windows
* that are not mapped (and never have been mapped). This is very
* usefull for programms with n windows, where n can be 0 (like kfm,
* for example), which want to recieve a WM_SAVE_YOURSELF message
* nevertheless. The same as usual: If you do not want the session
* manager to restart your application, since it is already started
* by the usual startup script (True for kfm), set the command to an
* empty string (setWmCommand(<your window>, "");)
*/
static void enableSessionManagement(Window w);
/**
* Store a shell command that can be used to restore the client.
* This should be done as reaction on a WM_SAVE_YOURSELF client
* message. setWmCommand also sets the WM_CLIENT_MACHINE property to
* allow a session management to restart your application even on
* the correct machine.
*/
static void setWmCommand(Window w, const QString &command);
/* Clients who react on WM_SAVE_YOURSELF should be able to save
* their entire state. If not (version under developent, lazy
* author, etc...) they should at least save their geometry
* informations and call setUnsavedDataHint. This will indicate to
* the session manager that the user might lose some data if he/she
* continues with the logout process.
*
* The hint can be set or unset either in the response to
* WM_SAVE_YOURSELF or anytime during runtime. Please make sure that
* the hint is also reset after the user saved the data!
*
* Note: The hint has also effect for clients that are not session management
* enabled or do not even do pseudo session management
*
* Note 2: May have no effect with other window- or session managers
*/
static void setUnsavedDataHint(Window w, bool value);
/**
* Set a mini icon for your application window. This icon may appear
* in the window decoration as well as on taskbar buttons. Therefore
* it should be very small (kwm for example will scale it to 14x14,
* so 14x14 may be the size of choice).
*
* setMiniIcon will _not_ change the icon_pixmap property of the
* standard XWMHints, but define a special KWM_WIN_ICON
* property. This has the advantage, that your application can
* support standard X11 icons (which are usually _very_ large) if it
* runs with mwm for example, as well as modern KDE-like miniicons.
*
* Note: kwm will even detect changes of this property when your
* window is mapped.
*
* Note 2: May have no effect with other windowmanagers */
static void setMiniIcon(Window w, const QPixmap &pm);
/**
* Set a standard (large) icon for the application window. If you
* are using Qt this should be almost aequivalent to a call to
* QWidget::setIcon(..)
*/
static void setIcon(Window w, const QPixmap &pm);
/**
* This declares a toplevel window to be a docking window. If a KWMDockModule
* is running (for example kpanel), it will swallow the window on
* its docking area when it is mapped.
*
* For docking call setDockWindow() on a new _unmapped_ toplevel
* window. If this window will be mapped (show), it will appear on
* the docking area, if you unmap it again (hide) it will disappear
* from the docking area again. Docking windows MUST be toplevel
* windows. If you create them with Qt (new QWidget()->winId()) be
* sure not to pass any parent.
*
* Note: May have no effect with other window mangers
*/
static void setDockWindow(Window w);
/**
*Some windows do not want to be decorated at all but should not be
* override_redirect (for example toolbars which are dragged out of
* their main window). This can be achieved with a simple call to
* setDecoration() even if the window is already mapped.
*
* KWM understands the following values at present:
* noDecoration : Not decorated at all
* normalDecoration : Normal decoration (transient windows with
* dialog decoration, shaped windows not decorated
* at all)
*
* tinyDecoration : Tiny decoration (just a little frame)
*
* If your window does not want the focus, you can OR the decoration
* property with noFocus, for example kpager:
* KWM::setDecoration(winId(), KWM::tinyDecoration | KWM::noFocus);
*
* Last not least, you can tell the window manager to keep the window
* always on top of other windows by combing a decoration with the
* KWM::staysOnTop flag, for example
* KWM::setDecoration(winId(), KWM::normalDecoration | KWM::staysOnTop);
*
* Note: X11R6 does not offer a standard property or protocoll for
* this purpose. So kwm uses a KDE specific property which may have
* no effect with other window managers.
*/
static void setDecoration(Window w, long value);
enum {noDecoration = 0, normalDecoration = 1, tinyDecoration = 2,
noFocus = 256, standaloneMenuBar = 512, desktopIcon = 1024 , staysOnTop = 2048};
/**
* Invokes the logout process (session management, logout dialog, ...)
*
* Note: May have no effect with other window mangers
*/
static void logout();
/**
* Clients who draw over other windows should call refreshScreen()
* afterwards to force an ExposureEvent on all visible windows.
* Also necessary after darkenScreen();
*
* Note: May have no effect with other window mangers
*/
static void refreshScreen();
/**
* Draw a black matrix over the entire screen to make it look darker.
* Clients who use this should grab the X server afterwards and also
* call refreshScreen() after releasing the X server.
*
* Note: May have no effect with other window mangers
*/
static void darkenScreen();
/**
* Clients who manipulated the config file of the windowmanager
* should call this afterwards
*
* Note: May have no effect with other window mangers
*/
static void configureWm();
/**
* The current virtual desktop. This is usefull if your program behaves
* different on different desktops (for example a background drawing
* program) but does not itself need to be a window manager module
* (which recieve a message when the current desktop changes)
*/
static int currentDesktop();
/**
* Raise/register/unregister sound events. The number of character in
* the event name is limited to 20.
*
Note: May have no effect with other window mangers
*/
static void raiseSoundEvent(const QString &event);
static void registerSoundEvent(const QString &event);
static void unregisterSoundEvent(const QString &event);
/**
*************************************************************************
*
* Functions below are probably only important for window manager modules
*
* DO NOT USE THEM WITH REGULAR CLIENTS
*
*************************************************************************
*/
/**
* Declare a toplevel window to be used for module
* communication. This window does not need to be mapped, although
* it can be mapped of course. Module windows MUST be toplevel
* windows. If you create them with Qt (new QWidget()->winId()) be
* sure not to pass any parent. Modules get the following client
* messages from kwm. Argument is either a window ((Window)
* XClientMessageEvent.data.l[0]), a (long) number or nothing.
*
* KWM_MODULE_INIT - initialization starts
* KWM_MODULE_INITIALIZED - initialization is complete
* KWM_MODULE_DESKTOP_CHANGE - new current virtual desktop
* KWM_MODULE_DESKTOP_NAME_CHANGE - a desktop got a new name
* KWM_MODULE_DESKTOP_NUMBER_CHANGE - the number of desktop changed
* KWM_MODULE_WIN_ADD - new window
* KWM_MODULE_DIALOG_WIN_ADD - new dialog window. The signal comes _before_
* the WIN_ADD signal to allow clients to exclude dialog windows.
* KWM_MODULE_WIN_REMOVE - remove window
* KWM_MODULE_WIN_CHANGE - size, properties, map state etc.
* KWM_MODULE_WIN_RAISE - raise and lower allow a module (for example
* KWM_MODULE_WIN_LOWER a pager) to keep the stacking order
* KWM_MODULE_WIN_ACTIVATE - new active (focus) window
* KWM_MODULE_WIN_ICON_CHANGE - window got a (new) icon
*
* KDE_SOUND_EVENT - a sound event
* KDE_REGISTER_SOUND_EVENT - registration of a new sound event
* KDE_UNREGISTER_SOUND_EVENT - remove a registration
*
* Please check out the KWMModuleApplication class which gives you easy
* access to all these messages via Qt signals and slots. It also keeps
* automatically a list of windows in both stacking and creation order.
*
*/
static void setKWMModule(Window w);
/**
* Is the window a kwm module?
*/
static bool isKWMModule(Window w);
/**
* Note that there can only be one single KWMDockModule at the same
* time. The first one to come wins. The later can check the result
* with isKWMDockModule.
*
* The KWMDockModule recieves two additional client messages:
* KWM_MODULE_DOCKWIN_ADD
* KWM_MODULE_DOCKWIN_REMOVE
*/
static void setKWMDockModule(Window w);
/**
* Is the window a kwm dock module?
*/
static bool isKWMDockModule(Window w);
/**
* This is usefull for modules which depend on a running
* windowmanager for the correct settings of the number of desktops
* or the desktop names (for example kpanel).
* Just insert
* while (!KWM::isKWMInitialized()) sleep(1);
* in the main function of your application to wait for kwm being
* ready. As an alternative you can also wait for the init-signal
* of KWMModuleApplication.
*/
static bool isKWMInitialized();
/**
* Returns the window which has the focus
*/
static Window activeWindow();
/**
* Switches to the specified virtual desktop
*/
static void switchToDesktop(int desk);
/**
*Window region define the rectangle where windows can appear. A
* window which can be fully maximized will exactly fill this
* region. The regions are settable withing kwm to allow desktop
* panels like kpanel to stay visible even if a window becomes maximized.
* kwm will store the regions in the kwmrc when exiting.
*/
static void setWindowRegion(int desk, const QRect ®ion);
/**
* Returns the window region of the specified virtual desktop.
*/
static QRect getWindowRegion(int desk);
/**
* At present the maximium number of desktops is limited to 32
*
* As with the window regions, kwm will store the following properties in
* the kwmrc when exiting
*/
/**
* Returns the number of virtual desktops.
*/
static int numberOfDesktops();
/**
* Sets the number of virtual desktops. Modules like kpanel are informed.
*/
static void setNumberOfDesktops(int num);
/**
* Changes a name of a virtual desktop. Modules like kpanel are informed.
*/
static void setDesktopName(int desk, const QString &name);
/**
* Returns the name of the specified virtual desktop.
*/
static QString getDesktopName(int desk);
/**
* low level kwm communication. This can also be used for a one-way
* communication with modules, since kwm sends messages, which it
* does not understand, to all modules. You module should declare a
* short unque praefix for this task.
*
* Note: the length of a command is limited to 20 character. This
* stems from the limitations of an ordinary X11 client messages.
*/
static void sendKWMCommand(const QString &command);
/**
* The standard window title. If kwm runs, title() will return the
* title kwm uses. These titles are always unique.
*/
static QString title(Window w);
/**
*titleWithState is aequivalent to title(), but inside round brackets
* for iconified window
*/
static QString titleWithState(Window w);
/**
* if no miniicon is set, miniIcon() will return the standard
* icon. The result will be scaled to (width, height) if it is
* larger. Otherwise it will not be modified. If you do not specify
* width or height, the result will be returned in its native
* size. Returns a null pixmap in the case no
* icon is defined.
*/
static QPixmap miniIcon(Window w, int width=0, int height=0);
/**
* Same as miniIcon() above, but for the full icon.
*/
static QPixmap icon(Window w, int width=0, int height=0);
/**
***** GET WINDOW PROPERTIES *****
*/
/**
* Returns the virtual desktop on which the window is located.
*/
static int desktop(Window w);
/**
* Returns the geometry of a window. If including_frame is set,
* then the geometry of kwm's decoration frame is returned. This
* functions tries to work even for non-KDE-compliant window
* managers. Anyway, since this is a bit weird in X the result
* cannot be guaranteed to be correct then.
*/
static QRect geometry(Window w, bool including_frame = FALSE);
/**
* geometry restore is only defined for maximized window. It is the
* geometry a window will get when it is unmaximized.
*/
static QRect geometryRestore(Window w);
/**
* Returns the icon geometry of a window. This is either the defined icon
* geometry from a setIconGeometry() call, or the center of the window in case
* there was no geometry or an empty geometry defined.
*/
static QRect iconGeometry(Window w);
/**
* Is the window iconified?
*/
static bool isIconified(Window w);
/**
* Is the window maximized?
*/
static bool isMaximized(Window w);
/**
* Shall the window be maximized?
*/
static bool isDoMaximize(Window w);
enum {horizontal = 1, vertical = 2, fullscreen = 3};
/**
* The maximize mode, either horizontal, vertical or fullscreen
*/
static int maximizeMode(Window w);
/**
* The doMaximize mode, either horizontal, vertical or fullscreen
*/
static int doMaximizeMode(Window w);
/**
* Is the window sticky?
*/
static bool isSticky(Window w);
/**
* Returns the KDE decoration hints of the window.
*/
static long getDecoration(Window w);
/**
* Is the window sticky?
*/
static bool fixedSize(Window w);
/**
* Does the window contain unsaved data? (KDE hint)
*/
static bool containsUnsavedData(Window w);
/**
* Does the window define the KDE unsaved data hint at all?
*/
static bool unsavedDataHintDefined(Window w);
/**
* Does the window have the focus?
*/
static bool isActive(Window w);
/**
* ***** SET WINDOW PROPERTIES *****
*
* Note: The functions for some general properties (decoration,
* icons) are in the general section at the beginning of this
* document.
*/
/**
* Move the window to another virutal desktop
*/
static void moveToDesktop(Window w, int desk);
/**
* Set the geometry of a window
*/
static void setGeometry(Window w, const QRect &geom);
/**
* Set the restore geometry (before maximize) of a window
*/
static void setGeometryRestore(Window w, const QRect &geom);
/**
* Set the icon geometry of a window.
*/
static void setIconGeometry(Window w, const QRect &geom);
/**
* Move a window to another geometric position
*/
static void move(Window w, const QPoint &pos);
/**
* Maximize/Unmaximize a window according to value. If the window
* is not mapped yet, this function only sets the _state_ of the
* maximize button, it does _not_ change the geometry. See
* doMaximize below.
*
* The mode can either be horizontal or vertical or ( the default) fullscreen
*/
static void setMaximize(Window w, bool value, int mode );
/**
* for binary compatibility, the above with default argument mode = horitzonal|vertical
*/
static void setMaximize(Window w, bool value);
/**
Maximize a window (changing the geometry to fill the entire screen).
*/
static void doMaximize(Window w, bool value, int mode);
/**
* for binary compatibility, the above with default argument mode = horitzonal|vertical
*/
static void doMaximize(Window w, bool value);
/**
* Iconify/UnIconify a window according to value
*/
static void setIconify(Window w, bool value);
/**
* Sticky/UnSticky a window according to value
*/
static void setSticky(Window w, bool value);
/**
* close will send a WM_DELETE_WINDOW message to the window, if this window
* requested for this protocol. Otherwise it will simply be destroyed.
*/
static void close(Window w);
/**
*activate will deiconify the window, if is is iconified, or switch to
* another desktop, if the window is there. Then the window is raised
* and activated with activateInteral (see below)
*/
static void activate(Window w);
/**
* activateInternal will simply activate the window. Be carefull: you might
* run into trouble if the window is iconified or on another desktop!
* You probably prefer activate (see above).
*/
static void activateInternal(Window w);
/**
* raise the specified window. Should work with any windowmanager
*/
static void raise(Window w);
/**
* lower the specified window. Should work with any windowmanager
*/
static void lower(Window w);
/**
* if you like to swallow a mapped window ( == XReparentWindow)
* you should call prepareForSwallowing before. This will set the
* window to WithDrawnState (and also wait until the window achieved
* this state), what usually let the windowmanager remove all its
* decorations and re-reparent the window to the root window.
*
* You do not need to call prepareForSwallowing if you are sure that
* the window is already in withdrawn state and unmanaged
* (i.e. still a child of the root window). This is usually the case
* if the window was never shown, but not always. Some
* windowmanagers may even manage newly created unmapped windows,
* although this is not a good idea to do. If the window is not in
* withdrawn state but managed by the windowmanager, then the
* windowmanager may react on the synthetic unmapNotify event
* created from XReparentWindow by reparenting the window back to
* the root window. Since this happen after your XReparentWindow,
* you did not swallow it but put it onto the desktop without any
* decoration frame instead! prepareForSwallowing helps to avoid
* this case.
*
* Note: You _never_ need to call prepareForSwallowing if you are
* using kwm, since kwm is very clever regarding unmapNotify
* events. If you like to ensure that your software works with other
* windowmanager though, you should better do it. Please keep in
* mind that taking windows away from windowmanagers is a sensitive
* topic. That means: Even prepareForSwallowing may fail with
* certain non-standard windowmanagers.
*
* Also note that all this stuff only affects toplevel
* windows. Reparenting subwindows is no problem at all, since a
* windowmanager does not care about them. */
static void prepareForSwallowing(Window w);
/**
* doNotManage(...) allows to define the first 20 character of a
window title (or a regular expression) that should not be
managed by the windowmanager. This is useful
* to avoid flickering when a panel swallows legacy applications.
* doNotManage(...) applies only for the first window which meets the
* criteria.
*
* Note: May have no effect with other windowmanagers.
*/
static void doNotManage(const QString&);
/**
* ***** CURRENT NAMES OF WINDOW OPERATION COMMANDS *****
*
* For 100% consitancy of the desktop, clients which do window operations
* should use these strings.
*/
/**
* An i18n'ed string for maximize.
*/
static QString getMaximizeString();
/**
* An i18n'ed string for unmaximize
*/
static QString getUnMaximizeString();
/**
* An i18n'ed string for iconify
*/
static QString getIconifyString();
/**
* An i18n'ed string for uniconify
*/
static QString getUnIconifyString();
/**
* An i18n'ed string for sticky
*/
static QString getStickyString();
/**
* An i18n'ed string for unsticky.
*/
static QString getUnStickyString();
/**
* An i18n'ed string for move.
*/
static QString getMoveString();
/**
* An i18n'ed string for resize.
*/
static QString getResizeString();
/**
* An i18n'ed string for close.
*/
static QString getCloseString();
/**
* An i18n'ed string for "toDesktop".
*/
static QString getToDesktopString();
/**
* An i18n'ed string for "ontoCurrentDesktop".
*/
static QString getOntoCurrentDesktopString();
/**
* ***** MORE OR LESS ONLY USEFULL FOR INTERNAL PURPOSES OR THE
* WINDOWMANAGER ITSELF *****
*/
/**
* Is the window a docking window?
*/
static bool isDockWindow(Window w);
/**
* Returns the X window state of the specified winodw
*/
static int getWindowState(Window w);
};
#endif // KWM_H
Documentation generated by tasin@cd1 on Die Nov 30 17:31:35 CET 1999