aboutsummaryrefslogtreecommitdiff
path: root/libLumina
diff options
context:
space:
mode:
authorKen Moore <moorekou@gmail.com>2015-11-11 14:20:56 -0500
committerKen Moore <moorekou@gmail.com>2015-11-11 14:20:56 -0500
commit7cba137e77529ff3c0e431d06efd600ab988f8c2 (patch)
treebcd6d7edac501de491d6f8e2399faf55bb678ba0 /libLumina
parentReplace the libreoffice SVG icon skip with a generic rule that skips any SVG ... (diff)
downloadlumina-7cba137e77529ff3c0e431d06efd600ab988f8c2.tar.gz
lumina-7cba137e77529ff3c0e431d06efd600ab988f8c2.tar.bz2
lumina-7cba137e77529ff3c0e431d06efd600ab988f8c2.zip
Add support for all the important Root window EWMH properties to the LuminaX11 class.
Diffstat (limited to 'libLumina')
-rw-r--r--libLumina/LuminaX11.cpp274
-rw-r--r--libLumina/LuminaX11.h47
2 files changed, 316 insertions, 5 deletions
diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp
index 62f21d49..b395841d 100644
--- a/libLumina/LuminaX11.cpp
+++ b/libLumina/LuminaX11.cpp
@@ -1,6 +1,6 @@
//===========================================
// Lumina-DE source code
-// Copyright (c) 2014, Ken Moore
+// Copyright (c) 2014-2015, Ken Moore
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
@@ -1239,14 +1239,284 @@ void LXCB::WM_ICCCM_SetProtocols(WId win, LXCB::ICCCM_PROTOCOLS flags){
// --------------------------------------------------------
// NET_WM Standards (newer standards)
// --------------------------------------------------------
+// _NET_SUPPORTED (Root)
void LXCB::WM_Set_Root_Supported(){
//NET_WM standards (ICCCM implied - no standard way to list those)
xcb_atom_t list[] = {};
xcb_ewmh_set_supported(&EWMH, QX11Info::appScreen(), 0,list);
}
+// _NET_CLIENT_LIST
+QList<WId> LXCB::WM_Get_Client_List(bool stacking){
+ QList<WId> out;
+ if(stacking){
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list_stacking(&EWMH, QX11Info::appScreen());
+ xcb_ewmh_get_windows_reply_t reply;
+ if(1==xcb_ewmh_get_client_list_stacking_reply(&EWMH, cookie, &reply, NULL) ){
+ for(unsigned int i=0; i<reply.windows_len; i++){
+ out << reply.windows[i];
+ }
+ }
+ }else{
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list(&EWMH, QX11Info::appScreen());
+ xcb_ewmh_get_windows_reply_t reply;
+ if(1==xcb_ewmh_get_client_list_reply(&EWMH, cookie, &reply, NULL) ){
+ for(unsigned int i=0; i<reply.windows_len; i++){
+ out << reply.windows[i];
+ }
+ }
+ }
+ return out;
+}
+
+void LXCB::WM_Set_Client_List(QList<WId> list, bool stacking){
+ //convert the QList into a generic array
+ xcb_window_t array[list.length()];
+ for(int i=0; i<list.length(); i++){ array[i] = list[i]; }
+ if(stacking){
+ xcb_ewmh_set_client_list_stacking(&EWMH, QX11Info::appScreen(), list.length(), array);
+ }else{
+ xcb_ewmh_set_client_list(&EWMH, QX11Info::appScreen(), list.length(), array);
+ }
+
+}
+
+// _NET_NUMBER_OF_DESKTOPS
+unsigned int LXCB::WM_Get_Number_Desktops(){
+ //return value equals 0 for errors
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_number_of_desktops_unchecked(&EWMH, QX11Info::appScreen());
+ uint32_t number = 0;
+ xcb_ewmh_get_number_of_desktops_reply(&EWMH, cookie, &number, NULL);
+ return number;
+}
+
+void LXCB::WM_SetNumber_Desktops(unsigned int number){
+ //NOTE: number should be at least 1
+ xcb_ewmh_set_number_of_desktops(&EWMH, QX11Info::appScreen(), number);
+}
+
+// _NET_DESKTOP_GEOMETRY
+QSize LXCB::WM_Get_Desktop_Geometry(){
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_desktop_geometry(&EWMH, QX11Info::appScreen());
+ uint32_t wid, hi;
+ wid = hi = 0;
+ xcb_ewmh_get_desktop_geometry_reply(&EWMH, cookie, &wid, &hi, NULL);
+ return QSize(wid,hi);
+}
+
+void LXCB::WM_Set_Desktop_Geometry(QSize size){
+ xcb_ewmh_set_desktop_geometry(&EWMH, QX11Info::appScreen(), size.width(), size.height());
+}
+
+// _NET_DESKTOP_VIEWPORT
+QList<QPoint> LXCB::WM_Get_Desktop_Viewport(){
+ QList<QPoint> out;
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_desktop_viewport_unchecked(&EWMH, QX11Info::appScreen());
+ xcb_ewmh_get_desktop_viewport_reply_t reply;
+ if(1==xcb_ewmh_get_desktop_viewport_reply(&EWMH, cookie, &reply, NULL) ){
+ for(unsigned int i=0; i<reply.desktop_viewport_len; i++){
+ out << QPoint( reply.desktop_viewport[i].x, reply.desktop_viewport[i].y );
+ }
+ xcb_ewmh_get_desktop_viewport_reply_wipe(&reply); //clean up the reply structure first
+ }
+ return out;
+}
+
+void LXCB::WM_Set_Desktop_Viewport(QList<QPoint> list){
+ //Turn the QList into xcb_ewmh_coordinates_t*
+ xcb_ewmh_coordinates_t array[list.length()];
+ for(int i=0; i<list.length(); i++){ array[i].x=list[i].x(); array[i].y=list[i].y(); }
+ //Now set the property
+ xcb_ewmh_set_desktop_viewport(&EWMH, QX11Info::appScreen(), list.length(), array);
+}
+
+// _NET_CURRENT_DESKTOP
+int LXCB::WM_Get_Current_Desktop(){
+ //Returns -1 for errors
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop_unchecked(&EWMH, QX11Info::appScreen());
+ uint32_t num = 0;
+ if(1==xcb_ewmh_get_current_desktop_reply(&EWMH, cookie, &num, NULL) ){
+ return num;
+ }else{
+ return -1;
+ }
+}
+
+void LXCB::WM_Set_Current_Desktop(unsigned int num){
+ xcb_ewmh_set_current_desktop(&EWMH, QX11Info::appScreen(), num);
+}
+
+// _NET_DESKTOP_NAMES
+QStringList LXCB::WM_Get_Desktop_Names(){
+ QStringList out;
+ // ** ISSUES with the XCB_EWMH strings reply structure - 11/11/15 (skip for now)
+ // (Appears to be a char* instead of char** in the class definitions)
+ /*xcb_get_property_cookie_t cookie = xcb_ewmh_get_desktop_names_unchecked(&EWMH, QX11Info::appScreen());
+ xcb_ewmh_get_utf8_strings_reply_t reply;
+ if(1==xcb_ewmh_get_desktop_names_reply(&EWMH, cookie, &reply, NULL) ){
+ for(unsigned int i=0; i<reply.strings_len; i++){
+ out << QString::fromUtf8( QByteArray(reply.strings[i]) );
+ }
+ }*/
+ return out;
+}
+
+void LXCB::WM_Set_Desktop_Names(QStringList list){
+ // ** ISSUES with the XCB_EWMH strings input structure - 11/11/15 (skip for now)
+ // (Appears to be a char* instead of char** in the class definitions)
+ /*//Convert to an array of char arrays
+ char *array[ list.length() ];
+ for(int i=0; i<list.length(); i++){array[i] = list[i].toUtf8().data(); }
+ //Now set the property
+ xcb_ewmh_set_desktop_names(&EWMH, QX11Info::appScreen(), list.length(), array);
+ */
+}
+
+// _NET_ACTIVE_WINDOW
+WId LXCB::WM_Get_Active_Window(){
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_active_window_unchecked(&EWMH, QX11Info::appScreen());
+ xcb_window_t win = 0;
+ xcb_ewmh_get_active_window_reply(&EWMH, cookie, &win, NULL);
+ return win;
+}
+
+void LXCB::WM_Set_Active_Window(WId win){
+ xcb_ewmh_set_active_window(&EWMH, QX11Info::appScreen(), win);
+}
+
+// _NET_WORKAREA
+QList<QRect> LXCB::WM_Get_Workarea(){
+ QList<QRect> out;
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_workarea_unchecked(&EWMH, QX11Info::appScreen());
+ xcb_ewmh_get_workarea_reply_t reply;
+ if(1==xcb_ewmh_get_workarea_reply(&EWMH, cookie, &reply, NULL) ){
+ for(unsigned int i=0; i<reply.workarea_len ;i++){
+ out << QRect( reply.workarea[i].x, reply.workarea[i].y, reply.workarea[i].width, reply.workarea[i].height);
+ }
+ xcb_ewmh_get_workarea_reply_wipe(&reply);
+ }
+ return out;
+}
+
+void LXCB::WM_Set_Workarea(QList<QRect> list){
+ //Convert to the XCB/EWMH data structures
+ xcb_ewmh_geometry_t array[list.length()];
+ for(int i=0; i<list.length(); i++){
+ array[i].x = list[i].x(); array[i].y = list[i].y();
+ array[i].width = list[i].width(); array[i].height = list[i].height();
+ }
+ //Now set the property
+ xcb_ewmh_set_workarea(&EWMH, QX11Info::appScreen(), list.length(), array);
+}
+
+// _NET_SUPPORTING_WM_CHECK
+WId LXCB::WM_Get_Supporting_WM(WId win){
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_supporting_wm_check_unchecked(&EWMH, win);
+ xcb_window_t out = 0;
+ xcb_ewmh_get_supporting_wm_check_reply(&EWMH, cookie, &out, NULL);
+ return win;
+}
+
+void LXCB::WM_Set_Supporting_WM(WId child){
+ //Set this property on the root window first
+ xcb_ewmh_set_supporting_wm_check(&EWMH, QX11Info::appRootWindow(), child);
+ //Also set this property on the child window (pointing to itself)
+ xcb_ewmh_set_supporting_wm_check(&EWMH, child, child);
+}
+
+// _NET_VIRTUAL_ROOTS
+QList<WId> LXCB::WM_Get_Virtual_Roots(){
+ QList<WId> out;
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_virtual_roots_unchecked(&EWMH, QX11Info::appScreen());
+ xcb_ewmh_get_windows_reply_t reply;
+ if(1==xcb_ewmh_get_virtual_roots_reply(&EWMH, cookie, &reply, NULL) ){
+ for(unsigned int i=0; i<reply.windows_len; i++){
+ out << reply.windows[i];
+ }
+ }
+ return out;
+}
+
+void LXCB::WM_Set_Virtual_Roots(QList<WId> list){
+ //Convert to XCB array
+ xcb_window_t array[list.length()];
+ for(int i=0; i<list.length(); i++){ array[i] = list[i]; }
+ //Set the property
+ xcb_ewmh_set_virtual_roots(&EWMH, QX11Info::appScreen(), list.length(), array);
+}
+
+// _NET_DESKTOP_LAYOUT
+
+// _NET_SHOWING_DESKTOP
+bool LXCB::WM_Get_Showing_Desktop(){
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_showing_desktop_unchecked(&EWMH, QX11Info::appScreen());
+ uint32_t reply = 0;
+ xcb_ewmh_get_showing_desktop_reply(&EWMH, cookie, &reply, NULL);
+ return (reply==1);
+}
+
+void LXCB::WM_Set_Showing_Desktop(bool show){
+ xcb_ewmh_set_showing_desktop(&EWMH, QX11Info::appScreen(), (show ? 1 : 0) );
+}
+
+// -- ROOT WINDOW MESSAGES/REQUESTS
+// _NET_CLOSE_WINDOW
+void LXCB::WM_Request_Close_Window(WId win){
+ xcb_ewmh_request_close_window(&EWMH, QX11Info::appScreen(), win, XCB_TIME_CURRENT_TIME, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER); //user choice to close the window
+}
+
+// _NET_MOVERESIZE_WINDOW
+
+// _NET_WM_MOVERESIZE
+
+// _NET_RESTACK_WINDOW
+
+// _NET_REQUEST_FRAME_EXTENTS
+
+
+// === WINDOW PROPERTIES ===
+// _NET_SUPPORTED (Window)
void LXCB::WM_Set_Window_Supported(WId win){
//NET_WM standards (ICCCM implied - no standard way to list those)
xcb_atom_t list[] = {};
xcb_ewmh_set_wm_allowed_actions(&EWMH, win, 0, list);
-} \ No newline at end of file
+}
+
+// _NET_WM_NAME
+
+// _NET_WM_VISIBLE_NAME
+
+// _NET_WM_ICON_NAME
+
+// _NET_WM_VISIBLE_ICON_NAME
+
+// _NET_WM_DESKTOP
+
+// _NET_WM_WINDOW_TYPE
+
+// _NET_WM_STATE
+
+// _NET_WM_ALLOWED_ACTIONS
+
+// _NET_WM_STRUT
+
+// _NET_WM_STRUT_PARTIAL
+
+// _NET_WM_ICON_GEOMETRY
+
+// _NET_WM_ICON
+
+// _NET_WM_PID
+
+// _NET_WM_HANDLED_ICONS
+
+// _NET_WM_USER_TIME
+
+// _NET_WM_USER_TIME_WINDOW
+
+// _NET_FRAME_EXTENTS
+
+// _NET_WM_OPAQUE_REGION
+
+// _NET_WM_BYPASS_COMPOSITOR
+ \ No newline at end of file
diff --git a/libLumina/LuminaX11.h b/libLumina/LuminaX11.h
index 779fae0e..fdc86a76 100644
--- a/libLumina/LuminaX11.h
+++ b/libLumina/LuminaX11.h
@@ -1,6 +1,6 @@
//===========================================
// Lumina-DE source code
-// Copyright (c) 2014, Ken Moore
+// Copyright (c) 2014-2015, Ken Moore
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
@@ -149,33 +149,73 @@ public:
// _NET_SUPPORTED
void WM_Set_Root_Supported(); //set the atom list of supported features on the root window
// _NET_CLIENT_LIST
+ // Note: client list ordered oldest->newest, stacking list ordered bottom->top
+ QList<WId> WM_Get_Client_List(bool stacking = false);
+ void WM_Set_Client_List(QList<WId> list, bool stacking=false);
// _NET_NUMBER_OF_DESKTOPS
+ // Note: This is the number of virtual workspaces, not monitors
+ unsigned int WM_Get_Number_Desktops(); //return value equals 0 for errors
+ void WM_SetNumber_Desktops(unsigned int number); //should be at least 1
// _NET_DESKTOP_GEOMETRY
+ // Note: This property is the combined size and/or bounding rectangle of all monitors
+ // The definition works well for single-monitors, but gets really fuzzy for multiple monitors
+ QSize WM_Get_Desktop_Geometry();
+ void WM_Set_Desktop_Geometry(QSize);
// _NET_DESKTOP_VIEWPORT
+ // Note: This is the X/Y origin of the viewport for each monitor
+ // Thi is normally (0,0) , unless desktop larger than monitor supports
+ QList<QPoint> WM_Get_Desktop_Viewport();
+ void WM_Set_Desktop_Viewport(QList<QPoint> list);
// _NET_CURRENT_DESKTOP
+ // Note: Current workspace number. Range = 0 to (_NET_NUMBER_OF_DESKTOPS - 1)
+ int WM_Get_Current_Desktop(); //Returns -1 for errors
+ void WM_Set_Current_Desktop(unsigned int num);
// _NET_DESKTOP_NAMES
+ QStringList WM_Get_Desktop_Names();
+ void WM_Set_Desktop_Names(QStringList list);
// _NET_ACTIVE_WINDOW
+ WId WM_Get_Active_Window();
+ void WM_Set_Active_Window(WId win);
// _NET_WORKAREA
+ // Note: The workarea is the recangle for each monitor where no space is reserved
+ // This accounts for any STRUT's that are set, within the current VIEWPORT
+ QList<QRect> WM_Get_Workarea();
+ void WM_Set_Workarea(QList<QRect> list);
// _NET_SUPPORTING_WM_CHECK
+ // Note: This needs to be set on two windows: root -> child, and child->child
+ // So the "set" function will do both at the same time
+ // The child window also needs the _NET_WM_NAME set to the window manager name
+ WId WM_Get_Supporting_WM(WId win);
+ void WM_Set_Supporting_WM(WId child);
// _NET_VIRTUAL_ROOTS
+ QList<WId> WM_Get_Virtual_Roots();
+ void WM_Set_Virtual_Roots(QList<WId> list);
// _NET_DESKTOP_LAYOUT
+ // NOTE: Skip this implementation for now - is supposed to be set by a pager (not the WM)
+ // and the WM can choose to use/ignore it as necessary.
+ // (Just use the current XRandR layout instead of this setting/property)
// _NET_SHOWING_DESKTOP
+ // Note: This is true/false depending on whether the WM is hiding all windows to show the desktop only
+ bool WM_Get_Showing_Desktop();
+ void WM_Set_Showing_Desktop(bool show);
- // -- ROOT WINDOW MESSAGES
+ // -- ROOT WINDOW MESSAGES/REQUESTS
// _NET_CLOSE_WINDOW
+ void WM_Request_Close_Window(WId win);
- // _NET_MOVERESIZE_WINDOW
+ // _NET_MOVERESIZE_WINDOW
+ //void WM_Request_MoveResize_Window(WId win, LXCB::Gravity grav, LXCB::WindowOptFlags flags, QRect geom);
// _NET_WM_MOVERESIZE
@@ -183,6 +223,7 @@ public:
// _NET_REQUEST_FRAME_EXTENTS
+
// -- WINDOW PROPERTIES
// _NET_SUPPORTED
void WM_Set_Window_Supported(WId win); //set the atom list of supported features on the given window
bgstack15