1 #ifndef WMFRAME_H
2 #define WMFRAME_H
3 
4 #include "ymsgbox.h"
5 #include "wmoption.h"
6 #include "yicon.h"
7 #include "ylist.h"
8 #include "WinMgr.h"
9 #include "workspaces.h"
10 
11 class YClientContainer;
12 class MiniIcon;
13 class TaskBarApp;
14 class TrayApp;
15 class YFrameTitleBar;
16 
17 class YFrameWindow:
18     public YWindow,
19     public YActionListener,
20     private YTimerListener,
21     private YPopDownListener,
22     private YMsgBoxListener,
23     public ClientData,
24     public YLayeredNode,
25     public YCreatedNode,
26     public YFocusedNode
27 {
28 public:
29     YFrameWindow(YActionListener *wmActionListener,
30                  unsigned depth = CopyFromParent,
31                  Visual* visual = nullptr,
32                  Colormap clmap = CopyFromParent);
33     virtual ~YFrameWindow();
34 
35     void doManage(YFrameClient *client, bool &doActivate, bool &requestFocus);
36     void afterManage();
37     void manage();
38     void unmanage(bool reparent = true);
39     void sendConfigure();
40 
41     Window createPointerWindow(Cursor cursor, int gravity);
42     void createPointerWindows();
43     void grabKeys();
44 
45     void focus(bool canWarp = false);
46     void activate(bool canWarp = false, bool curWork = true);
47     void activateWindow(bool raise, bool curWork = true);
48 
49     virtual void paint(Graphics &g, const YRect &r);
50 
51     virtual bool handleKey(const XKeyEvent &key);
52     virtual void handleButton(const XButtonEvent &button);
53     virtual void handleClick(const XButtonEvent &up, int count);
54     virtual bool handleBeginDrag(const XButtonEvent &down, const XMotionEvent &motion);
55     virtual void handleMotion(const XMotionEvent &motion);
56     virtual void handleCrossing(const XCrossingEvent &crossing);
57     virtual void handleFocus(const XFocusChangeEvent &focus);
58     virtual void handleConfigure(const XConfigureEvent &configure);
59     virtual void handleExpose(const XExposeEvent &expose);
60 
61     virtual bool handleTimer(YTimer *t);
62 
63     virtual void actionPerformed(YAction action, unsigned modifiers = 0);
64     virtual void handleMsgBox(YMsgBox *msgbox, int operation);
frame()65     virtual YFrameWindow* frame() { return this; }
66 
67     void wmRestore();
68     void wmMinimize();
69     void wmMaximize();
70     void wmMaximizeVert();
71     void wmMaximizeHorz();
72     void wmRollup();
73     void wmHide();
74     void wmShow();
75     void wmLower();
76     void doLower();
77     void wmRaise();
78     void doRaise();
79     void wmClose();
80     void wmConfirmKill(const char* message = nullptr);
81     void wmKill();
82     void wmNextWindow();
83     void wmPrevWindow();
84     void wmMove();
85     void wmSize();
86     void wmOccupyAll();
87     void wmOccupyAllOrCurrent();
88     void wmOccupyWorkspace(int workspace);
89     void wmSetLayer(int layer);
90     void wmSetTrayOption(int option);
91     void wmTile(YAction action);
92     void wmToggleTray();
93 #if DO_NOT_COVER_OLD
94     void wmToggleDoNotCover();
95 #endif
96     void wmToggleFullscreen();
97 
98     void minimizeTransients();
99     void restoreMinimizedTransients();
100     void hideTransients();
101     void restoreHiddenTransients();
102 
103     void doMaximize(int flags);
104 
105     void loseWinFocus();
106     void setWinFocus();
focused()107     bool focused() const { return fFocused; }
108     void updateFocusOnMap(bool &doActivate);
109 
client()110     YFrameClient *client() const { return fClient; }
111     YFrameTitleBar *titlebar();
container()112     YClientContainer *container() const { return fContainer; }
113 
114     void startMoveSize(int x, int y, int direction);
115 
116     void startMoveSize(bool doMove, bool byMouse,
117                        int sideX, int sideY,
118                        int mouseXroot, int mouseYroot);
119     void endMoveSize();
120     void moveWindow(int newX, int newY);
121     void manualPlace();
122     void snapTo(int &wx, int &wy,
123                 int rx1, int ry1, int rx2, int ry2,
124                 int &flags);
125     void snapTo(int &wx, int &wy);
126 
127     void drawMoveSizeFX(int x, int y, int w, int h);
128     int handleMoveKeys(const XKeyEvent &xev, int &newX, int &newY);
129     int handleResizeKeys(const XKeyEvent &key,
130                          int &newX, int &newY, int &newWidth, int &newHeight,
131                          int incX, int incY);
132     void handleMoveMouse(const XMotionEvent &motion, int &newX, int &newY);
133     void handleResizeMouse(const XMotionEvent &motion,
134                            int &newX, int &newY, int &newWidth, int &newHeight);
135 
136     void outlineMove();
137     void outlineResize();
138 
139     void constrainPositionByModifier(int &x, int &y, const XMotionEvent &motion);
140     void constrainMouseToWorkspace(int &x, int &y);
141 
142     void getDefaultOptions(bool &doActivate);
143 
144     bool canSize(bool horiz = true, bool vert = true);
canMove()145     bool canMove() const { return hasbit(frameFunctions(), ffMove); }
canClose()146     bool canClose() const { return hasbit(frameFunctions(), ffClose); }
canMaximize()147     bool canMaximize() const { return hasbit(frameFunctions(), ffMaximize); }
canMinimize()148     bool canMinimize() const { return hasbit(frameFunctions(), ffMinimize); }
149     bool canRestore() const;
canRollup()150     bool canRollup() const { return (frameFunctions() & ffRollup) && titleY(); }
151     bool canShow() const;
canHide()152     bool canHide() const { return hasbit(frameFunctions(), ffHide); }
153     bool canLower() const;
154     bool canRaise() const;
155     bool canFullscreen() const;
156     bool overlaps(bool below);
157     unsigned overlap(YFrameWindow *other);
158 
159     void insertFrame(bool top);
160     void removeFrame();
161     bool setAbove(YFrameWindow *aboveFrame);
162     bool setBelow(YFrameWindow *belowFrame);
163 
164     enum FindWindowFlags {
165         fwfVisible    = 1 << 0, // visible windows only
166         fwfCycle      = 1 << 1, // cycle when bottom(top) reached
167         fwfBackward   = 1 << 2, // go up in zorder (default=down)
168         fwfNext       = 1 << 3, // start from next window
169         fwfFocusable  = 1 << 4, // only focusable windows
170         fwfWorkspace  = 1 << 5, // current workspace only
171         fwfSame       = 1 << 6, // return same if no match and same matches
172         fwfLayers     = 1 << 7, // find windows in other layers
173         fwfMinimized  = 1 << 9, // minimized/visible windows
174         fwfUnminimized = 1 << 10, // normal/rolledup only
175         fwfHidden     = 1 << 11, // hidden
176         fwfNotHidden  = 1 << 12 // not hidden
177     };
178 
179     YFrameWindow *findWindow(int flag);
180 
181     void updateMenu();
182     virtual void updateSubmenus();
183 
184     virtual void raise();
185     virtual void lower();
186 
187     void popupSystemMenu(YWindow *owner, int x, int y,
188                          unsigned int flags,
189                          YWindow *forWindow = nullptr);
190     virtual void popupSystemMenu(YWindow *owner);
191     virtual void handlePopDown(YPopupWindow *popup);
192 
193     virtual void configure(const YRect2& r);
194 
195     void getNewPos(const XConfigureRequestEvent &cr,
196                    int &cx, int &cy, int &cw, int &ch);
197     void configureClient(const XConfigureRequestEvent &configureRequest);
198     void configureClient(int cx, int cy, int cwidth, int cheight);
199     void netRestackWindow(Window window, int detail);
200 
201     void setShape();
202 
203     enum YFrameFunctions {
204         ffMove          = (1 << 0),
205         ffResize        = (1 << 1),
206         ffClose         = (1 << 2),
207         ffMinimize      = (1 << 3),
208         ffMaximize      = (1 << 4),
209         ffRollup        = (1 << 5),
210         ffHide          = (1 << 6),
211     };
212 
213     enum YFrameDecors {
214         fdTitleBar      = (1 << 0),
215         fdResize        = (1 << 1),
216         fdClose         = (1 << 2),
217         fdMinimize      = (1 << 3),
218         fdMaximize      = (1 << 4),
219         fdRollup        = (1 << 5),
220         fdHide          = (1 << 6),
221         fdDepth         = (1 << 7),
222         fdBorder        = (1 << 8),
223         fdSysMenu       = (1 << 9),
224     };
225 
226     enum YFrameOptions {
227         foAllWorkspaces            = (1 << 0),  // WinStateSticky
228         foMinimized                = (1 << 1),  // WinStateMinimized
229         foMaximizedVert            = (1 << 2),  // WinStateMaximizedVert
230         foMaximizedHorz            = (1 << 3),  // WinStateMaximizedHoriz
231         foMaximizedBoth            = (3 << 2),  // WinStateMaximizedBoth
232         foAppTakesFocus            = (1 << 4),
233         foDoNotCover               = (1 << 5),
234         foDoNotFocus               = (1 << 6),
235         foForcedClose              = (1 << 7),
236         foFullKeys                 = (1 << 8),
237         foFullscreen               = (1 << 9),
238         foIgnoreNoFocusHint        = (1 << 10),
239         foIgnorePagerPreview       = (1 << 11),
240         foIgnorePosition           = (1 << 12),
241         foIgnoreQSwitch            = (1 << 13),
242         foIgnoreTaskBar            = (1 << 14),
243         foIgnoreUrgent             = (1 << 15),
244         foIgnoreWinList            = (1 << 16),
245         foIgnoreActivationMessages = (1 << 17),
246         foNoFocusOnAppRaise        = (1 << 18),
247         foNoFocusOnMap             = (1 << 19),
248         foNoIgnoreTaskBar          = (1 << 20),
249         foClose                    = (1 << 22),
250     };
251 
frameFunctions()252     unsigned frameFunctions() const { return fFrameFunctions; }
frameDecors()253     unsigned frameDecors() const { return fFrameDecors; }
frameOptions()254     unsigned frameOptions() const { return fFrameOptions; }
frameOption(YFrameOptions o)255     bool frameOption(YFrameOptions o) const { return hasbit(fFrameOptions, o); }
256     void updateAllowed();
257     void getFrameHints();
haveHintOption()258     bool haveHintOption() const { return fHintOption; }
getHintOption()259     WindowOption& getHintOption() { return *fHintOption; }
260     WindowOption getWindowOption();
261     void getWindowOptions(WindowOptions* list, WindowOption& opt, bool remove);
262 
263     YMenu *windowMenu();
264 
getState()265     int getState() const { return fWinState; }
266     void setState(int mask, int state);
hasState(int bit)267     bool hasState(int bit) const { return hasbit(fWinState, bit); }
hasStates(int bits)268     bool hasStates(int bits) const { return hasbits(fWinState, bits); }
notState(int bit)269     bool notState(int bit) const { return !hasbit(fWinState, bit); }
270 
isFullscreen()271     bool isFullscreen() const { return hasState(WinStateFullscreen); }
isResizable()272     bool isResizable() const { return hasbit(frameFunctions(), ffResize); }
isUnmapped()273     bool isUnmapped() const { return hasState(WinStateUnmapped); }
isMapped()274     bool isMapped() const { return notState(WinStateUnmapped); }
makeMapped()275     void makeMapped() { return setState(WinStateUnmapped, None); }
276     bool hasBorders() const;
277     int borderXN() const;
278     int borderYN() const;
279     int titleYN() const;
280 
281     int borderX() const;
282     int borderY() const;
283     int titleY() const;
284 
285     void layoutTitleBar();
286     void layoutResizeIndicators();
287     void layoutShape();
288     void layoutClient();
289 
290     YFrameWindow *nextLayer();
291     YFrameWindow *prevLayer();
winListItem()292     WindowListItem *winListItem() const { return fWinListItem; }
setWinListItem(WindowListItem * i)293     void setWinListItem(WindowListItem *i) { fWinListItem = i; }
294 
295     bool addAsTransient();
296     void removeAsTransient();
297     void addTransients();
298     void removeTransients();
299 
setTransient(YFrameWindow * transient)300     void setTransient(YFrameWindow *transient) { fTransient = transient; }
setNextTransient(YFrameWindow * nextTransient)301     void setNextTransient(YFrameWindow *nextTransient) { fNextTransient = nextTransient; }
setOwner(YFrameWindow * owner)302     void setOwner(YFrameWindow *owner) { fOwner = owner; }
transient()303     YFrameWindow *transient() const { return fTransient; }
nextTransient()304     YFrameWindow *nextTransient() const { return fNextTransient; }
owner()305     YFrameWindow *owner() const { return fOwner; }
306     YFrameWindow *mainOwner();
307 
getClientIcon()308     ref<YIcon> getClientIcon() const { return fFrameIcon; }
309     ref<YIcon> clientIcon() const;
310 
311     void getNormalGeometryInner(int *x, int *y, int *w, int *h) const;
312     void setNormalGeometryOuter(int x, int y, int w, int h);
313     void setNormalPositionOuter(int x, int y);
314     void setNormalGeometryInner(int x, int y, int w, int h);
315     void updateDerivedSize(int flagmask);
316 
317     void setCurrentGeometryOuter(YRect newSize);
318     void setCurrentPositionOuter(int x, int y);
319     void limitOuterPosition();
320     void updateNormalSize();
321 
322     void updateTitle();
323     void updateIconTitle();
324     void updateIcon();
325     void updateState();
326     void updateLayer(bool restack = true);
327     void updateIconPosition();
328     void updateLayout();
329     void performLayout();
330 
331     void updateMwmHints(XSizeHints* sh);
332     void updateProperties();
333     void updateTaskBar();
334     void updateAppStatus();
335     void removeAppStatus();
336 
setWindowType(WindowType winType)337     void setWindowType(WindowType winType) { fWindowType = winType; }
isTypeDock()338     bool isTypeDock() { return (fWindowType == wtDock); }
339 
getWorkspace()340     int getWorkspace() const { return fWinWorkspace; }
getTrayOrder()341     int getTrayOrder() const { return fTrayOrder; }
342     void setWorkspace(int workspace);
getActiveLayer()343     int getActiveLayer() const { return fWinActiveLayer; }
344     void setRequestedLayer(int layer);
getRequestedLayer()345     int getRequestedLayer() const { return fWinRequestedLayer; }
getTrayOption()346     int getTrayOption() const { return fWinTrayOption; }
347     void setTrayOption(int option);
348     void setDoNotCover(bool flag);
isMaximized()349     bool isMaximized() const { return hasState(WinStateMaximizedBoth); }
isMaximizedVert()350     bool isMaximizedVert() const { return hasState(WinStateMaximizedVert); }
isMaximizedHoriz()351     bool isMaximizedHoriz() const { return hasState(WinStateMaximizedHoriz); }
isMaximizedFully()352     bool isMaximizedFully() const { return hasStates(WinStateMaximizedBoth); }
isMinimized()353     bool isMinimized() const { return hasState(WinStateMinimized); }
isHidden()354     bool isHidden() const { return hasState(WinStateHidden); }
isSkipPager()355     bool isSkipPager() const { return hasState(WinStateSkipPager); }
isSkipTaskBar()356     bool isSkipTaskBar() const { return hasState(WinStateSkipTaskBar); }
isRollup()357     bool isRollup() const { return hasState(WinStateRollup); }
isSticky()358     bool isSticky() const { return hasState(WinStateSticky); }
isAllWorkspaces()359     bool isAllWorkspaces() const { return fWinWorkspace == AllWorkspaces; }
wasMinimized()360     bool wasMinimized() const { return hasState(WinStateWasMinimized); }
wasHidden()361     bool wasHidden() const { return hasState(WinStateWasHidden); }
362 
isIconic()363     bool isIconic() const { return isMinimized() && fMiniIcon; }
hasMiniIcon()364     bool hasMiniIcon() const { return fMiniIcon != nullptr; }
365     MiniIcon *getMiniIcon();
classHint()366     ClassHint* classHint() const { return client()->classHint(); }
clientLeader()367     Window clientLeader() const { return client()->clientLeader(); }
368 
isManaged()369     bool isManaged() const { return fManaged; }
setManaged(bool isManaged)370     void setManaged(bool isManaged) { fManaged = isManaged; }
371 
372     void setAllWorkspaces();
373 
visibleOn(int workspace)374     bool visibleOn(int workspace) const {
375         return fWinWorkspace == workspace || fWinWorkspace == AllWorkspaces;
376     }
377     bool visibleNow() const;
378 
379     bool isModal();
380     bool hasModal();
381     bool canFocus();
382     bool canFocusByMouse();
383     bool avoidFocus();
384     bool getInputFocusHint();
385 
386     bool inWorkArea() const;
387     bool affectsWorkArea() const;
388 
doNotCover()389     bool doNotCover() const { return frameOption(foDoNotCover); }
390 
getIcon()391     virtual ref<YIcon> getIcon() const { return clientIcon(); }
392 
getTitle()393     virtual mstring getTitle() const { return client()->windowTitle(); }
getIconTitle()394     virtual mstring getIconTitle() const { return client()->iconTitle(); }
395 
396     void updateNetWMStrut();
397     void updateNetWMStrutPartial();
398     void updateNetStartupId();
399     void updateNetWMUserTime();
400     void updateNetWMUserTimeWindow();
401     void updateNetWMWindowOpacity();
402     void updateNetWMFullscreenMonitors(int top, int bottom, int left, int right);
403 
strutLeft()404     int strutLeft() { return fStrutLeft; }
strutRight()405     int strutRight() { return fStrutRight; }
strutTop()406     int strutTop() { return fStrutTop; }
strutBottom()407     int strutBottom() { return fStrutBottom; }
haveStruts()408     bool haveStruts() const { return fHaveStruts; }
409 
410     void setWmUrgency(bool wmUrgency);
411     bool isUrgent() const;
412     bool isPassive() const;
413 
414     int getScreen() const;
415     void refresh();
416 
417     int windowTypeLayer() const;
418 
hasIndicators()419     bool hasIndicators() const { return indicatorsCreated; }
topSideIndicator()420     Window topSideIndicator() const { return topSide; }
topLeftIndicator()421     Window topLeftIndicator() const { return topLeft; }
topRightIndicator()422     Window topRightIndicator() const { return topRight; }
since()423     Time since() const { return fStartManaged; }
startMinimized()424     bool startMinimized() const { return frameOption(foMinimized); }
ignoreActivation()425     bool ignoreActivation() const { return frameOption(foIgnoreActivationMessages); }
426 
427     void addToWindowList();
428     void removeFromWindowList();
429 
430 private:
431     /*typedef enum {
432         fsMinimized       = 1 << 0,
433         fsMaximized       = 1 << 1,
434         fsRolledup        = 1 << 2,
435         fsHidden          = 1 << 3,
436         fsWorkspaceHidden = 1 << 4
437     } FrameStateFlags;*/
438 
439     bool fManaged;
440     bool fFocused;
441     unsigned fFrameFunctions;
442     unsigned fFrameDecors;
443     unsigned fFrameOptions;
444 
445     int normalX, normalY, normalW, normalH;
446     int posX, posY, posW, posH;
447 
448     YFrameClient *fClient;
449     YClientContainer *fContainer;
450     YFrameTitleBar *fTitleBar;
451 
452     YPopupWindow *fPopupActive;
453 
454     int buttonDownX, buttonDownY;
455     int grabX, grabY;
456     bool movingWindow, sizingWindow;
457     int origX, origY, origW, origH;
458 
459     Window topSide, leftSide, rightSide, bottomSide;
460     Window topLeft, topRight, bottomLeft, bottomRight;
461 
462     TaskBarApp *fTaskBarApp;
463     TrayApp *fTrayApp;
464     MiniIcon *fMiniIcon;
465     WindowListItem *fWinListItem;
466     ref<YIcon> fFrameIcon;
467     lazy<WindowOption> fHintOption;
468     lazy<YTimer> fFocusEventTimer;
469 
470     YMsgBox *fKillMsgBox;
471     YFrameWindow *fOwner;
472     YFrameWindow *fTransient;
473     YFrameWindow *fNextTransient;
474     YActionListener *wmActionListener;
475 
476     static lazy<YTimer> fAutoRaiseTimer;
477     static lazy<YTimer> fDelayFocusTimer;
478 
479     int fWinWorkspace;
480     int fWinRequestedLayer;
481     int fWinActiveLayer;
482     int fWinTrayOption;
483     int fWinState;
484     int fWinOptionMask;
485     int fTrayOrder;
486 
487     int fFullscreenMonitorsTop;
488     int fFullscreenMonitorsBottom;
489     int fFullscreenMonitorsLeft;
490     int fFullscreenMonitorsRight;
491 
492     // _NET_WM_STRUT support
493     int fStrutLeft;
494     int fStrutRight;
495     int fStrutTop;
496     int fStrutBottom;
497 
498     // _NET_WM_USER_TIME support
499     UserTime fUserTime;
500     Window fUserTimeWindow;
501     Time fStartManaged;
502 
503     unsigned fShapeWidth;
504     unsigned fShapeHeight;
505     int fShapeTitleY;
506     int fShapeBorderX;
507     int fShapeBorderY;
508     unsigned fShapeDecors;
509     mstring fShapeTitle;
510 
511     bool fHaveStruts;
512     bool indicatorsCreated;
513 
514     enum WindowType fWindowType;
515 
516     enum WindowArranges {
517         waTop,
518         waBottom,
519         waCenter,
520         waLeft,
521         waRight
522     };
523 
524     void wmArrange(int tcb, int lcr);
525     void wmSnapMove(int tcb, int lcr);
526     int getTopCoord(int my, YFrameWindow **w, int count);
527     int getBottomCoord(int My, YFrameWindow **w, int count);
528     int getLeftCoord(int mx, YFrameWindow **w, int count);
529     int getRightCoord(int Mx, YFrameWindow **w, int count);
530 
531     // only focus if mouse moves
532     //static int fMouseFocusX, fMouseFocusY;
533 
534     void repaint();
535     void setGeometry(const YRect &) = delete;
536     void setPosition(int, int) = delete;
537     void setSize(int, int) = delete;
setWindowGeometry(const YRect & r)538     void setWindowGeometry(const YRect &r) {
539         YWindow::setGeometry(r);
540     }
541 
542     struct GroupModal {
GroupModalGroupModal543         GroupModal(Window g, YFrameWindow* f) : group(g), frame(f) { }
544         Window group;
545         YFrameWindow* frame;
546         bool operator==(Window window) const { return window == group; }
547         operator YFrameWindow*() const { return frame; }
548         YFrameWindow* operator->() const { return frame; }
549     };
550     static YArray<GroupModal> groupModals;
551     bool isGroupModalFor(const YFrameWindow* other) const;
552     bool isTransientFor(const YFrameWindow* other) const;
553 };
554 
555 #endif
556 
557 
558 // vim: set sw=4 ts=4 et:
559