aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Moore <moorekou@gmail.com>2015-11-12 17:05:29 -0500
committerKen Moore <moorekou@gmail.com>2015-11-12 17:05:29 -0500
commit301e62b9176eb339fa72a5ab424cd516fd3df13a (patch)
tree9dbec8f79a7ba71a2a49bb9f1e6c89ef686b5338
parentAdd a couple more XCB EWMH functions. One change required a re-definition of ... (diff)
downloadlumina-301e62b9176eb339fa72a5ab424cd516fd3df13a.tar.gz
lumina-301e62b9176eb339fa72a5ab424cd516fd3df13a.tar.bz2
lumina-301e62b9176eb339fa72a5ab424cd516fd3df13a.zip
Add a bunch more of the window-level EWMH standards support into luminaX11. Only a few more to go, and then assembling the WM guts can commence...
-rw-r--r--libLumina/LuminaX11.cpp279
-rw-r--r--libLumina/LuminaX11.h27
2 files changed, 247 insertions, 59 deletions
diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp
index d9dab41c..cecadc99 100644
--- a/libLumina/LuminaX11.cpp
+++ b/libLumina/LuminaX11.cpp
@@ -1589,20 +1589,20 @@ QList<LXCB::WINDOWTYPE> LXCB::WM_Get_Window_Type(WId win){
xcb_ewmh_get_atoms_reply_t reply;
if(1==xcb_ewmh_get_wm_window_type_reply(&EWMH, cookie, &reply, NULL) ){
for(unsigned int i=0; i<reply.atoms_len; i++){
- if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DESKTOP){ out << LXCB::DESKTOP; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DOCK){ out << LXCB::DOCK; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_TOOLBAR){ out << LXCB::TOOLBAR; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_MENU){ out << LXCB::MENU; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_UTILITY){ out << LXCB::UTILITY; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_SPLASH){ out << LXCB::SPLASH; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DIALOG){ out << LXCB::DIALOG; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU){ out << LXCB::DROPDOWN_MENU; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU){ out << LXCB::POPUP_MENU; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_TOOLTIP){ out << LXCB::TOOLTIP; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION){ out << LXCB::NOTIFICATION; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_COMBO){ out << LXCB::COMBO; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DND){ out << LXCB::DND; }
- else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_NORMAL){ out << LXCB::NORMALTYPE; }
+ if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DESKTOP){ out << LXCB::T_DESKTOP; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DOCK){ out << LXCB::T_DOCK; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_TOOLBAR){ out << LXCB::T_TOOLBAR; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_MENU){ out << LXCB::T_MENU; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_UTILITY){ out << LXCB::T_UTILITY; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_SPLASH){ out << LXCB::T_SPLASH; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DIALOG){ out << LXCB::T_DIALOG; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU){ out << LXCB::T_DROPDOWN_MENU; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU){ out << LXCB::T_POPUP_MENU; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_TOOLTIP){ out << LXCB::T_TOOLTIP; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION){ out << LXCB::T_NOTIFICATION; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_COMBO){ out << LXCB::T_COMBO; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_DND){ out << LXCB::T_DND; }
+ else if(reply.atoms[i]==EWMH._NET_WM_WINDOW_TYPE_NORMAL){ out << LXCB::T_NORMAL; }
}
}
return out;
@@ -1613,31 +1613,31 @@ void LXCB::WM_Set_Window_Type(WId win, QList<LXCB::WINDOWTYPE> list){
xcb_atom_t array[list.length()];
for(int i=0; i<list.length(); i++){
switch(list[i]){
- case LXCB::DESKTOP:
+ case LXCB::T_DESKTOP:
array[i] = EWMH._NET_WM_WINDOW_TYPE_DESKTOP; break;
- case LXCB::DOCK:
+ case LXCB::T_DOCK:
array[i] = EWMH._NET_WM_WINDOW_TYPE_DOCK; break;
- case LXCB::TOOLBAR:
+ case LXCB::T_TOOLBAR:
array[i] = EWMH._NET_WM_WINDOW_TYPE_TOOLBAR; break;
- case LXCB::MENU:
+ case LXCB::T_MENU:
array[i] = EWMH._NET_WM_WINDOW_TYPE_MENU; break;
- case LXCB::UTILITY:
+ case LXCB::T_UTILITY:
array[i] = EWMH._NET_WM_WINDOW_TYPE_UTILITY; break;
- case LXCB::SPLASH:
+ case LXCB::T_SPLASH:
array[i] = EWMH._NET_WM_WINDOW_TYPE_SPLASH; break;
- case LXCB::DIALOG:
+ case LXCB::T_DIALOG:
array[i] = EWMH._NET_WM_WINDOW_TYPE_DIALOG; break;
- case LXCB::DROPDOWN_MENU:
+ case LXCB::T_DROPDOWN_MENU:
array[i] = EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU; break;
- case LXCB::POPUP_MENU:
+ case LXCB::T_POPUP_MENU:
array[i] = EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU; break;
- case LXCB::TOOLTIP:
+ case LXCB::T_TOOLTIP:
array[i] = EWMH._NET_WM_WINDOW_TYPE_TOOLTIP; break;
- case LXCB::NOTIFICATION:
+ case LXCB::T_NOTIFICATION:
array[i] = EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION; break;
- case LXCB::COMBO:
+ case LXCB::T_COMBO:
array[i] = EWMH._NET_WM_WINDOW_TYPE_COMBO; break;
- case LXCB::DND:
+ case LXCB::T_DND:
array[i] = EWMH._NET_WM_WINDOW_TYPE_DND; break;
default:
array[i] = EWMH._NET_WM_WINDOW_TYPE_NORMAL;
@@ -1654,18 +1654,18 @@ QList<LXCB::WINDOWSTATE> LXCB::WM_Get_Window_States(WId win){
xcb_ewmh_get_atoms_reply_t reply;
if(1==xcb_ewmh_get_wm_state_reply(&EWMH, cookie, &reply, NULL) ){
for(unsigned int i=0; i<reply.atoms_len; i++){
- if(reply.atoms[i]==EWMH._NET_WM_STATE_MODAL){ out << LXCB::MODAL; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_STICKY){ out << LXCB::STICKY; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_MAXIMIZED_VERT){ out << LXCB::MAX_VERT; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_MAXIMIZED_HORZ){ out << LXCB::MAX_HORZ; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_SHADED){ out << LXCB::SHADED; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_SKIP_TASKBAR){ out << LXCB::SKIP_TASKBAR; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_SKIP_PAGER){ out << LXCB::SKIP_PAGER; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_HIDDEN){ out << LXCB::HIDDEN; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_FULLSCREEN){ out << LXCB::FULLSCREEN; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_ABOVE){ out << LXCB::KEEP_ABOVE; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_BELOW){ out << LXCB::KEEP_BELOW; }
- else if(reply.atoms[i]==EWMH._NET_WM_STATE_DEMANDS_ATTENTION){ out << LXCB::DEMANDS_ATTENTION; }
+ if(reply.atoms[i]==EWMH._NET_WM_STATE_MODAL){ out << LXCB::S_MODAL; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_STICKY){ out << LXCB::S_STICKY; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_MAXIMIZED_VERT){ out << LXCB::S_MAX_VERT; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_MAXIMIZED_HORZ){ out << LXCB::S_MAX_HORZ; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_SHADED){ out << LXCB::S_SHADED; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_SKIP_TASKBAR){ out << LXCB::S_SKIP_TASKBAR; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_SKIP_PAGER){ out << LXCB::S_SKIP_PAGER; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_HIDDEN){ out << LXCB::S_HIDDEN; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_FULLSCREEN){ out << LXCB::S_FULLSCREEN; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_ABOVE){ out << LXCB::S_ABOVE; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_BELOW){ out << LXCB::S_BELOW; }
+ else if(reply.atoms[i]==EWMH._NET_WM_STATE_DEMANDS_ATTENTION){ out << LXCB::S_ATTENTION; }
//else if(reply.atoms[i]==EWMH._NET_WM_STATE_FOCUSED){ out << LXCB::FOCUSED; }
}
}
@@ -1677,29 +1677,29 @@ void LXCB::WM_Set_Window_States(WId win, QList<LXCB::WINDOWSTATE> list){
xcb_atom_t array[list.length()];
for(int i=0; i<list.length(); i++){
switch(list[i]){
- case LXCB::MODAL:
+ case LXCB::S_MODAL:
array[i] = EWMH._NET_WM_STATE_MODAL; break;
- case LXCB::STICKY:
+ case LXCB::S_STICKY:
array[i] = EWMH._NET_WM_STATE_STICKY; break;
- case LXCB::MAX_VERT:
+ case LXCB::S_MAX_VERT:
array[i] = EWMH._NET_WM_STATE_MAXIMIZED_VERT; break;
- case LXCB::MAX_HORZ:
+ case LXCB::S_MAX_HORZ:
array[i] = EWMH._NET_WM_STATE_MAXIMIZED_HORZ; break;
- case LXCB::SHADED:
+ case LXCB::S_SHADED:
array[i] = EWMH._NET_WM_STATE_SHADED; break;
- case LXCB::SKIP_TASKBAR:
+ case LXCB::S_SKIP_TASKBAR:
array[i] = EWMH._NET_WM_STATE_SKIP_TASKBAR; break;
- case LXCB::SKIP_PAGER:
+ case LXCB::S_SKIP_PAGER:
array[i] = EWMH._NET_WM_STATE_SKIP_PAGER; break;
- case LXCB::HIDDEN:
+ case LXCB::S_HIDDEN:
array[i] = EWMH._NET_WM_STATE_HIDDEN; break;
- case LXCB::FULLSCREEN:
+ case LXCB::S_FULLSCREEN:
array[i] = EWMH._NET_WM_STATE_FULLSCREEN; break;
- case LXCB::KEEP_ABOVE:
+ case LXCB::S_ABOVE:
array[i] = EWMH._NET_WM_STATE_ABOVE; break;
- case LXCB::KEEP_BELOW:
+ case LXCB::S_BELOW:
array[i] = EWMH._NET_WM_STATE_BELOW; break;
- case LXCB::DEMANDS_ATTENTION:
+ case LXCB::S_ATTENTION:
array[i] = EWMH._NET_WM_STATE_DEMANDS_ATTENTION; break;
//case LXCB::FOCUSED:
//array[i] = EWMH._NET_WM_STATE_FOCUSED; break;
@@ -1710,15 +1710,162 @@ void LXCB::WM_Set_Window_States(WId win, QList<LXCB::WINDOWSTATE> list){
}
// _NET_WM_ALLOWED_ACTIONS
-
+QList<LXCB::WINDOWACTION> LXCB::WM_Get_Window_Actions(WId win){
+ QList<LXCB::WINDOWACTION> out;
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_allowed_actions_unchecked(&EWMH, win);
+ xcb_ewmh_get_atoms_reply_t reply;
+ if(1==xcb_ewmh_get_wm_allowed_actions_reply(&EWMH, cookie, &reply, NULL) ){
+ for(unsigned int i=0; i<reply.atoms_len; i++){
+ if(reply.atoms[i]==EWMH._NET_WM_ACTION_MOVE){ out << LXCB::A_MOVE; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_RESIZE){ out << LXCB::A_RESIZE; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_MINIMIZE){ out << LXCB::A_MINIMIZE; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_SHADE){ out << LXCB::A_SHADE; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_STICK){ out << LXCB::A_STICK; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_MAXIMIZE_HORZ){ out << LXCB::A_MAX_HORZ; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_MAXIMIZE_VERT){ out << LXCB::A_MAX_VERT; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_FULLSCREEN){ out << LXCB::A_FULLSCREEN; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_CHANGE_DESKTOP){ out << LXCB::A_CHANGE_DESKTOP; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_CLOSE){ out << LXCB::A_CLOSE; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_ABOVE){ out << LXCB::A_ABOVE; }
+ else if(reply.atoms[i]==EWMH._NET_WM_ACTION_BELOW){ out << LXCB::A_BELOW; }
+ }
+ }
+ return out;
+}
+
+void LXCB::WM_Set_Window_Actions(WId win, QList<LXCB::WINDOWACTION> list){
+ //Convert to the XCB format
+ xcb_atom_t array[list.length()];
+ for(int i=0; i<list.length(); i++){
+ switch(list[i]){
+ case LXCB::A_MOVE:
+ array[i] = EWMH._NET_WM_ACTION_MOVE; break;
+ case LXCB::A_RESIZE:
+ array[i] = EWMH._NET_WM_ACTION_RESIZE; break;
+ case LXCB::A_MINIMIZE:
+ array[i] = EWMH._NET_WM_ACTION_MINIMIZE; break;
+ case LXCB::A_SHADE:
+ array[i] = EWMH._NET_WM_ACTION_SHADE; break;
+ case LXCB::A_STICK:
+ array[i] = EWMH._NET_WM_ACTION_STICK; break;
+ case LXCB::A_MAX_HORZ:
+ array[i] = EWMH._NET_WM_ACTION_MAXIMIZE_HORZ; break;
+ case LXCB::A_MAX_VERT:
+ array[i] = EWMH._NET_WM_ACTION_MAXIMIZE_VERT; break;
+ case LXCB::A_FULLSCREEN:
+ array[i] = EWMH._NET_WM_ACTION_FULLSCREEN; break;
+ case LXCB::A_CHANGE_DESKTOP:
+ array[i] = EWMH._NET_WM_ACTION_CHANGE_DESKTOP; break;
+ case LXCB::A_CLOSE:
+ array[i] = EWMH._NET_WM_ACTION_CLOSE; break;
+ case LXCB::A_ABOVE:
+ array[i] = EWMH._NET_WM_ACTION_ABOVE; break;
+ case LXCB::A_BELOW:
+ array[i] = EWMH._NET_WM_ACTION_BELOW; break;
+ }
+ }
+ //Now set the property
+ xcb_ewmh_set_wm_allowed_actions(&EWMH, win, list.length(), array);
+}
+
// _NET_WM_STRUT
-
+QList<unsigned int> LXCB::WM_Get_Window_Strut(WId win){
+ //Returns: [left,right,top,bottom] margins in pixels (always length 4)
+ QList<unsigned int> out; out << 0 << 0 << 0 << 0; //init the output list
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_strut_unchecked(&EWMH, win);
+ xcb_ewmh_get_extents_reply_t reply;
+ if(1==xcb_ewmh_get_wm_strut_reply(&EWMH, cookie, &reply, NULL) ){
+ out[0] = reply.left;
+ out[1] = reply.right;
+ out[2] = reply.top;
+ out[3] = reply.bottom;
+ }
+ return out;
+}
+
+void LXCB::WM_Set_Window_Strut(WId win, QList<unsigned int> margins){
+ //Input: [left, right, top, bottom] - must be length 4
+ while(margins.length()<4){ margins << 0; }
+ xcb_ewmh_set_wm_strut(&EWMH, win, margins[0], margins[1], margins[2], margins[3]);
+}
+
// _NET_WM_STRUT_PARTIAL
-
+QList<strut_geom> LXCB::WM_Get_Window_Strut_Partial(WId win){
+ //Returns: [left,right,top,bottom] struts
+ QList<strut_geom> out; out << strut_geom() << strut_geom() << strut_geom() << strut_geom();
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_strut_partial_unchecked(&EWMH, win);
+ xcb_ewmh_wm_strut_partial_t reply;
+ if(1==xcb_ewmh_get_wm_strut_partial_reply(&EWMH, cookie, &reply, NULL) ){
+ if(reply.left>0){
+ out[0].start = reply.left_start_y; out[0].end = reply.left_end_y; out[0].thick = reply.left;
+ }
+ if(reply.right>0){
+ out[1].start = reply.right_start_y; out[1].end = reply.right_end_y; out[1].thick = reply.right;
+ }
+ if(reply.top>0){
+ out[2].start = reply.top_start_x; out[2].end = reply.top_end_x; out[2].thick = reply.top;
+ }
+ if(reply.bottom>0){
+ out[3].start = reply.bottom_start_x; out[3].end = reply.bottom_end_x; out[3].thick = reply.bottom;
+ }
+ }
+ return out;
+}
+
+void LXCB::WM_Set_Window_Strut_Partial(WId win, QList<strut_geom> struts){
+ //Input: [left,right,top,bottom] - must be length 4
+ while(struts.length() < 4){ struts << strut_geom(); }
+ //Convert to the XCB input format
+ xcb_ewmh_wm_strut_partial_t input;
+ input.left=struts[0].thick; input.left_start_y=struts[0].start; input.left_end_y=struts[0].end;
+ input.right=struts[1].thick; input.right_start_y=struts[1].start; input.right_end_y=struts[1].end;
+ input.top=struts[2].thick; input.top_start_x=struts[2].start; input.top_end_x=struts[2].end;
+ input.bottom=struts[3].thick; input.bottom_start_x=struts[3].start; input.bottom_end_x=struts[3].end;
+ //Now set the property
+ xcb_ewmh_set_wm_strut_partial(&EWMH, win, input);
+}
+
// _NET_WM_ICON_GEOMETRY
-
+QRect LXCB::WM_Get_Icon_Geometry(WId win){
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_geometry_unchecked(&EWMH, win);
+ xcb_ewmh_geometry_t reply;
+ QRect out;
+ if(1==xcb_ewmh_get_wm_icon_geometry_reply(&EWMH, cookie, &reply, NULL) ){
+ out = QRect(reply.x, reply.y, reply.width, reply.height);
+ }
+ return out;
+}
+
+void LXCB::WM_Set_Icon_Geometry(WId win, QRect geom){
+ //Note - 11/12/15: xcb_ewmh.h lists the inputs as "left/right/top/bottom"
+ // but this might be an error and the real inputs are "x/y/width/height"
+ // as in the other geometry get/set routines (and as returned by the xcb_ewmh_get_wm_icon_geometry() routine)
+ xcb_ewmh_set_wm_icon_geometry(&EWMH, win, geom.x(), geom.x()+geom.width(), geom.y(), geom.y()+geom.height());
+ //xcb_ewmh_set_wm_icon_geometry(&EWMH, win, geom.x(), geom.y(), geom.width(), geom.height());
+}
+
// _NET_WM_ICON
-
+QIcon LXCB::WM_Get_Icon(WId win){
+ //Note: The output is a QIcon because it allows for multiple varying-sized images to be loaded/used later as needed
+ // For each pixmap found here, add it (in its native size) to the icon structure
+ QIcon out;
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_unchecked(&EWMH, win);
+ xcb_ewmh_get_wm_icon_reply_t reply;
+ if(1==xcb_ewmh_get_wm_icon_reply(&EWMH, cookie, &reply, NULL) ){
+ //Now iterate over all the pixmaps and load them into the QIcon
+ xcb_ewmh_wm_icon_iterator_t it = xcb_ewmh_get_wm_icon_iterator(&reply);
+ while(it.index < reply.num_icons){
+ QImage img( (const unsigned char *) it.data, it.width, it.height, QImage::Format_ARGB32);
+ out.addPixmap( QPixmap::fromImage(img) );
+ if(it.rem>0){ xcb_ewmh_get_wm_icon_next(&it); } //go to the next pixmap
+ else{ break; } //just finished the last one - ensure this breaks out now (just in case)
+ }
+ //Clean up any background buffer for the reply
+ xcb_ewmh_get_wm_icon_reply_wipe(&reply);
+ }
+ return out;
+}
+
// _NET_WM_PID
// _NET_WM_HANDLED_ICONS
@@ -1728,7 +1875,25 @@ void LXCB::WM_Set_Window_States(WId win, QList<LXCB::WINDOWSTATE> list){
// _NET_WM_USER_TIME_WINDOW
// _NET_FRAME_EXTENTS
-
+QList<unsigned int> LXCB::WM_Get_Frame_Extents(WId win){
+ //Returns: [left,right,top,bottom] margins in pixels (always length 4)
+ QList<unsigned int> out; out << 0 << 0 << 0 << 0; //init the output list
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_frame_extents_unchecked(&EWMH, win);
+ xcb_ewmh_get_extents_reply_t reply;
+ if(1==xcb_ewmh_get_frame_extents_reply(&EWMH, cookie, &reply, NULL) ){
+ out[0] = reply.left;
+ out[1] = reply.right;
+ out[2] = reply.top;
+ out[3] = reply.bottom;
+ }
+ return out;
+}
+
+void LXCB::WM_Set_Frame_Extents(WId win, QList<unsigned int> margins){
+ //Input: [left, right, top, bottom] - must be length 4
+ while(margins.length()<4){ margins << 0; }
+ xcb_ewmh_set_frame_extents(&EWMH, win, margins[0], margins[1], margins[2], margins[3]);
+}
// _NET_WM_OPAQUE_REGION
// _NET_WM_BYPASS_COMPOSITOR
diff --git a/libLumina/LuminaX11.h b/libLumina/LuminaX11.h
index 426b86ab..a66a0c3a 100644
--- a/libLumina/LuminaX11.h
+++ b/libLumina/LuminaX11.h
@@ -35,6 +35,16 @@
#define URGENCYHINT (1L << 8) //For window urgency detection
+//Simple data container for doing STRUT_PARTIAL input/output calculations
+class strut_geom{
+public:
+ //Note: "Thick" will always be in the direction perpenticular to the start/end coordinates
+ //Example: A left strut will use start/end as Y coordinates, with "thick" in X coordinates starting from the left edge
+ unsigned int start, end, thick;
+ strut_geom(){ start = end = thick = 0; }
+ ~strut_geom(){}
+};
+
//XCB Library replacement for LX11 (Qt5 uses XCB instead of XLib)
class LXCB{
@@ -43,8 +53,9 @@ public:
enum ICCCM_STATE {WITHDRAWN, NORMAL, ICONIC};
enum GRAVITY {FORGET=0, NW=1, N=2, NE=3, W=4, CENTER=5, E=6, SW=7, S=8, SE=9, STATIC=10};
enum STACK_FLAG {ABOVE=0, BELOW=1, TOP_IF=2, BOTTOM_IF=3, OPPOSITE=4};
- enum WINDOWTYPE {DESKTOP, DOCK, TOOLBAR, MENU, UTILITY, SPLASH, DIALOG, DROPDOWN_MENU, POPUP_MENU, TOOLTIP, NOTIFICATION, COMBO, DND, NORMALTYPE};
- enum WINDOWSTATE {MODAL, STICKY, MAX_VERT, MAX_HORZ, SHADED, SKIP_TASKBAR, SKIP_PAGER, HIDDEN, FULLSCREEN, KEEP_ABOVE, KEEP_BELOW, DEMANDS_ATTENTION};
+ enum WINDOWTYPE {T_DESKTOP, T_DOCK, T_TOOLBAR, T_MENU, T_UTILITY, T_SPLASH, T_DIALOG, T_DROPDOWN_MENU, T_POPUP_MENU, T_TOOLTIP, T_NOTIFICATION, T_COMBO, T_DND, T_NORMAL};
+ enum WINDOWSTATE {S_MODAL, S_STICKY, S_MAX_VERT, S_MAX_HORZ, S_SHADED, S_SKIP_TASKBAR, S_SKIP_PAGER, S_HIDDEN, S_FULLSCREEN, S_ABOVE, S_BELOW, S_ATTENTION};
+ enum WINDOWACTION {A_MOVE, A_RESIZE, A_MINIMIZE, A_SHADE, A_STICK, A_MAX_VERT, A_MAX_HORZ, A_FULLSCREEN, A_CHANGE_DESKTOP, A_CLOSE, A_ABOVE, A_BELOW};
//Now enums which can have multiple values at once (Use the plural form for the QFlags)
enum ICCCM_PROTOCOL {TAKE_FOCUS = 0x0, DELETE_WINDOW = 0x1}; //any combination
Q_DECLARE_FLAGS(ICCCM_PROTOCOLS, ICCCM_PROTOCOL);
@@ -273,14 +284,24 @@ public:
void WM_Set_Window_States(WId win, QList<LXCB::WINDOWSTATE> list);
// _NET_WM_ALLOWED_ACTIONS
+ QList<LXCB::WINDOWACTION> WM_Get_Window_Actions(WId win);
+ void WM_Set_Window_Actions(WId win, QList<LXCB::WINDOWACTION> list);
// _NET_WM_STRUT
+ QList<unsigned int> WM_Get_Window_Strut(WId win); //Returns: [left,right,top,bottom] margins in pixels (always length 4)
+ void WM_Set_Window_Strut(WId win, QList<unsigned int> margins); //Input: [left, right, top, bottom] - must be length 4
// _NET_WM_STRUT_PARTIAL
+ QList<strut_geom> WM_Get_Window_Strut_Partial(WId win); //Returns: [left,right,top,bottom] struts
+ void WM_Set_Window_Strut_Partial(WId win, QList<strut_geom> struts); //Input: [left,right,top,bottom] - must be length 4
// _NET_WM_ICON_GEOMETRY
+ QRect WM_Get_Icon_Geometry(WId win);
+ void WM_Set_Icon_Geometry(WId win, QRect geom);
// _NET_WM_ICON
+ // Note: Don't write a "Set" routine for this - that is handled on the client side and not the WM/DE side
+ QIcon WM_Get_Icon(WId win);
// _NET_WM_PID
@@ -291,6 +312,8 @@ public:
// _NET_WM_USER_TIME_WINDOW
// _NET_FRAME_EXTENTS
+ QList<unsigned int> WM_Get_Frame_Extents(WId win); //Returns: [left,right,top,bottom] margins in pixels (always length 4)
+ void WM_Set_Frame_Extents(WId win, QList<unsigned int> margins); //Input: [left, right, top, bottom] - must be length 4
// _NET_WM_OPAQUE_REGION
bgstack15