1 #ifndef YCLIENT_H 2 #define YCLIENT_H 3 4 #include "ywindow.h" 5 #include "ymenu.h" 6 #include "MwmUtil.h" 7 #ifndef InputHint 8 #include <X11/Xutil.h> 9 #endif 10 11 #define InvalidFrameState (-1) 12 13 class YFrameWindow; 14 class WindowListItem; 15 class YIcon; 16 17 typedef int FrameState; 18 19 enum WindowType { 20 wtCombo, 21 wtDesktop, 22 wtDialog, 23 wtDND, 24 wtDock, 25 wtDropdownMenu, 26 wtMenu, 27 wtNormal, 28 wtNotification, 29 wtPopupMenu, 30 wtSplash, 31 wtToolbar, 32 wtTooltip, 33 wtUtility, 34 }; 35 36 class ClassHint : public XClassHint { 37 public: ClassHint()38 ClassHint() { res_name = res_class = nullptr; } ClassHint(const char * name,const char * klas)39 ClassHint(const char* name, const char* klas) { init(name, klas); } ClassHint(const ClassHint & ch)40 ClassHint(const ClassHint& ch) { init(ch.res_name, ch.res_class); } ~ClassHint()41 ~ClassHint() { reset(); } init(const char * name,const char * klas)42 void init(const char* name, const char* klas) { 43 res_name = name ? strdup(name) : nullptr; 44 res_class = klas ? strdup(klas) : nullptr; 45 } reset()46 void reset() { 47 if (res_name) { XFree(res_name); res_name = nullptr; } 48 if (res_class) { XFree(res_class); res_class = nullptr; } 49 } 50 bool match(const char* resource) const; 51 char* resource() const; 52 void operator=(const ClassHint& hint) { 53 if (this != &hint) { 54 reset(); 55 init(hint.res_name, hint.res_class); 56 } 57 } 58 bool operator==(const ClassHint& hint) { 59 return ((res_name && hint.res_name) ? 60 !strcmp(res_name, hint.res_name) : 61 res_name == hint.res_name) && 62 ((res_class && hint.res_class) ? 63 !strcmp(res_class, hint.res_class) : 64 res_class == hint.res_class); 65 } 66 bool operator!=(const ClassHint& hint) { 67 return !operator==(hint); 68 } nonempty()69 bool nonempty() { 70 return ::nonempty(res_name) || ::nonempty(res_class); 71 } 72 }; 73 74 /* 75 * X11 time state to support _NET_WM_USER_TIME. 76 * Keep track of the time in seconds when we receive a X11 time stamp. 77 * Only compare two X11 time stamps if they are in a time interval. 78 */ 79 class UserTime { 80 private: 81 unsigned long xtime; 82 bool valid; 83 unsigned long since; 84 enum : unsigned long { 85 XTimeMask = 0xFFFFFFFFUL, // milliseconds 86 XTimeRange = 0x7FFFFFFFUL, // milliseconds 87 SInterval = 0x3FFFFFFFUL / 1000, // seconds 88 }; 89 public: UserTime()90 UserTime() : xtime(0), valid(false), since(0) { } 91 explicit UserTime(unsigned long xtime, bool valid = true) : xtime(xtime & XTimeMask)92 xtime(xtime & XTimeMask), valid(valid), since(seconds()) { } time()93 unsigned long time() const { return xtime; } good()94 bool good() const { return valid; } when()95 long when() const { return since; } 96 bool update(unsigned long xtime, bool valid = true) { 97 UserTime u(xtime, valid); 98 return *this < u || xtime == 0 ? (*this = u, true) : false; 99 } 100 bool operator<(const UserTime& u) const { 101 if (since == 0 || u.since == 0) return u.since != 0; 102 if (valid == false || u.valid == false) return u.valid; 103 if (since < u.since && u.since - since > SInterval) return true; 104 if (since > u.since && since - u.since > SInterval) return false; 105 if (xtime < u.xtime) return u.xtime - xtime <= XTimeRange; 106 if (xtime > u.xtime) return xtime - u.xtime > XTimeRange; 107 return false; 108 } 109 bool operator==(const UserTime& u) const { 110 return !(*this < u) && !(u < *this); 111 } 112 }; 113 114 class ClientData { 115 public: 116 virtual void setWinListItem(WindowListItem *i) = 0; 117 virtual YFrameWindow *owner() const = 0; 118 virtual ref<YIcon> getIcon() const = 0; 119 virtual mstring getTitle() const = 0; 120 virtual mstring getIconTitle() const = 0; 121 virtual void activateWindow(bool raise, bool curWork) = 0; 122 virtual bool isHidden() const = 0; 123 virtual bool isMaximized() const = 0; 124 virtual bool isMaximizedVert() const = 0; 125 virtual bool isMaximizedHoriz() const = 0; 126 virtual bool isMaximizedFully() const = 0; 127 virtual bool isMinimized() const = 0; 128 virtual bool isFullscreen() const = 0; 129 virtual bool isRollup() const = 0; 130 virtual void actionPerformed(YAction action, unsigned int modifiers = 0) = 0; 131 virtual bool focused() const = 0; 132 virtual bool visibleNow() const = 0; 133 virtual bool canClose() const = 0; 134 virtual bool canShow() const = 0; 135 virtual bool canHide() const = 0; 136 virtual bool canLower() const = 0; 137 virtual bool canMinimize() const = 0; 138 virtual bool canMaximize() const = 0; 139 virtual bool canRaise() const = 0; 140 virtual bool canRestore() const = 0; 141 virtual bool canRollup() const = 0; 142 virtual void wmRaise() = 0; 143 virtual void wmLower() = 0; 144 virtual void wmMinimize() = 0; 145 virtual int getWorkspace() const = 0; 146 virtual int getTrayOrder() const = 0; 147 virtual int getTrayOption() const = 0; 148 virtual unsigned frameOptions() const = 0; 149 virtual bool isSticky() const = 0; 150 virtual bool isAllWorkspaces() const = 0; 151 virtual bool startMinimized() const = 0; 152 virtual void wmOccupyWorkspace(int workspace) = 0; 153 virtual void popupSystemMenu(YWindow *owner) = 0; 154 virtual void popupSystemMenu(YWindow *owner, int x, int y, 155 unsigned int flags, 156 YWindow *forWindow = nullptr) = 0; 157 virtual void updateSubmenus() = 0; 158 virtual Time since() const = 0; 159 virtual ClassHint* classHint() const = 0; 160 virtual Window clientLeader() const = 0; 161 virtual bool isUrgent() const = 0; 162 virtual void updateAppStatus() = 0; 163 virtual void removeAppStatus() = 0; 164 protected: ~ClientData()165 virtual ~ClientData() {} 166 }; 167 168 class YFrameClient: public YDndWindow 169 , public YTimerListener 170 { 171 typedef YDndWindow super; 172 public: 173 YFrameClient(YWindow *parent, YFrameWindow *frame, Window win = 0, 174 int depth = 0, Visual *visual = nullptr, Colormap cmap = 0); 175 virtual ~YFrameClient(); 176 177 virtual void handleProperty(const XPropertyEvent &property); 178 virtual void handleColormap(const XColormapEvent &colormap); 179 virtual void handleMapNotify(const XMapEvent& map); 180 virtual void handleUnmap(const XUnmapEvent &unmap); 181 virtual void handleDestroyWindow(const XDestroyWindowEvent &destroyWindow); 182 virtual void handleClientMessage(const XClientMessageEvent &message); 183 #ifdef CONFIG_SHAPE 184 virtual void handleShapeNotify(const XShapeEvent &shape); 185 #endif 186 getBorder()187 int getBorder() const { return fBorder; } setBorder(unsigned int border)188 void setBorder(unsigned int border) { fBorder = border; } 189 void setFrame(YFrameWindow *newFrame); getFrame()190 YFrameWindow *getFrame() const { return fFrame; }; 191 192 enum WindowProtocols { 193 wpDeleteWindow = 1 << 0, 194 wpTakeFocus = 1 << 1, 195 wpPing = 1 << 2, 196 }; 197 protocol(WindowProtocols wp)198 bool protocol(WindowProtocols wp) const { return bool(fProtocols & wp); } 199 void sendMessage(Atom msg, Time ts, long p2 = 0L, long p3 = 0L, long p4 = 0L); 200 void sendTakeFocus(); 201 void sendDelete(); 202 void sendPing(); 203 void recvPing(const XClientMessageEvent &message); 204 bool killPid(); timedOut()205 bool timedOut() const { return fTimedOut; } 206 207 enum { 208 csKeepX = 1, 209 csKeepY = 2, 210 csRound = 4 211 }; 212 213 void constrainSize(int &w, int &h, int flags); 214 215 void gravityOffsets(int &xp, int &yp); 216 colormap()217 Colormap colormap() const { return fColormap; } 218 void setColormap(Colormap cmap); 219 220 FrameState getFrameState(); 221 void setFrameState(FrameState state); 222 223 void getWMHints(); hints()224 XWMHints *hints() const { return fHints; } wmHint(int flag)225 bool wmHint(int flag) const { return fHints && (fHints->flags & flag); } 226 Window windowGroupHint() const; 227 Window iconWindowHint() const; 228 Pixmap iconPixmapHint() const; 229 Pixmap iconMaskHint() const; urgencyHint()230 bool urgencyHint() const { return wmHint(XUrgencyHint); } 231 bool isDockApp() const; 232 bool isDockAppIcon() const; 233 bool isDockAppWindow() const; isDocked()234 bool isDocked() const { return fDocked; } setDocked(bool docked)235 void setDocked(bool docked) { fDocked = docked; } 236 237 void getSizeHints(); sizeHints()238 XSizeHints *sizeHints() const { return fSizeHints; } sizeHintsFlags()239 int sizeHintsFlags() const { return fSizeHints ? int(fSizeHints->flags) : 0; } winGravity()240 int winGravity() const { return hasbit(sizeHintsFlags(), PWinGravity) 241 ? fSizeHints->win_gravity : NorthWestGravity; } 242 243 void getProtocols(bool force); 244 245 void getTransient(); ownerWindow()246 Window ownerWindow() const { return fTransientFor; } 247 248 void getClassHint(); classHint()249 ClassHint* classHint() { return &fClassHint; } 250 251 void getNameHint(); 252 void getNetWmName(); 253 void getIconNameHint(); 254 void getNetWmIconName(); 255 void setWindowTitle(const char *title); 256 void setIconTitle(const char *title); windowTitle()257 mstring windowTitle() { return fWindowTitle; } iconTitle()258 mstring iconTitle() { return fIconTitle; } 259 260 void setWorkspaceHint(int workspace); 261 bool getWinWorkspaceHint(int* workspace); 262 263 void setLayerHint(int layer); 264 bool getLayerHint(int* layer); 265 266 void setWinTrayHint(int tray_opt); 267 bool getWinTrayHint(int* tray_opt); 268 269 void setStateHint(); 270 void setWinHintsHint(int hints); winHints()271 int winHints() const { return fWinHints; } 272 273 bool getWinIcons(Atom* type, long* count, long** elem); 274 bool getKwmIcon(long* count, Pixmap** pixmap); 275 bool getNetWMIcon(long* count, long** elem); 276 277 bool getNetWMStateHint(int* mask, int* state); 278 bool getNetWMDesktopHint(int* workspace); 279 bool getNetWMPid(long *pid); 280 bool getNetWMStrut(int *left, int *right, int *top, int *bottom); 281 bool getNetWMStrutPartial(int *left, int *right, int *top, int *bottom); 282 bool getNetStartupId(unsigned long &time); 283 bool getNetWMUserTime(Window window, unsigned long &time); 284 bool getNetWMUserTimeWindow(Window &window); 285 bool getNetWMWindowOpacity(long &opacity); 286 bool getNetWMWindowType(WindowType *window_type); 287 void setNetWMFullscreenMonitors(int top, int bottom, int left, int right); 288 void setNetFrameExtents(int left, int right, int top, int bottom); 289 void setNetWMAllowedActions(Atom *actions, int count); 290 void netStateRequest(int action, int mask); 291 void actionPerformed(YAction action); 292 isPinging()293 bool isPinging() const { return fPinging; } pingTime()294 bool pingTime() const { return fPingTime; } 295 virtual bool handleTimer(YTimer *t); 296 mwmHints()297 MwmHints *mwmHints() const { return fMwmHints._ptr(); } 298 void getMwmHints(); 299 void setMwmHints(const MwmHints &mwm); 300 long mwmFunctions(); 301 long mwmDecors(); 302 shaped()303 bool shaped() const { return fShaped; } 304 void queryShape(); 305 306 void getClientLeader(); 307 void getWindowRole(); 308 clientLeader()309 Window clientLeader() const { return fClientLeader; } windowRole()310 mstring windowRole() const { return fWindowRole; } 311 312 mstring getClientId(Window leader); 313 void getPropertiesList(); 314 315 // virtual void configure(const YRect2 &rect); 316 virtual void handleGravityNotify(const XGravityEvent &gravity); 317 isKdeTrayWindow()318 bool isKdeTrayWindow() { return prop.kde_net_wm_system_tray_window_for; } 319 isEmbed()320 bool isEmbed() { return prop.xembed_info; } 321 322 private: 323 YFrameWindow *fFrame; 324 int fProtocols; 325 int haveButtonGrab; 326 unsigned int fBorder; 327 FrameState fSavedFrameState; 328 int fWinStateHint; 329 XSizeHints *fSizeHints; 330 ClassHint fClassHint; 331 XWMHints *fHints; 332 Colormap fColormap; 333 bool fDocked; 334 bool fShaped; 335 bool fTimedOut; 336 bool fPinging; 337 long fPingTime; 338 lazy<YTimer> fPingTimer; 339 int fWinHints; 340 long fPid; 341 342 mstring fWindowTitle; 343 mstring fIconTitle; 344 345 Window fClientLeader; 346 mstring fWMWindowRole; 347 mstring fWindowRole; 348 349 lazy<MwmHints> fMwmHints; 350 351 Window fTransientFor; 352 353 Pixmap *kwmIcons; 354 struct { 355 bool wm_state : 1; // no property notify 356 bool wm_hints : 1; 357 bool wm_normal_hints : 1; 358 bool wm_transient_for : 1; 359 bool wm_name : 1; 360 bool wm_icon_name : 1; 361 bool wm_class : 1; 362 bool wm_protocols : 1; 363 bool wm_client_leader : 1; 364 bool wm_window_role : 1; 365 bool window_role : 1; 366 bool sm_client_id : 1; 367 bool kwm_win_icon : 1; 368 bool kde_net_wm_system_tray_window_for : 1; 369 bool net_wm_name : 1; 370 bool net_wm_icon_name : 1; 371 bool net_wm_icon : 1; 372 bool net_wm_strut : 1; 373 bool net_wm_strut_partial : 1; 374 bool net_wm_desktop : 1; // no property notify 375 bool net_wm_state : 1; // no property notify 376 bool net_wm_window_type : 1; 377 bool net_startup_id : 1; // no property notify 378 bool net_wm_user_time : 1; 379 bool net_wm_user_time_window : 1; 380 bool net_wm_window_opacity : 1; 381 bool net_wm_pid : 1; 382 bool mwm_hints : 1; 383 bool win_tray : 1; // no property notify 384 bool win_layer : 1; // no property notify 385 bool win_icons : 1; 386 bool xembed_info : 1; 387 } prop; 388 private: // not-used 389 YFrameClient(const YFrameClient &); 390 YFrameClient &operator=(const YFrameClient &); 391 }; 392 393 #endif // YCLIENT_H 394 395 // vim: set sw=4 ts=4 et: 396