mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
eed5749909
Also center ede-launch window.
414 lines
13 KiB
C++
414 lines
13 KiB
C++
//
|
|
// Client.hh for pekwm
|
|
// Copyright © 2003-2009 Claes Nästén <me{@}pekdon{.}net>
|
|
//
|
|
// client.hh for aewm++
|
|
// Copyright (C) 2002 Frank Hale <frankhale@yahoo.com>
|
|
// http://sapphire.sourceforge.net/
|
|
//
|
|
// This program is licensed under the GNU GPL.
|
|
// See the LICENSE file for more information.
|
|
//
|
|
|
|
#ifndef _CLIENT_HH_
|
|
#define _CLIENT_HH_
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif // HAVE_CONFIG_H
|
|
|
|
#include "pekwm.hh"
|
|
#include "Observer.hh"
|
|
#include "PTexturePlain.hh"
|
|
#include "PDecor.hh"
|
|
|
|
class PScreen;
|
|
class Strut;
|
|
class PWinObj;
|
|
class ClassHint;
|
|
class AutoProperty;
|
|
class Frame;
|
|
|
|
#include <string>
|
|
|
|
extern "C" {
|
|
#include <X11/Xutil.h>
|
|
}
|
|
|
|
class LayerObservation : public Observation {
|
|
public:
|
|
LayerObservation(enum Layer _layer) : layer(_layer) { };
|
|
virtual ~LayerObservation(void) { };
|
|
public:
|
|
const enum Layer layer; /**< Layer client changed to. */
|
|
};
|
|
|
|
class Client : public PWinObj, public Observer
|
|
{
|
|
// FIXME: This relationship should end as soon as possible, but I need to
|
|
// figure out a good way of sharing. :)
|
|
friend class Frame;
|
|
|
|
public: // Public Member Functions
|
|
struct MwmHints {
|
|
ulong flags;
|
|
ulong functions;
|
|
ulong decorations;
|
|
};
|
|
enum {
|
|
MWM_HINTS_FUNCTIONS = (1L << 0),
|
|
MWM_HINTS_DECORATIONS = (1L << 1),
|
|
MWM_HINTS_NUM = 3
|
|
};
|
|
enum {
|
|
MWM_FUNC_ALL = (1L << 0),
|
|
MWM_FUNC_RESIZE = (1L << 1),
|
|
MWM_FUNC_MOVE = (1L << 2),
|
|
MWM_FUNC_ICONIFY = (1L << 3),
|
|
MWM_FUNC_MAXIMIZE = (1L << 4),
|
|
MWM_FUNC_CLOSE = (1L << 5)
|
|
};
|
|
enum {
|
|
MWM_DECOR_ALL = (1L << 0),
|
|
MWM_DECOR_BORDER = (1L << 1),
|
|
MWM_DECOR_HANDLE = (1L << 2),
|
|
MWM_DECOR_TITLE = (1L << 3),
|
|
MWM_DECOR_MENU = (1L << 4),
|
|
MWM_DECOR_ICONIFY = (1L << 5),
|
|
MWM_DECOR_MAXIMIZE = (1L << 6)
|
|
};
|
|
|
|
Client(Window new_client, bool is_new = false);
|
|
virtual ~Client(void);
|
|
|
|
// START - PWinObj interface.
|
|
virtual void mapWindow(void);
|
|
virtual void unmapWindow(void);
|
|
virtual void iconify(void);
|
|
virtual void stick(void);
|
|
|
|
virtual void move(int x, int y);
|
|
virtual void resize(uint width, uint height);
|
|
virtual void moveResize(int x, int y, uint width, uint height);
|
|
|
|
virtual void setWorkspace(uint workspace);
|
|
|
|
virtual void giveInputFocus(void);
|
|
virtual void reparent(PWinObj *parent, int x, int y);
|
|
|
|
virtual ActionEvent *handleButtonPress(XButtonEvent *ev) {
|
|
if (_parent) { return _parent->handleButtonPress(ev); }
|
|
return 0;
|
|
}
|
|
virtual ActionEvent *handleButtonRelease(XButtonEvent *ev) {
|
|
if (_parent) { return _parent->handleButtonRelease(ev); }
|
|
return 0;
|
|
}
|
|
|
|
virtual ActionEvent *handleMapRequest(XMapRequestEvent *ev);
|
|
virtual ActionEvent *handleUnmapEvent(XUnmapEvent *ev);
|
|
// END - PWinObj interface.
|
|
|
|
// START - Observer interface.
|
|
virtual void notify(Observable *observable, Observation *observation);
|
|
// END - Observer interface.
|
|
|
|
static Client *findClient(Window win);
|
|
static Client *findClientFromWindow(Window win);
|
|
static Client *findClientFromHint(const ClassHint *class_hint);
|
|
static Client *findClientFromID(uint id);
|
|
static void findFamilyFromWindow(std::list<Client*> &client_list, Window win);
|
|
|
|
static void mapOrUnmapTransients(Window win, bool hide);
|
|
|
|
// START - Iterators
|
|
static uint client_size(void) { return _client_list.size(); }
|
|
static std::list<Client*>::iterator client_begin(void) {
|
|
return _client_list.begin();
|
|
}
|
|
static std::list<Client*>::iterator client_end(void) {
|
|
return _client_list.end();
|
|
}
|
|
static std::list<Client*>::reverse_iterator client_rbegin(void) {
|
|
return _client_list.rbegin();
|
|
}
|
|
static std::list<Client*>::reverse_iterator client_rend(void) {
|
|
return _client_list.rend();
|
|
}
|
|
|
|
unsigned int transient_size(void) { return _transient_clients.size(); }
|
|
std::list<Client*>::iterator transient_begin(void) {
|
|
return _transient_clients.begin(); }
|
|
std::list<Client*>::iterator transient_end(void) {
|
|
return _transient_clients.end(); }
|
|
// END - Iterators
|
|
|
|
bool validate(void);
|
|
|
|
inline uint getClientID(void) { return _id; }
|
|
/**< Return title item for client name. */
|
|
inline PDecor::TitleItem *getTitle(void) { return &_title; }
|
|
/**< Return title item for client icon name. */
|
|
inline PDecor::TitleItem *getIconName(void) { return &_icon_name; }
|
|
|
|
inline const ClassHint* getClassHint(void) const { return _class_hint; }
|
|
|
|
bool isTransient(void) const { return _transient_window != None; }
|
|
Client *getTransientClient(void) const { return _transient; }
|
|
Window getTransientClientWindow(void) const { return _transient_window; }
|
|
void findAndRaiseIfTransient(void);
|
|
|
|
inline XSizeHints* getXSizeHints(void) const { return _size; }
|
|
|
|
bool isViewable(void);
|
|
bool setPUPosition(void);
|
|
|
|
inline bool hasTitlebar(void) const { return (_state.decor&DECOR_TITLEBAR); }
|
|
inline bool hasBorder(void) const { return (_state.decor&DECOR_BORDER); }
|
|
inline bool isShaped(void) const { return _shaped; }
|
|
inline bool hasStrut(void) const { return (_strut); }
|
|
Strut *getStrut(void) const { return _strut; }
|
|
|
|
PTexture *getIcon(void) const { return _icon; }
|
|
|
|
/** Return PID of client. */
|
|
long getPid(void) const { return _pid; }
|
|
/** Return true if client is remote. */
|
|
bool isRemote(void) const { return _is_remote; }
|
|
|
|
// State accessors
|
|
inline bool isMaximizedVert(void) const { return _state.maximized_vert; }
|
|
inline bool isMaximizedHorz(void) const { return _state.maximized_horz; }
|
|
inline bool isShaded(void) const { return _state.shaded; }
|
|
inline bool isFullscreen(void) const { return _state.fullscreen; }
|
|
inline bool isPlaced(void) const { return _state.placed; }
|
|
inline uint getInitialFrameOrder(void) const { return _state.initial_frame_order; }
|
|
inline uint getSkip(void) const { return _state.skip; }
|
|
inline bool isSkip(Skip skip) const { return (_state.skip&skip); }
|
|
inline uint getDecorState(void) const { return _state.decor; }
|
|
inline bool isCfgDeny(uint deny) { return (_state.cfg_deny&deny); }
|
|
|
|
inline bool allowMove(void) const { return _actions.move; }
|
|
inline bool allowResize(void) const { return _actions.resize; }
|
|
inline bool allowMinimize(void) const { return _actions.minimize; }
|
|
inline bool allowShade(void) const { return _actions.shade; }
|
|
inline bool allowStick(void) const { return _actions.stick; }
|
|
inline bool allowMaximizeHorz(void) const { return _actions.maximize_horz; }
|
|
inline bool allowMaximizeVert(void) const { return _actions.maximize_vert; }
|
|
inline bool allowFullscreen(void) const { return _actions.fullscreen; }
|
|
inline bool allowChangeDesktop(void) const { return _actions.change_desktop; }
|
|
inline bool allowClose(void) const { return _actions.close; }
|
|
|
|
inline bool isAlive(void) const { return _alive; }
|
|
inline bool isMarked(void) const { return _marked; }
|
|
|
|
// We have this public so that we can reload button actions.
|
|
void grabButtons(void);
|
|
|
|
void setStateCfgDeny(StateAction sa, uint deny);
|
|
inline void setStateMarked(StateAction sa) {
|
|
if (ActionUtil::needToggle(sa, _marked)) {
|
|
_marked = !_marked;
|
|
if (_marked) {
|
|
_title.infoAdd(PDecor::TitleItem::INFO_MARKED);
|
|
} else {
|
|
_title.infoRemove(PDecor::TitleItem::INFO_MARKED);
|
|
}
|
|
_title.updateVisible();
|
|
}
|
|
}
|
|
|
|
// toggles
|
|
void alwaysOnTop(bool top);
|
|
void alwaysBelow(bool bottom);
|
|
|
|
void setSkip(uint skip);
|
|
|
|
inline void setStateSkip(StateAction sa, Skip skip) {
|
|
if ((isSkip(skip) && (sa == STATE_SET)) || (! isSkip(skip) && (sa == STATE_UNSET))) {
|
|
return;
|
|
}
|
|
_state.skip ^= skip;
|
|
}
|
|
|
|
void setStateDemandsAttention(StateAction sa, bool attention);
|
|
|
|
inline void setTitlebar(bool titlebar) {
|
|
if (titlebar) {
|
|
_state.decor |= DECOR_TITLEBAR;
|
|
} else {
|
|
_state.decor &= ~DECOR_TITLEBAR;
|
|
}
|
|
}
|
|
inline void setBorder(bool border) {
|
|
if (border) {
|
|
_state.decor |= DECOR_BORDER;
|
|
} else {
|
|
_state.decor &= ~DECOR_BORDER;
|
|
}
|
|
}
|
|
|
|
/** Set shaped flag on Client. */
|
|
inline void setShaped(bool shaped) {
|
|
_shaped = shaped;
|
|
}
|
|
|
|
void close(void);
|
|
void kill(void);
|
|
|
|
// Event handlers below - Used by WindowManager
|
|
void handleDestroyEvent(XDestroyWindowEvent *ev);
|
|
void handleColormapChange(XColormapEvent *ev);
|
|
|
|
inline bool setConfigureRequestLock(bool lock) {
|
|
bool old_lock = _cfg_request_lock;
|
|
_cfg_request_lock = lock;
|
|
return old_lock;
|
|
}
|
|
|
|
void configureRequestSend(void);
|
|
void sendTakeFocusMessage(void);
|
|
|
|
bool getAspectSize(uint *r_w, uint *r_h, uint w, uint h);
|
|
bool getIncSize(uint *r_w, uint *r_h, uint w, uint h, bool incr=false);
|
|
|
|
bool getEwmhStates(NetWMStates &win_states);
|
|
void updateEwmhStates(void);
|
|
|
|
void getWMNormalHints(void);
|
|
void getWMProtocols(void);
|
|
void getTransientForHint(void);
|
|
void getStrutHint(void);
|
|
void readName(void);
|
|
void readIconName(void);
|
|
void removeStrutHint(void);
|
|
|
|
long getPekwmFrameOrder(void);
|
|
void setPekwmFrameOrder(long num);
|
|
bool getPekwmFrameActive(void);
|
|
void setPekwmFrameActive(bool active);
|
|
|
|
static void setClientEnvironment(Client *client);
|
|
AutoProperty* readAutoprops(uint type = 0);
|
|
|
|
private:
|
|
bool getAndUpdateWindowAttributes(void);
|
|
|
|
void findOrCreateFrame(AutoProperty *autoproperty);
|
|
bool findTaggedFrame(void);
|
|
bool findPreviousFrame(void);
|
|
bool findAutoGroupFrame(AutoProperty *autoproperty);
|
|
|
|
void setInitialState(void);
|
|
void setMappedStateAndFocus(bool is_new, AutoProperty *autoproperty);
|
|
|
|
bool titleApplyRule(std::wstring &wtitle);
|
|
uint titleFindID(std::wstring &wtitle);
|
|
|
|
void setWmState(ulong state);
|
|
long getWmState(void);
|
|
|
|
int sendXMessage(Window window, Atom atom, long mask,
|
|
long v1 = 0l, long v2 = 0l, long v3 = 0l,
|
|
long v4 = 0l, long v5 = 0l);
|
|
|
|
MwmHints* getMwmHints(Window w);
|
|
|
|
// these are used by frame
|
|
inline void setMaximizedVert(bool m) { _state.maximized_vert = m; }
|
|
inline void setMaximizedHorz(bool m) { _state.maximized_horz = m; }
|
|
inline void setShade(bool s) { _state.shaded = s; }
|
|
inline void setFullscreen(bool f) { _state.fullscreen = f; }
|
|
inline void setFocusable(bool f) { _focusable = f; }
|
|
|
|
// Grabs button with Caps,Num and so on
|
|
void grabButton(int button, int mod, int mask, Window win, Cursor curs);
|
|
|
|
void readHints(void);
|
|
ulong readWmHints(void);
|
|
void readClassRoleHints(void);
|
|
void readEwmhHints(void);
|
|
void readMwmHints(void);
|
|
void readPekwmHints(void);
|
|
void readIcon(void);
|
|
void applyAutoprops(AutoProperty *ap);
|
|
void applyActionAccessMask(uint mask, bool value);
|
|
void readClientPid(void);
|
|
void readClientRemote(void);
|
|
|
|
static uint findClientID(void);
|
|
static void returnClientID(uint id);
|
|
|
|
private: // Private Member Variables
|
|
uint _id; //<! Unique ID of the Client.
|
|
|
|
XSizeHints *_size;
|
|
Colormap _cmap;
|
|
|
|
Client *_transient; /**< Client for which this client is transient for */
|
|
Window _transient_window;
|
|
std::list<Client*> _transient_clients; /**< List of transient clients. */
|
|
|
|
Strut *_strut;
|
|
|
|
PDecor::TitleItem _title; /**< Name of the client. */
|
|
PDecor::TitleItem _icon_name; /**< Name of the client when iconified. */
|
|
PTextureImage *_icon;
|
|
|
|
long _pid; /**< _NET_WM_PID of the client, only valid if is_remote is false. */
|
|
bool _is_remote; /**< Boolean flag */
|
|
|
|
ClassHint *_class_hint;
|
|
|
|
bool _alive, _marked;
|
|
bool _send_focus_message, _send_close_message, _wm_hints_input;
|
|
bool _cfg_request_lock;
|
|
bool _shaped;
|
|
bool _extended_net_name;
|
|
|
|
class State {
|
|
public:
|
|
State(void)
|
|
: maximized_vert(false), maximized_horz(false), shaded(false), fullscreen(false),
|
|
placed(false), initial_frame_order(0),
|
|
skip(0), decor(DECOR_TITLEBAR|DECOR_BORDER),
|
|
cfg_deny(CFG_DENY_NO), demands_attention(true) { }
|
|
~State(void) { }
|
|
|
|
bool maximized_vert, maximized_horz;
|
|
bool shaded;
|
|
bool fullscreen;
|
|
|
|
// pekwm states
|
|
bool placed;
|
|
uint initial_frame_order; /**< Initial frame position */
|
|
uint skip, decor, cfg_deny;
|
|
bool demands_attention; /**< If true, the client requires attention from the user. */
|
|
} _state;
|
|
|
|
class Actions {
|
|
public:
|
|
Actions(void) : move(true), resize(true), minimize(true),
|
|
shade(true), stick(true), maximize_horz(true),
|
|
maximize_vert(true), fullscreen(true),
|
|
change_desktop(true), close(true) { }
|
|
~Actions(void) { }
|
|
|
|
bool move;
|
|
bool resize;
|
|
bool minimize; // iconify
|
|
bool shade;
|
|
bool stick;
|
|
bool maximize_horz;
|
|
bool maximize_vert;
|
|
bool fullscreen;
|
|
bool change_desktop; // workspace
|
|
bool close;
|
|
} _actions;
|
|
|
|
static std::list<Client*> _client_list; //!< List of all Clients.
|
|
static std::vector<uint> _clientid_list; //!< List of free Client IDs.
|
|
};
|
|
|
|
#endif // _CLIENT_HH_
|