From 2a45036bc3a74aaba919353f3ac5c84df1004eed Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Mon, 26 Jun 2017 10:37:07 -0400 Subject: Tag Version 1.3.0 in source Ensure the translation files are all in sync as well. --- src-qt5/core/libLumina/LDesktopUtils.cpp | 110 +++++++++++++++---------------- 1 file changed, 55 insertions(+), 55 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index d76c68e9..caf3c55e 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -15,12 +15,12 @@ static QStringList fav; -QString LDesktopUtils::LuminaDesktopVersion(){ - QString ver = "1.2.2"; +QString LDesktopUtils::LuminaDesktopVersion(){ + QString ver = "1.3.0"; #ifdef GIT_VERSION ver.append( QString(" (Git Revision: %1)").arg(GIT_VERSION) ); #endif - return ver; + return ver; } QString LDesktopUtils::LuminaDesktopBuildDate(){ @@ -88,7 +88,7 @@ QStringList LDesktopUtils::listFavorites(){ fav.removeDuplicates(); lastRead = cur; } - + return fav; } @@ -138,7 +138,7 @@ void LDesktopUtils::removeFavorite(QString path){ void LDesktopUtils::upgradeFavorites(int){ //fromoldversionnumber //NOTE: Version number syntax: *1000000 + *1000 + // Example: 1.2.3 -> 1002003 -} +} void LDesktopUtils::LoadSystemDefaults(bool skipOS){ //Will create the Lumina configuration files based on the current system template (if any) @@ -156,15 +156,15 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ QDesktopWidget *desk =QApplication::desktop(); QRect screenGeom; for(int i=0; iscreenCount(); i++){ - if(desk->screenGeometry(i).x()==0){ - screen = QString::number(i); - screenGeom = desk->screenGeometry(i); - break; + if(desk->screenGeometry(i).x()==0){ + screen = QString::number(i); + screenGeom = desk->screenGeometry(i); + break; } } //Now setup the default "desktopsettings.conf" and "sessionsettings.conf" files QStringList deskset, sesset;//, lopenset; - + // -- SESSION SETTINGS -- QStringList tmp = sysDefaults.filter("session_"); if(tmp.isEmpty()){ tmp = sysDefaults.filter("session."); }//for backwards compat @@ -177,36 +177,36 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(val.isEmpty()){ continue; } QString istrue = (val.toLower()=="true") ? "true": "false"; //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while - if(var.contains(".")){ var.replace(".","_"); } - //Now parse the variable and put the value in the proper file - + if(var.contains(".")){ var.replace(".","_"); } + //Now parse the variable and put the value in the proper file + if(var.contains("_default_")){ val = LUtils::AppToAbsolute(val); } //got an application/binary //Special handling for values which need to exist first - if(var.endsWith("_ifexists") ){ + if(var.endsWith("_ifexists") ){ var = var.remove("_ifexists"); //remove this flag from the variable //Check if the value exists (absolute path only) if(!QFile::exists(val)){ continue; } //skip this line - value/file does not exist } - + //Parse/save the value QString sset; //temporary strings if(var=="session_enablenumlock"){ sset = "EnableNumlock="+ istrue; } else if(var=="session_playloginaudio"){ sset = "PlayStartupAudio="+istrue; } else if(var=="session_playlogoutaudio"){ sset = "PlayLogoutAudio="+istrue; } - else if(var=="session_default_terminal"){ + else if(var=="session_default_terminal"){ LXDG::setDefaultAppForMime("application/terminal", val); - //sset = "default-terminal="+val; - }else if(var=="session_default_filemanager"){ + //sset = "default-terminal="+val; + }else if(var=="session_default_filemanager"){ LXDG::setDefaultAppForMime("inode/directory", val); //sset = "default-filemanager="+val; - //loset = "directory="+val; - }else if(var=="session_default_webbrowser"){ - //loset = "webbrowser="+val; + //loset = "directory="+val; + }else if(var=="session_default_webbrowser"){ + //loset = "webbrowser="+val; LXDG::setDefaultAppForMime("x-scheme-handler/http", val); LXDG::setDefaultAppForMime("x-scheme-handler/https", val); - }else if(var=="session_default_email"){ + }else if(var=="session_default_email"){ LXDG::setDefaultAppForMime("application/email",val); - //loset = "email="+val; + //loset = "email="+val; } //Put the line into the file (overwriting any previous assignment as necessary) /*if(!loset.isEmpty()){ @@ -218,7 +218,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(!sset.isEmpty()){ int index = sesset.indexOf(QRegExp(sset.section("=",0,0)+"=*", Qt::CaseSensitive, QRegExp::Wildcard)); if(index<0){ sesset << sset; } //new line - else{ sesset[index] = sset; } //overwrite the other line + else{ sesset[index] = sset; } //overwrite the other line } } //if(!lopenset.isEmpty()){ lopenset.prepend("[default]"); } //the session options exist within this set @@ -232,11 +232,11 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(val.isEmpty()){ continue; } QString istrue = (val.toLower()=="true") ? "true": "false"; //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while - if(var.contains(".")){ var.replace(".","_"); } - //Now parse the variable and put the value in the proper file + if(var.contains(".")){ var.replace(".","_"); } + //Now parse the variable and put the value in the proper file val = LUtils::AppToAbsolute(val); //Special handling for values which need to exist first - if(var.endsWith("_ifexists") ){ + if(var.endsWith("_ifexists") ){ var = var.remove("_ifexists"); //remove this flag from the variable //Check if the value exists (absolute path only) if(!QFile::exists(val)){ continue; } //skip this line - value/file does not exist @@ -259,8 +259,8 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(val.isEmpty()){ continue; } QString istrue = (val.toLower()=="true") ? "true": "false"; //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while - if(var.contains(".")){ var.replace(".","_"); } - //Now parse the variable and put the value in the proper file + if(var.contains(".")){ var.replace(".","_"); } + //Now parse the variable and put the value in the proper file if(var=="desktop_visiblepanels"){ deskset << "panels="+val; } else if(var=="desktop_backgroundfiles"){ deskset << "background\\filelist="+val; } else if(var=="desktop_backgroundrotateminutes"){ deskset << "background\\minutesToChange="+val; } @@ -282,8 +282,8 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(val.isEmpty()){ continue; } QString istrue = (val.toLower()=="true") ? "true": "false"; //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while - if(var.contains(".")){ var.replace(".","_"); } - //Now parse the variable and put the value in the proper file + if(var.contains(".")){ var.replace(".","_"); } + //Now parse the variable and put the value in the proper file if(var==(panvar+"_pixelsize")){ //qDebug() << "Panel Size:" << val; if(val.contains("%")){ @@ -293,7 +293,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ else if(last=="w"){ val = QString::number( qRound(screenGeom.width()*val.toDouble())/100 ); }//adjust value to a percentage of the width of the screen } //qDebug() << " -- Adjusted:" << val; - deskset << "height="+val; + deskset << "height="+val; } else if(var==(panvar+"_autohide")){ deskset << "hidepanel="+istrue; } else if(var==(panvar+"_location")){ deskset << "location="+val.toLower(); } @@ -314,8 +314,8 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ QString val = tmp[i].section("=",1,1).section("#",0,0).toLower().simplified(); if(val.isEmpty()){ continue; } //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while - if(var.contains(".")){ var.replace(".","_"); } - //Now parse the variable and put the value in the proper file + if(var.contains(".")){ var.replace(".","_"); } + //Now parse the variable and put the value in the proper file if(var=="menu_plugins"){ deskset << "itemlist="+val; } } if(!tmp.isEmpty()){ deskset << ""; } //space between sections @@ -328,7 +328,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ QString var = tmp[i].section("=",0,0).toLower().simplified(); QString val = tmp[i].section("=",1,1).section("#",0,0).simplified(); //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while - if(var.contains(".")){ var.replace(".","_"); } + if(var.contains(".")){ var.replace(".","_"); } //Now parse the variable and put the value in the proper file qDebug() << "Favorite entry:" << var << val; val = LUtils::AppToAbsolute(val); //turn any relative files into absolute @@ -346,19 +346,19 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ QString var = tmp[i].section("=",0,0).toLower().simplified(); QString val = tmp[i].section("=",1,1).section("#",0,0).simplified(); //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while - if(var.contains(".")){ var.replace(".","_"); } + if(var.contains(".")){ var.replace(".","_"); } //Now parse the variable and put the value in the proper file val = LUtils::AppToAbsolute(val); //turn any relative files into absolute if(var=="quicklaunch_add_ifexists" && QFile::exists(val)){ quickL << val; } else if(var=="quicklaunch_add"){ quickL << val; } } - if(!quickL.isEmpty()){ + if(!quickL.isEmpty()){ if(sesset.isEmpty()){ sesset << "[General]"; } //everything is in this section - sesset << "QuicklaunchApps="+quickL.join(", "); + sesset << "QuicklaunchApps="+quickL.join(", "); } //Now do any theme settings - QStringList themesettings = LTHEME::currentSettings(); + QStringList themesettings = LTHEME::currentSettings(); //List: [theme path, colorspath, iconsname, font, fontsize] //qDebug() << "Current Theme Color:" << themesettings[1]; tmp = sysDefaults.filter("theme_"); @@ -370,19 +370,19 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ QString val = tmp[i].section("=",1,1).section("#",0,0).simplified(); if(val.isEmpty()){ continue; } //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while - if(var.contains(".")){ var.replace(".","_"); } - //Now parse the variable and put the value in the proper file + if(var.contains(".")){ var.replace(".","_"); } + //Now parse the variable and put the value in the proper file if(var=="theme_themefile"){ themesettings[0] = val; } else if(var=="theme_colorfile"){ themesettings[1] = val; } else if(var=="theme_iconset"){ themesettings[2] = val; } else if(var=="theme_font"){ themesettings[3] = val; } - else if(var=="theme_fontsize"){ + else if(var=="theme_fontsize"){ if(val.endsWith("%")){ val = QString::number( (screenGeom.height()*val.section("%",0,0).toDouble())/100 )+"px"; } - themesettings[4] = val; + themesettings[4] = val; } } //qDebug() << " - Now Color:" << themesettings[1] << setTheme; - + //Now double check that the custom theme/color files exist and reset it will the full path as necessary if(setTheme){ QStringList systhemes = LTHEME::availableSystemThemes(); @@ -414,15 +414,15 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ //Ensure that the settings directory exists QString setdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop"; - if(!QFile::exists(setdir)){ - QDir dir; - dir.mkpath(setdir); + if(!QFile::exists(setdir)){ + QDir dir; + dir.mkpath(setdir); } //Now save the settings files if(setTheme){ LTHEME::setCurrentSettings( themesettings[0], themesettings[1], themesettings[2], themesettings[3], themesettings[4]); } LUtils::writeFile(setdir+"/sessionsettings.conf", sesset, true); LUtils::writeFile(setdir+"/desktopsettings.conf", deskset, true); - + //Now run any extra config scripts or utilities as needed tmp = sysDefaults.filter("usersetup_run"); if(tmp.isEmpty()){ tmp = sysDefaults.filter("usersetup.run"); } @@ -431,25 +431,25 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ QString var = tmp[i].section("=",0,0).toLower().simplified(); QString val = tmp[i].section("=",1,1).section("#",0,0).simplified(); //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while - if(var.contains(".")){ var.replace(".","_"); } + if(var.contains(".")){ var.replace(".","_"); } //Now parse the variable and put the value in the proper file if(var=="usersetup_run"){ qDebug() << "Running user setup command:" << val; QProcess::execute(val); } } - + } bool LDesktopUtils::checkUserFiles(QString lastversion){ - //internal version conversion examples: + //internal version conversion examples: // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001] //returns true if something changed int oldversion = LDesktopUtils::VersionStringToNumber(lastversion); int nversion = LDesktopUtils::VersionStringToNumber(QApplication::applicationVersion()); bool newversion = ( oldversion < nversion ); //increasing version number bool newrelease = ( lastversion.contains("-devel", Qt::CaseInsensitive) && QApplication::applicationVersion().contains("-release", Qt::CaseInsensitive) ); //Moving from devel to release - + QString confdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/"; //Check for the desktop settings file QString dset = confdir+"desktopsettings.conf"; @@ -461,7 +461,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion){ } //Convert the favorites framework as necessary (change occured with 0.8.4) if(newversion || newrelease){ - LDesktopUtils::upgradeFavorites(oldversion); + LDesktopUtils::upgradeFavorites(oldversion); } //Convert from the old desktop numbering system to the new one (change occured with 1.0.1) if(oldversion<=1000001){ @@ -488,7 +488,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion){ } LUtils::writeFile(dset, DS, true); } - + //Check the fluxbox configuration files dset = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/"; if(!QFile::exists(dset+"fluxbox-init")){ @@ -517,7 +517,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion){ int LDesktopUtils::VersionStringToNumber(QString version){ version = version.section("-",0,0); //trim any extra labels off the end int maj, mid, min; //major/middle/minor version numbers (..) - maj = mid = min = 0; + maj = mid = min = 0; bool ok = true; maj = version.section(".",0,0).toInt(&ok); if(ok){ mid = version.section(".",1,1).toInt(&ok); }else{ maj = 0; } -- cgit From 01b8ec846504b1a13b8523048fbe8bc1171a00e4 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Mon, 26 Jun 2017 14:43:47 -0400 Subject: Tag version 1.3.1 in the source tree (no differences from 1.3.0 yet) --- src-qt5/core/libLumina/LDesktopUtils.cpp | 2 +- src-qt5/core/libLumina/NativeWindowSystem.cpp | 48 +++++++++++++-------------- src-qt5/core/libLumina/NativeWindowSystem.h | 12 +++---- 3 files changed, 31 insertions(+), 31 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index caf3c55e..4454d29b 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -16,7 +16,7 @@ static QStringList fav; QString LDesktopUtils::LuminaDesktopVersion(){ - QString ver = "1.3.0"; + QString ver = "1.3.1"; #ifdef GIT_VERSION ver.append( QString(" (Git Revision: %1)").arg(GIT_VERSION) ); #endif diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 36a0b7f0..da7f4404 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -59,14 +59,14 @@ public: //Functions for setting up these objects as needed bool init_ATOMS(){ QStringList atoms; - atoms << "WM_TAKE_FOCUS" << "WM_DELETE_WINDOW" << "WM_PROTOCOLS" - << "WM_CHANGE_STATE" << "_NET_SYSTEM_TRAY_OPCODE" << "_NET_SYSTEM_TRAY_ORIENTATION" + atoms << "WM_TAKE_FOCUS" << "WM_DELETE_WINDOW" << "WM_PROTOCOLS" + << "WM_CHANGE_STATE" << "_NET_SYSTEM_TRAY_OPCODE" << "_NET_SYSTEM_TRAY_ORIENTATION" << "_NET_SYSTEM_TRAY_VISUAL" << QString("_NET_SYSTEM_TRAY_S%1").arg(QString::number(QX11Info::appScreen())); //Create all the requests for the atoms QList reply; for(int i=0; ivisual_id); + ATOMS.value("_NET_SYSTEM_TRAY_VISUAL"), XCB_ATOM_VISUALID, 32, 1, &type->visual_id); }else{ qWarning() << " - Could not set TrueColor visual for system tray"; } - + //Finally, send out an X event letting others know that the system tray is up and running xcb_client_message_event_t event; event.response_type = XCB_CLIENT_MESSAGE; event.format = 32; event.window = root_screen->root; event.type = EWMH.MANAGER; //MANAGER atom - event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; + event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; event.data.data32[1] = _NET_SYSTEM_TRAY_S; //_NET_SYSTEM_TRAY_S atom event.data.data32[2] = tray_window; event.data.data32[3] = 0; @@ -255,7 +255,7 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native if(name.isEmpty()){ //_NET_WM_VISIBLE_NAME xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_visible_name_unchecked(&obj->EWMH, win->id()); - if(cookie.sequence != 0){ + if(cookie.sequence != 0){ xcb_ewmh_get_utf8_strings_reply_t data; if( 1 == xcb_ewmh_get_wm_visible_name_reply(&obj->EWMH, cookie, &data, NULL) ){ name = QString::fromUtf8(data.strings, data.strings_len); @@ -288,7 +288,7 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native if(name.isEmpty()){ //_NET_WM_VISIBLE_ICON_NAME xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_visible_icon_name_unchecked(&obj->EWMH, win->id()); - if(cookie.sequence != 0){ + if(cookie.sequence != 0){ xcb_ewmh_get_utf8_strings_reply_t data; if( 1 == xcb_ewmh_get_wm_visible_icon_name_reply(&obj->EWMH, cookie, &data, NULL) ){ name = QString::fromUtf8(data.strings, data.strings_len); @@ -337,7 +337,7 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native uint* dat = iter.data; //dat+=2; //remember the first 2 element offset for(int i=0; isetProperty(NativeWindow::Icon, icon); } //end ICON property - if(props.contains(NativeWindow::MinSize) || props.contains(NativeWindow::MaxSize) + if(props.contains(NativeWindow::MinSize) || props.contains(NativeWindow::MaxSize) || props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ //Try the ICCCM "Normal Hints" structure first (newer spec?) xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_normal_hints_unchecked(QX11Info::connection(), win->id()); @@ -429,7 +429,7 @@ void NativeWindowSystem::NewWindowDetected(WId id){ XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ XCB_EVENT_MASK_ENTER_WINDOW) - + uint32_t value_list[1] = {NORMAL_WIN_EVENT_MASK}; xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, value_list); //Now go ahead and create/populate the container for this window @@ -457,7 +457,7 @@ void NativeWindowSystem::NewTrayWindowDetected(WId id){ XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ XCB_EVENT_MASK_ENTER_WINDOW) - + uint32_t value_list[1] = {TRAY_WIN_EVENT_MASK}; xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, value_list); //Now go ahead and create/populate the container for this window @@ -478,7 +478,7 @@ void NativeWindowSystem::WindowCloseDetected(WId id){ if(win!=0){ TWindows.removeAll(win); win->emit WindowClosed(id); - win->deleteLater(); + win->deleteLater(); } } } @@ -515,13 +515,13 @@ void NativeWindowSystem::NewMousePress(int buttoncode, WId win){ //Convert the native button code into a Qt mouse button code Qt::MouseButton button; switch(buttoncode){ - case 1: + case 1: button = Qt::LeftButton ; break; - case 2: + case 2: button = Qt::MiddleButton ; break; - case 3: + case 3: button = Qt::RightButton ; break; - case 4: + case 4: button = Qt::LeftButton ; break; default: return; //Unhandled button @@ -534,13 +534,13 @@ void NativeWindowSystem::NewMouseRelease(int buttoncode, WId win){ //Convert the native button code into a Qt mouse button code Qt::MouseButton button; switch(buttoncode){ - case 1: + case 1: button = Qt::LeftButton ; break; - case 2: + case 2: button = Qt::MiddleButton ; break; - case 3: + case 3: button = Qt::RightButton ; break; - case 4: + case 4: button = Qt::LeftButton ; break; default: return; //Unhandled button @@ -564,7 +564,7 @@ void NativeWindowSystem::RequestPropertiesChange(WId win, QListid()){ return NWindows[i]; } + for(int i=0; iid()){ return NWindows[i]; } } return 0; } NativeWindow* findTrayWindow(WId id){ - for(int i=0; iid()){ return TWindows[i]; } + for(int i=0; iid()){ return TWindows[i]; } } return 0; } - //Now define a simple private_objects class so that each implementation + //Now define a simple private_objects class so that each implementation // has a storage container for defining/placing private objects as needed class p_objects; p_objects* obj; @@ -58,7 +58,7 @@ private: } } - // Since some properties may be easier to update in bulk + // Since some properties may be easier to update in bulk // let the native system interaction do them in whatever logical groups are best void UpdateWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props); -- cgit From 79ed54ff31ed654b953d46987851ce4f572245c2 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 08:20:14 -0400 Subject: Another large batch of re-organization for lumina-desktop-unified. This gets the new "NativeWindowSystem" and associated Native* classes all integrated (untested) --- src-qt5/core/libLumina/NativeWindow.h | 8 ++-- src-qt5/core/libLumina/NativeWindow.pri | 6 ++- src-qt5/core/libLumina/NativeWindowSystem.cpp | 56 ++++++++++----------------- src-qt5/core/libLumina/NativeWindowSystem.h | 23 ++++++++--- src-qt5/core/libLumina/RootWindow.cpp | 16 ++++---- src-qt5/core/libLumina/RootWindow.h | 4 +- 6 files changed, 55 insertions(+), 58 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index fbdf9e1b..351462bd 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -5,8 +5,8 @@ // See the LICENSE file for full details //=========================================== // This is a container object for setting/announcing changes -// in a native window's properties. -// The WM will usually run the "setProperty" function on this object, +// in a native window's properties. +// The WM will usually run the "setProperty" function on this object, // and any other classes/widgets which watch this window can act appropriatly after-the-fact // Non-WM classes should use the "Request" signals to ask the WM to do something, and listen for changes later //=========================================== @@ -59,7 +59,7 @@ public: ~NativeWindow(); WId id(); - QWindow* window(); + QWindow* window(); QVariant property(NativeWindow::Property); void setProperty(NativeWindow::Property, QVariant); @@ -89,7 +89,7 @@ signals: void RequestClose(WId); //Close the window void RequestKill(WId); //Kill the window/app (usually from being unresponsive) void RequestPing(WId); //Verify that the window is still active (such as not closing after a request - + // System Tray Icon Embed/Unembed Requests //void RequestEmbed(WId, QWidget*); //void RequestUnEmbed(WId, QWidget*); diff --git a/src-qt5/core/libLumina/NativeWindow.pri b/src-qt5/core/libLumina/NativeWindow.pri index a5715287..b10e472c 100644 --- a/src-qt5/core/libLumina/NativeWindow.pri +++ b/src-qt5/core/libLumina/NativeWindow.pri @@ -4,9 +4,11 @@ QT *= x11extras LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lXdamage SOURCES *= $${PWD}/NativeWindow.cpp \ - $${PWD}/NativeWindowSystem.cpp + $${PWD}/NativeWindowSystem.cpp \ + $${PWD}/NativeEventFilter.cpp HEADERS *= $${PWD}/NativeWindow.h \ - $${PWD}/NativeWindowSystem.h + $${PWD}/NativeWindowSystem.h \ + $${PWD}/NativeEventFilter.h INCLUDEPATH *= $${PWD} diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index da7f4404..49839a69 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -175,6 +175,7 @@ public: NativeWindowSystem::NativeWindowSystem() : QObject(){ obj = 0; pingTimer = 0; + screenLocked = false; } NativeWindowSystem::~NativeWindowSystem(){ @@ -210,6 +211,8 @@ void NativeWindowSystem::stop(){ //Small simplification functions Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ + qDebug() << "Try to convert keycode to Qt::Key:" << keycode; + qDebug() << " - Not implemented yet"; return Qt::Key_unknown; } @@ -410,6 +413,10 @@ void NativeWindowSystem::RegisterVirtualRoot(WId){ } +int NativeWindowSystem::currentWorkspace(){ + return 0; +} + //NativeWindowEventFilter interactions void NativeWindowSystem::NewWindowDetected(WId id){ //Make sure this can be managed first @@ -499,54 +506,29 @@ void NativeWindowSystem::GotPong(WId id){ if(waitingForPong.isEmpty() && pingTimer!=0){ pingTimer->stop(); } } -/*void NativeWindowSystem::NewKeyPress(int keycode, WId win){ +void NativeWindowSystem::NewKeyPress(int keycode, WId win){ emit NewInputEvent(); + if(screenLocked){ return; } + emit KeyPressDetected(win, keycode); } void NativeWindowSystem::NewKeyRelease(int keycode, WId win){ emit NewInputEvent(); - //Convert the native button code into a Qt keycode - //Qt::Key key = keycode; //TODO - //emit KeyReleaseDetected( key, win); + if(screenLocked){ return; } + emit KeyReleaseDetected(win, keycode); } void NativeWindowSystem::NewMousePress(int buttoncode, WId win){ emit NewInputEvent(); - //Convert the native button code into a Qt mouse button code - Qt::MouseButton button; - switch(buttoncode){ - case 1: - button = Qt::LeftButton ; break; - case 2: - button = Qt::MiddleButton ; break; - case 3: - button = Qt::RightButton ; break; - case 4: - button = Qt::LeftButton ; break; - default: - return; //Unhandled button - } - emit MousePressDetected(button, win); + if(screenLocked){ return; } + emit MousePressDetected(win, MouseToQt(buttoncode)); } void NativeWindowSystem::NewMouseRelease(int buttoncode, WId win){ emit NewInputEvent(); - //Convert the native button code into a Qt mouse button code - Qt::MouseButton button; - switch(buttoncode){ - case 1: - button = Qt::LeftButton ; break; - case 2: - button = Qt::MiddleButton ; break; - case 3: - button = Qt::RightButton ; break; - case 4: - button = Qt::LeftButton ; break; - default: - return; //Unhandled button - } - emit MouseReleaseDetected(button, win); -}*/ + if(screenLocked){ return; } + emit MouseReleaseDetected(win, MouseToQt(buttoncode)); +} void NativeWindowSystem::CheckDamageID(WId win){ NativeWindow *WIN = findTrayWindow(win); @@ -564,7 +546,9 @@ void NativeWindowSystem::RequestPropertiesChange(WId win, QList props); + //Generic private variables + bool screenLocked; + public: enum Property{ None, CurrentWorkspace, Workspaces, VirtualRoots, WorkAreas }; enum MouseButton{NoButton, LeftButton, RightButton, MidButton, BackButton, ForwardButton, TaskButton, WheelUp, WheelDown, WheelLeft, WheelRight}; @@ -84,8 +87,16 @@ public: public slots: //These are the slots which are typically only used by the desktop system itself or the NativeWindowEventFilter + //This is called by the lock screen to keep the NWS aware of the current status + // it is **NOT** the function to call for the user to actually lock the session (that is in the screensaver/lockscreen class) + void ScreenLockChanged(bool lock){ + screenLocked = lock; + } + //RootWindow interactions void RegisterVirtualRoot(WId); + // - Workspaces + int currentWorkspace(); //void GoToWorkspace(int); //void RegisterWorkspaces(QStringList); //Names of workspaces, in ascending order //void RegisterKnownInteractions(); @@ -98,10 +109,10 @@ public slots: void WindowPropertyChanged(WId, NativeWindow::Property); //will rescan the window and update the object as needed void GotPong(WId); -/* void NewKeyPress(int keycode, WId win = 0); + void NewKeyPress(int keycode, WId win = 0); void NewKeyRelease(int keycode, WId win = 0); void NewMousePress(int buttoncode, WId win = 0); - void NewMouseRelease(int buttoncode, WId win = 0);*/ + void NewMouseRelease(int buttoncode, WId win = 0); void CheckDamageID(WId); private slots: @@ -115,10 +126,10 @@ signals: void NewWindowAvailable(NativeWindow*); void NewTrayWindowAvailable(NativeWindow*); void NewInputEvent(); //a mouse or keypress was detected (lock-state independent); - void KeyPressDetected(Qt::Key, WId); //only emitted if lockstate = false - void KeyReleaseDetected(Qt::Key, WId); //only emitted if lockstate = false - void MousePressDetected(Qt::MouseButton, WId); //only emitted if lockstate = false - void MouseReleaseDetected(Qt::MouseButton, WId); //only emitted if lockstate = false + void KeyPressDetected(WId, int); //only emitted if lockstate = false + void KeyReleaseDetected(WId, int); //only emitted if lockstate = false + void MousePressDetected(WId, NativeWindowSystem::MouseButton); //only emitted if lockstate = false + void MouseReleaseDetected(WId, NativeWindowSystem::MouseButton); //only emitted if lockstate = false }; diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp index b1f740d3..2586ccc2 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/RootWindow.cpp @@ -51,7 +51,7 @@ void RootWindow::updateScreenPixmap(screeninfo *info){ QPixmap raw(info->file); //load the image from file //Now apply the proper aspect ratio as needed if(info->scale == RootWindow::Stretch || info->scale == RootWindow::Full || info->scale == RootWindow::Fit){ - Qt::AspectRatioMode armode = Qt::KeepAspectRatio; + Qt::AspectRatioMode armode = Qt::KeepAspectRatio; if(info->scale == RootWindow::Stretch ){ armode = Qt::IgnoreAspectRatio; } else if(info->scale == RootWindow::Full ){ armode = Qt::KeepAspectRatioByExpanding; } if(raw.height()!=info->area.height() && raw.width() !=info->area.width()){ @@ -60,16 +60,16 @@ void RootWindow::updateScreenPixmap(screeninfo *info){ } //Now calculate offset and draw width/height QRect drawRect(0,0, raw.width(), raw.height()); - if(info->scale == RootWindow::Full ){ + if(info->scale == RootWindow::Full ){ drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); }else if(info->scale == RootWindow::Fit ){ - drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); + drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); }else if(info->scale == RootWindow::Center ){ - drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); + drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); }else if(info->scale == RootWindow::Tile ){ //Draw the entire area - no offset drawRect.setHeight(info->area.height()); - drawRect.setWidth(info->area.width()); + drawRect.setWidth(info->area.width()); }else if(info->scale == RootWindow::BottomLeft ){ drawRect.moveTo( 0 , info->area.height() - raw.height() ); }else if(info->scale == RootWindow::BottomRight ){ @@ -138,7 +138,7 @@ void RootWindow::ResizeRoot(){ void RootWindow::ChangeWallpaper(QString id, RootWindow::ScaleType scale, QString file){ bool found = false; for(int i=0; iid() == win->id()){ subwin = WINDOWS[i]; } + if(WINDOWS[i]->id() == win->id()){ subwin = WINDOWS[i]; } } if(subwin==0){ subwin = new RootSubWindow(this, win); @@ -181,7 +181,7 @@ void RootWindow::NewWindow(NativeWindow *win){ void RootWindow::CloseWindow(WId win){ for(int i=0; iid() == win){ WINDOWS.takeAt(i)->clientClosed(); break; } + if(WINDOWS[i]->id() == win){ WINDOWS.takeAt(i)->clientClosed(); break; } } } diff --git a/src-qt5/core/libLumina/RootWindow.h b/src-qt5/core/libLumina/RootWindow.h index 0ae248b5..080c4bd1 100644 --- a/src-qt5/core/libLumina/RootWindow.h +++ b/src-qt5/core/libLumina/RootWindow.h @@ -31,7 +31,7 @@ public: RootWindow(); ~RootWindow(); - + void start(); private: @@ -49,7 +49,7 @@ private: //Window Management QList WINDOWS; - + public slots: void ResizeRoot(); void ChangeWallpaper(QString id, RootWindow::ScaleType scale, QString file); -- cgit From 711cf23db3f3e73e82e21ecd22a7ea56aa1c18ca Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 08:26:27 -0400 Subject: Oops - forgot to add the new NativeEventFilter files in the last commit. --- src-qt5/core/libLumina/NativeEventFilter.cpp | 316 +++++++++++++++++++++++++++ src-qt5/core/libLumina/NativeEventFilter.h | 109 +++++++++ 2 files changed, 425 insertions(+) create mode 100644 src-qt5/core/libLumina/NativeEventFilter.cpp create mode 100644 src-qt5/core/libLumina/NativeEventFilter.h (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp new file mode 100644 index 00000000..cc73e222 --- /dev/null +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -0,0 +1,316 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2015-2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "NativeEventFilter.h" +#include +#include + +//#include +//#include + +//================================================== +// NOTE: All the XCB interactions and atoms are accessed via: +// obj->XCB->EWMH.(atom name) +// obj->XCB->(do something) +//================================================== + +/* +List of XCB response types (since almost impossible to find good docs on XCB) +switch (xcb_generic_event_t*->response_type & ~0x80) +case values: +XCB_KEY_[PRESS | RELEASE] +XCB_BUTTON_[PRESS | RELEASE] +XCB_MOTION_NOTIFY +XCB_ENTER_NOTIFY +XCB_LEAVE_NOTIFY +XCB_FOCUS_[IN | OUT] +XCB_KEYMAP_NOTIFY +XCB_EXPOSE +XCB_GRAPHICS_EXPOSURE +XCB_VISIBILITY_NOTIFY +XCB_CREATE_NOTIFY +XCB_DESTROY_NOTIFY +XCB_UNMAP_NOTIFY +XCB_MAP_[NOTIFY | REQUEST] +XCB_REPARENT_NOTIFY +XCB_CONFIGURE_[NOTIFY | REQUEST] +XCB_GRAVITY_NOTIFY +XCB_RESIZE_REQUEST +XCB_CIRCULATE_[NOTIFY | REQUEST] +XCB_PROPERTY_NOTIFY +XCB_SELECTION_[CLEAR | REQUEST | NOTIFY] +XCB_COLORMAP_NOTIFY +XCB_CLIENT_MESSAGE +*/ + +//SYSTEM TRAY STANDARD DEFINITIONS +#define SYSTEM_TRAY_REQUEST_DOCK 0 +#define SYSTEM_TRAY_BEGIN_MESSAGE 1 +#define SYSTEM_TRAY_CANCEL_MESSAGE 2 + +#include +#include +#include + +#define DEBUG 0 + +//Special objects/variables for XCB parsing +static LXCB *XCB = new LXCB(); +static xcb_atom_t _NET_SYSTEM_TRAY_OPCODE = 0; + +inline void ParsePropertyEvent(xcb_property_notify_event_t *ev, NativeEventFilter *obj){ + //qDebug() << "Got Property Event:" << ev->window << ev->atom; + NativeWindow::Property prop = NativeWindow::None; + //Now determine which properties are getting changed, and update the native window as appropriate + if(ev->atom == XCB->EWMH._NET_WM_NAME){ prop = NativeWindow::Title; } + else if(ev->atom == XCB->EWMH._NET_WM_ICON){ prop = NativeWindow::Icon; } + else if(ev->atom == XCB->EWMH._NET_WM_ICON_NAME){ prop = NativeWindow::ShortTitle; } + else if(ev->atom == XCB->EWMH._NET_WM_DESKTOP){ prop = NativeWindow::Workspace; } + else if(ev->atom == XCB->EWMH._NET_WM_WINDOW_TYPE ){ prop = NativeWindow::WinTypes; } + else if( ev->atom == XCB->EWMH._NET_WM_STATE){ prop = NativeWindow::States; } + //Send out the signal if necessary + if(prop!=NativeWindow::None){ + obj->emit WindowPropertyChanged(ev->window, prop); + } +} + + +//Constructor for the Event Filter wrapper +NativeEventFilter::NativeEventFilter() : QObject(){ + EF = new EventFilter(this); + if(_NET_SYSTEM_TRAY_OPCODE==0){ + //_NET_SYSTEM_TRAY_OPCODE + xcb_intern_atom_cookie_t cookie = xcb_intern_atom(QX11Info::connection(), 0, 23,"_NET_SYSTEM_TRAY_OPCODE"); + xcb_intern_atom_reply_t *r = xcb_intern_atom_reply(QX11Info::connection(), cookie, NULL); + if(r){ + _NET_SYSTEM_TRAY_OPCODE = r->atom; + free(r); + } + } +} + +void NativeEventFilter::start(){ + if(DEBUG){ qDebug() << " - Install event filter..."; } + QCoreApplication::instance()->installNativeEventFilter(EF); + if(DEBUG){ qDebug() << " - Run request check..."; } + +} + +void NativeEventFilter::stop(){ + QCoreApplication::instance()->installNativeEventFilter(0); +} + +//============================= +// EventFilter Class +//============================= + +//Constructor for the XCB event filter +EventFilter::EventFilter(NativeEventFilter *parent) : QAbstractNativeEventFilter(){ + obj = parent; +} + +//This function format taken directly from the Qt5.3 documentation +bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *){ + //qDebug() << "New Event"; + if(eventType=="xcb_generic_event_t"){ + //Convert to known event type (for X11 systems) + xcb_generic_event_t *ev = static_cast(message); + //Now parse the event and emit signals as necessary + switch( ev->response_type & ~0x80){ +//============================== +// INTERACTIVITY EVENTS +//============================== + case XCB_KEY_PRESS: + //This is a keyboard key press + //qDebug() << "Key Press Event" + obj->emit KeyPressed( ((xcb_key_press_event_t *) ev)->detail, ((xcb_key_press_event_t *) ev)->root ); + break; + case XCB_KEY_RELEASE: + //This is a keyboard key release + //qDebug() << "Key Release Event"; + obj->emit KeyReleased( ((xcb_key_release_event_t *) ev)->detail, ((xcb_key_release_event_t *) ev)->root ); + break; + case XCB_BUTTON_PRESS: + //This is a mouse button press + //qDebug() << "Button Press Event"; + obj->emit MousePressed( ((xcb_button_press_event_t *) ev)->detail, ((xcb_button_press_event_t *) ev)->root ); + break; + case XCB_BUTTON_RELEASE: + //This is a mouse button release + //qDebug() << "Button Release Event"; + obj->emit MouseReleased( ((xcb_button_release_event_t *) ev)->detail, ((xcb_button_release_event_t *) ev)->root ); + break; + case XCB_MOTION_NOTIFY: + //This is a mouse movement event + //qDebug() << "Motion Notify Event"; + obj->emit MouseMovement(); + break; + case XCB_ENTER_NOTIFY: + //This is a mouse movement event when mouse goes over a new window + //qDebug() << "Enter Notify Event"; + obj->emit MouseEnterWindow( ((xcb_enter_notify_event_t *) ev)->root ); + break; + case XCB_LEAVE_NOTIFY: + //This is a mouse movement event when mouse goes leaves a window + //qDebug() << "Leave Notify Event"; + obj->emit MouseLeaveWindow( ((xcb_leave_notify_event_t *) ev)->root ); + break; +//============================== + case XCB_EXPOSE: + //qDebug() << "Expose Notify Event:"; + //qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window; + break; +//============================== + case XCB_MAP_NOTIFY: + //qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; + /*if(Lumina::SS->isLocked()){ waitingToShow << ((xcb_map_notify_event_t *)ev)->window ; } + else{ + for(int i=0; iid() == ((xcb_map_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, true); break; } + } + }*/ + obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible ); + break; //This is just a notification that a window was mapped - nothing needs to change here + case XCB_MAP_REQUEST: + //qDebug() << "Window Map Request Event"; + obj->emit WindowCreated( ((xcb_map_request_event_t *) ev)->window ); + //SetupNewWindow( ); + break; +//============================== + case XCB_CREATE_NOTIFY: + //qDebug() << "Window Create Event"; + break; +//============================== + case XCB_UNMAP_NOTIFY: + //qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; + /*if(waitingToShow.contains(((xcb_unmap_notify_event_t *)ev)->window)){ waitingToShow.removeAll(((xcb_unmap_notify_event_t *)ev)->window); } + for(int i=0; iid() == ((xcb_unmap_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, false); break; } + }*/ + obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible ); + break; +//============================== + case XCB_DESTROY_NOTIFY: + //qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; + obj->emit WindowDestroyed( ((xcb_destroy_notify_event_t *) ev)->window ); + /*if( !rmTrayApp( ((xcb_destroy_notify_event_t *) ev)->window ) ){ + //qDebug() <<" - Non-tray window"; + for(int i=0; iid() == ((xcb_destroy_notify_event_t *)ev)->window){ + windows[i]->emit WindowClosed(windows[i]->id()); + QTimer::singleShot(500, windows.takeAt(i), SLOT(deleteLater()) ); //give a few moments first, then clean up the object + break; + } + } + }*/ + break; +//============================== + case XCB_FOCUS_IN: + //qDebug() << "Focus In Event:"; + break; +//============================== + case XCB_FOCUS_OUT: + //qDebug() << "Focus Out Event:"; + break; +//============================== + case XCB_PROPERTY_NOTIFY: + //qDebug() << "Property Notify Event:"; + ParsePropertyEvent((xcb_property_notify_event_t*)ev, obj); + break; +//============================== + case XCB_CLIENT_MESSAGE: + //qDebug() << "Client Message Event"; + //qDebug() << " - Given Window:" << ((xcb_client_message_event_t*)ev)->window; + if( ((xcb_client_message_event_t*)ev)->type == _NET_SYSTEM_TRAY_OPCODE && ((xcb_client_message_event_t*)ev)->format == 32){ + //data32[0] is timestamp, [1] is opcode, [2] is window handle + if(SYSTEM_TRAY_REQUEST_DOCK == ((xcb_client_message_event_t*)ev)->data.data32[1]){ + obj->emit TrayWindowCreated( ((xcb_client_message_event_t*)ev)->data.data32[2] ); + //addTrayApp( ((xcb_client_message_event_t*)ev)->data.data32[2] ); + } + //Ignore the System Tray messages at the moment + } + break; +//============================== + case XCB_CONFIGURE_NOTIFY: + //qDebug() << "Configure Notify Event"; + break; +//============================== + case XCB_CONFIGURE_REQUEST: + //qDebug() << "Configure Request Event"; + break; +//============================== + case XCB_SELECTION_CLEAR: + //qDebug() << "Selection Clear Event"; + break; +//============================== + case 85: //not sure what event this is - but it seems to come up very often (just hide the notice) + case 0: + case XCB_GE_GENERIC: + break; //generic event - don't do anything special + default: + //if( (ev->response_type & ~0x80)==TrayDmgID){ + obj->emit PossibleDamageEvent( ((xcb_damage_notify_event_t*)ev)->drawable ); + //checkDamageID( ((xcb_damage_notify_event_t*)ev)->drawable ); + //}else{ + qDebug() << "Default Event:" << (ev->response_type & ~0x80); + //} +//============================== + } + } + return false; + //never stop event handling (this will not impact the X events themselves - just the internal Qt application) +} + + +//========= +// PRIVATE +//========= + + +// WINDOW HANDLING FUNCTIONS +/*void EventFilter::SetupNewWindow(xcb_map_request_event_t *ev){ + WId win = ev->window; + + bool ok = obj->XCB->WM_ManageWindow(win, true); + //Quick check if this is a transient window if we could not manage it directly + if(!ok){ + WId tran = obj->XCB->WM_ICCCM_GetTransientFor(win); + if(tran!=win && tran!=0){ + win = tran; + ok = obj->XCB->WM_ManageWindow(win); + } + } + qDebug() << "New Window:" << win << obj->XCB->WM_ICCCM_GetClass(win) << " Managed:" << ok; + obj->XCB->WM_Set_Active_Window(win); + //Determing the requested geometry/location/management within the event, + NativeWindow *nwin = new NativeWindow(win); + QObject::connect(nwin, SIGNAL(RequestClose(WId)), obj, SLOT(TryCloseWindow(WId)) ); + QObject::connect(nwin, SIGNAL(RequestActivate(WId)), obj, SLOT(TryActivateWindow(WId)) ); + windows << nwin; + bool show_now = !Lumina::SS->isLocked(); + if(!show_now){ waitingToShow << win; } //add to the list to get set visible later + //populate the native window settings as they are right now + nwin->setProperty(NativeWindow::Active, true); + nwin->setProperty(NativeWindow::Visible, show_now); + nwin->setProperty(NativeWindow::Workspace, obj->XCB->CurrentWorkspace()); + icccm_size_hints hints = obj->XCB->WM_ICCCM_GetNormalHints(win); + if(!hints.isValid()){ hints = obj->XCB->WM_ICCCM_GetSizeHints(win); } + if(hints.validMinSize()){ nwin->setProperty(NativeWindow::MinSize, QSize(hints.min_width,hints.min_height)); } + if(hints.validMaxSize()){ nwin->setProperty(NativeWindow::MaxSize, QSize(hints.max_width,hints.max_height)); } + if(hints.validBaseSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.base_width,hints.base_height)); } + else if(hints.validSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.width, hints.height)); } + nwin->setProperty(NativeWindow::Icon, obj->XCB->WM_Get_Icon(win)); + QString title = obj->XCB->WM_Get_Name(win); + if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Name(win); } + if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetName(win); } + nwin->setProperty(NativeWindow::Title, title); + title = obj->XCB->WM_Get_Icon_Name(win); + if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Icon_Name(win); } + if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetIconName(win); } + nwin->setProperty(NativeWindow::ShortTitle, title); + + obj->emit WindowCreated(nwin); +}*/ diff --git a/src-qt5/core/libLumina/NativeEventFilter.h b/src-qt5/core/libLumina/NativeEventFilter.h new file mode 100644 index 00000000..2d5fbc61 --- /dev/null +++ b/src-qt5/core/libLumina/NativeEventFilter.h @@ -0,0 +1,109 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2012-2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This class provides the XCB event handling/registrations that are needed +//=========================================== +#ifndef _LUMINA_DESKTOP_NATIVE_EVENT_FILTER_H +#define _LUMINA_DESKTOP_NATIVE_EVENT_FILTER_H + +#include +#include +#include + +#include "NativeWindow.h" + + +class NativeEventFilter : public QObject{ + Q_OBJECT +private: + QAbstractNativeEventFilter* EF; + WId WMFlag; //used to flag a running WM process + +public: + NativeEventFilter(); + ~NativeEventFilter(){} + + void start(); + void stop(); + +signals: + //Window Signals + void WindowCreated(WId); + void WindowDestroyed(WId); + void WindowPropertyChanged(WId, NativeWindow::Property); + + //System Tray Signals + void TrayWindowCreated(WId); + void TrayWindowDestroyed(WId); + + //Miscellaneos Signals + void PossibleDamageEvent(WId); + + //Input Event Signals + void KeyPressed(int, WId); + void KeyReleased(int, WId); + void MousePressed(int, WId); + void MouseReleased(int, WId); + void MouseMovement(); + void MouseEnterWindow(WId); + void MouseLeaveWindow(WId); +}; + +class EventFilter : public QAbstractNativeEventFilter{ +public: + EventFilter(NativeEventFilter *parent); + ~EventFilter(){} + + virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *); + + //System Tray Functions + //QList trayApps(); //return the list of all current tray apps + //bool startSystemTray(); + //bool stopSystemTray(); + + //Window List Functions + //QList windowList(); + +private: + NativeEventFilter *obj; + /*QList WinNotifyAtoms, SysNotifyAtoms; + xcb_atom_t _NET_SYSTEM_TRAY_OPCODE; + void InitAtoms(); + + bool BlockInputEvent(WId win = 0); //Checks the current state of the system to see if the event should be stopped + WId InputWindow(WId win = 0); //Checks the window ID and determines if this is an external window or returns 0 (for desktop/root windows) + Lumina::MouseButton MouseKey(int keycode); //convert the keycode into the mouse button code + + //System Tray Variables + WId SystemTrayID; + int TrayDmgID; + QList RunningTrayApps; + //System Tray functions + void addTrayApp(WId); + bool rmTrayApp(WId); //returns "true" if the tray app was found and removed + void checkDamageID(WId); + + //Window List Variables + QList windows; + QList waitingToShow; + + //Longer Event handling functions + void SetupNewWindow(xcb_map_request_event_t *ev); + + //bool ParseKeyPressEvent(); + //bool ParseKeyReleaseEvent(); + //bool ParseButtonPressEvent(); + //bool ParseButtonReleaseEvent(); + //bool ParseMotionEvent(); + void ParsePropertyEvent(xcb_property_notify_event_t *ev); + //bool ParseClientMessageEvent(); + //bool ParseDestroyEvent(); + //bool ParseConfigureEvent(); + //bool ParseKeySelectionClearEvent(); + */ +}; + +#endif -- cgit From 6444a12d81b3a2539e9c86dc4fe2117fbe49489e Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 09:37:10 -0400 Subject: Fix a bug in the initialization routine of NativeEventFilter --- src-qt5/core/libLumina/NativeEventFilter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp index cc73e222..537d54aa 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -58,7 +58,7 @@ XCB_CLIENT_MESSAGE #define DEBUG 0 //Special objects/variables for XCB parsing -static LXCB *XCB = new LXCB(); +static LXCB *XCB = 0; static xcb_atom_t _NET_SYSTEM_TRAY_OPCODE = 0; inline void ParsePropertyEvent(xcb_property_notify_event_t *ev, NativeEventFilter *obj){ @@ -90,6 +90,7 @@ NativeEventFilter::NativeEventFilter() : QObject(){ free(r); } } + if(XCB==0){ XCB = new LXCB(); } } void NativeEventFilter::start(){ -- cgit From 3285fabf539aa136c20fba6902d3927f684b901b Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 10:06:00 -0400 Subject: Add some more debugging. --- src-qt5/core/libLumina/RootSubWindow.cpp | 30 ++++++++++++++++-------------- src-qt5/core/libLumina/RootWindow.cpp | 3 ++- 2 files changed, 18 insertions(+), 15 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 41c04ee1..d00a3a75 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -41,34 +41,34 @@ RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset //above the frame itself - need to figure out which quadrant it is in (8-directions) if(pt.y() < WIN_BORDER){ //One of the top options - if(pt.x() < WIN_BORDER){ + if(pt.x() < WIN_BORDER){ if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()); } //difference from top-left corner return ResizeTopLeft; - }else if(pt.x() > (this->width()-WIN_BORDER)){ + }else if(pt.x() > (this->width()-WIN_BORDER)){ if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(pt.y()); } //difference from top-right corner return ResizeTopRight; - }else{ + }else{ if(setoffset){ offset.setX(0); offset.setY(pt.y()); } //difference from top edge (X does not matter) - return ResizeTop; - } + return ResizeTop; + } }else if(pt.y() > (this->height()-WIN_BORDER) ){ //One of the bottom options - if(pt.x() < WIN_BORDER){ + if(pt.x() < WIN_BORDER){ if(setoffset){ offset.setX(pt.x()); offset.setY(this->height()-pt.y()); } //difference from bottom-left corner return ResizeBottomLeft; - }else if(pt.x() > (this->width()-WIN_BORDER)){ + }else if(pt.x() > (this->width()-WIN_BORDER)){ if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(this->height()-pt.y()); } //difference from bottom-right corner return ResizeBottomRight; - }else{ + }else{ if(setoffset){ offset.setX(0); offset.setY(this->height() - pt.y()); } //difference from bottom edge (X does not matter) - return ResizeBottom; - } + return ResizeBottom; + } }else{ //One of the side options - if(pt.x() < WIN_BORDER){ + if(pt.x() < WIN_BORDER){ if(setoffset){ offset.setX(pt.x()); offset.setY(0); } //difference from left edge (Y does not matter) return ResizeLeft; - }else if(pt.x() > (this->width()-WIN_BORDER) ){ + }else if(pt.x() > (this->width()-WIN_BORDER) ){ if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(0); } //difference from right edge (Y does not matter) return ResizeRight; }else{ @@ -112,7 +112,7 @@ void RootSubWindow::setMouseCursor(ModState state, bool override){ break; case ResizeTopLeft: shape = Qt::SizeFDiagCursor; - break; + break; } if(override){ QApplication::setOverrideCursor(QCursor(shape)); @@ -123,6 +123,7 @@ void RootSubWindow::setMouseCursor(ModState state, bool override){ } void RootSubWindow::initWindowFrame(){ + qDebug() << "Create RootSubWindow Frame"; mainLayout = new QVBoxLayout(this); titleBar = new QHBoxLayout(this); closeB = new QToolButton(this); @@ -139,7 +140,6 @@ void RootSubWindow::initWindowFrame(){ connect(maxB, SIGNAL(clicked()), this, SLOT(toggleMaximize()) ); connect(minB, SIGNAL(clicked()), this, SLOT(toggleMinimize()) ); //Now assemble the frame layout based on the current settings - this->setLayout(mainLayout); titleBar->addWidget(otherB); titleBar->addWidget(titleLabel); titleBar->addWidget(minB); @@ -161,6 +161,8 @@ void RootSubWindow::initWindowFrame(){ mainLayout->setSpacing(0); titleBar->setSpacing(1); titleBar->setContentsMargins(0,0,0,0); + this->setLayout(mainLayout); + qDebug() << " - Done"; } void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp index 2586ccc2..f7b73eac 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/RootWindow.cpp @@ -168,6 +168,7 @@ void RootWindow::ChangeWallpaper(QString id, RootWindow::ScaleType scale, QStrin void RootWindow::NewWindow(NativeWindow *win){ RootSubWindow *subwin = 0; + qDebug() << "Got New Window:" << win->property(NativeWindow::Title); for(int i=0; iid() == win->id()){ subwin = WINDOWS[i]; } } @@ -176,7 +177,7 @@ void RootWindow::NewWindow(NativeWindow *win){ connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(CloseWindow(WId)) ); WINDOWS << subwin; } - //subwin->show(); + subwin->show(); } void RootWindow::CloseWindow(WId win){ -- cgit From 91c9e6f4c7b5aad491d5f8fdd892e038b2cd9656 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 10:21:41 -0400 Subject: Start working on the RootSubWindow interactions. --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 5 +++-- src-qt5/core/libLumina/RootSubWindow.cpp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 49839a69..d25d441f 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -408,7 +408,7 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native // === PUBLIC SLOTS === -//These are the slots which are only used by the desktop system itself or the NativeWindowEventFilter +//These are the slots which are only used by the desktop system itself or the NativeEventFilter void NativeWindowSystem::RegisterVirtualRoot(WId){ } @@ -476,6 +476,7 @@ void NativeWindowSystem::NewTrayWindowDetected(WId id){ void NativeWindowSystem::WindowCloseDetected(WId id){ NativeWindow *win = findWindow(id); + qDebug() << "Got Window Closed" << id << win; if(win!=0){ NWindows.removeAll(win); win->emit WindowClosed(id); @@ -491,7 +492,7 @@ void NativeWindowSystem::WindowCloseDetected(WId id){ } void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop){ - //NOTE: This is triggered by the NativeWindowEventFilter - not by changes to the NativeWindow objects themselves + //NOTE: This is triggered by the NativeEventFilter - not by changes to the NativeWindow objects themselves NativeWindow *win = findWindow(id); if(win==0){ win = findTrayWindow(id); } if(win!=0){ diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index d00a3a75..3c8e5b97 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -155,7 +155,7 @@ void RootSubWindow::initWindowFrame(){ maxB->setObjectName("Button_Maximize"); otherM->setObjectName("Menu_Actions"); titleLabel->setObjectName("Label_Title"); - this->setStyleSheet("QWidget#WindowFrame{background-color: darkblue;} QWidget#Label_Title{background-color: transparent; color: white; }"); + this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; }"); //And adjust the margins mainLayout->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); mainLayout->setSpacing(0); @@ -227,7 +227,7 @@ void RootSubWindow::startResizing(){ void RootSubWindow::propertiesChanged(QList props, QList vals){ for(int i=0; ishow(); } -- cgit From 42ccfd08274e4ebb8a8b8a22ec329bcf5abb6684 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 10:48:21 -0400 Subject: Another couple minor changes - trying to track down some missing events. --- src-qt5/core/libLumina/NativeWindowSystem.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h index eb01a460..631b8cb2 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/core/libLumina/NativeWindowSystem.h @@ -23,7 +23,9 @@ private: //Simplifications to find an already-created window object NativeWindow* findWindow(WId id){ + qDebug() << "Find Window:" << id; for(int i=0; iid(); if(id==NWindows[i]->id()){ return NWindows[i]; } } return 0; -- cgit From 5de759a52a3339741bff176d47efb9d9399d7c0d Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 12:21:43 -0400 Subject: Commit some more debugging and changes to the event systems for Lumina2. --- src-qt5/core/libLumina/NativeEventFilter.cpp | 35 ++++++---------------------- src-qt5/core/libLumina/NativeWindow.cpp | 8 +++++++ src-qt5/core/libLumina/NativeWindow.h | 4 ++++ src-qt5/core/libLumina/NativeWindowSystem.h | 5 ++-- src-qt5/core/libLumina/RootSubWindow.cpp | 9 +++---- 5 files changed, 27 insertions(+), 34 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp index 537d54aa..4914cea3 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -146,7 +146,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, break; case XCB_MOTION_NOTIFY: //This is a mouse movement event - //qDebug() << "Motion Notify Event"; + qDebug() << "Motion Notify Event"; obj->emit MouseMovement(); break; case XCB_ENTER_NOTIFY: @@ -166,47 +166,26 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, break; //============================== case XCB_MAP_NOTIFY: - //qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; - /*if(Lumina::SS->isLocked()){ waitingToShow << ((xcb_map_notify_event_t *)ev)->window ; } - else{ - for(int i=0; iid() == ((xcb_map_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, true); break; } - } - }*/ + qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible ); break; //This is just a notification that a window was mapped - nothing needs to change here case XCB_MAP_REQUEST: - //qDebug() << "Window Map Request Event"; + qDebug() << "Window Map Request Event"; obj->emit WindowCreated( ((xcb_map_request_event_t *) ev)->window ); - //SetupNewWindow( ); break; //============================== case XCB_CREATE_NOTIFY: - //qDebug() << "Window Create Event"; + qDebug() << "Window Create Event"; break; //============================== case XCB_UNMAP_NOTIFY: - //qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; - /*if(waitingToShow.contains(((xcb_unmap_notify_event_t *)ev)->window)){ waitingToShow.removeAll(((xcb_unmap_notify_event_t *)ev)->window); } - for(int i=0; iid() == ((xcb_unmap_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, false); break; } - }*/ + qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible ); break; //============================== case XCB_DESTROY_NOTIFY: - //qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; + qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; obj->emit WindowDestroyed( ((xcb_destroy_notify_event_t *) ev)->window ); - /*if( !rmTrayApp( ((xcb_destroy_notify_event_t *) ev)->window ) ){ - //qDebug() <<" - Non-tray window"; - for(int i=0; iid() == ((xcb_destroy_notify_event_t *)ev)->window){ - windows[i]->emit WindowClosed(windows[i]->id()); - QTimer::singleShot(500, windows.takeAt(i), SLOT(deleteLater()) ); //give a few moments first, then clean up the object - break; - } - } - }*/ break; //============================== case XCB_FOCUS_IN: @@ -218,7 +197,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, break; //============================== case XCB_PROPERTY_NOTIFY: - //qDebug() << "Property Notify Event:"; + qDebug() << "Property Notify Event:"; ParsePropertyEvent((xcb_property_notify_event_t*)ev, obj); break; //============================== diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index 97131b52..020e4596 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -17,6 +17,14 @@ NativeWindow::~NativeWindow(){ //WIN->deleteLater(); //This class only deals with Native windows which were created outside the app - they need to be cleaned up outside the app too } +void NativeWindow::addFrameWinID(WId fid){ + relatedTo << fid; +} + +bool NativeWindow::isRelatedTo(WId tmp){ + return (relatedTo.contains(tmp) || winid == tmp); +} + WId NativeWindow::id(){ return winid; } diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index 351462bd..a3efd234 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -58,6 +58,9 @@ public: NativeWindow(WId id); ~NativeWindow(); + void addFrameWinID(WId); + bool isRelatedTo(WId); + WId id(); QWindow* window(); @@ -76,6 +79,7 @@ private: QHash hash; QWindow *WIN; WId winid; + QList relatedTo; signals: //General Notifications diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h index 631b8cb2..c82c70fd 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/core/libLumina/NativeWindowSystem.h @@ -14,6 +14,7 @@ #include "NativeWindow.h" #include #include +#include class NativeWindowSystem : public QObject{ Q_OBJECT @@ -26,14 +27,14 @@ private: qDebug() << "Find Window:" << id; for(int i=0; iid(); - if(id==NWindows[i]->id()){ return NWindows[i]; } + if(NWindows[i]->isRelatedTo(id)){ qDebug() << " -- Got Match!"; return NWindows[i]; } } return 0; } NativeWindow* findTrayWindow(WId id){ for(int i=0; iid()){ return TWindows[i]; } + if(TWindows[i]->isRelatedTo(id)){ return TWindows[i]; } } return 0; } diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 3c8e5b97..fdb9ac76 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -10,7 +10,7 @@ #include #include -#define WIN_BORDER 3 +#define WIN_BORDER 5 // === PUBLIC === RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ @@ -24,6 +24,7 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ LoadProperties( NativeWindow::allProperties() ); //Hookup the signals/slots connect(WIN, SIGNAL(PropertiesChanged(QList, QList)), this, SLOT(propertiesChanged(QList, QList))); + WIN->addFrameWinID(this->winId()); } RootSubWindow::~RootSubWindow(){ @@ -123,7 +124,7 @@ void RootSubWindow::setMouseCursor(ModState state, bool override){ } void RootSubWindow::initWindowFrame(){ - qDebug() << "Create RootSubWindow Frame"; + //qDebug() << "Create RootSubWindow Frame"; mainLayout = new QVBoxLayout(this); titleBar = new QHBoxLayout(this); closeB = new QToolButton(this); @@ -161,8 +162,8 @@ void RootSubWindow::initWindowFrame(){ mainLayout->setSpacing(0); titleBar->setSpacing(1); titleBar->setContentsMargins(0,0,0,0); - this->setLayout(mainLayout); - qDebug() << " - Done"; + //this->setLayout(mainLayout); + //qDebug() << " - Done"; } void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ -- cgit From 4caf7b5e15bf8989b26091cd6981215bb0cfa8fd Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 13:04:18 -0400 Subject: Add a ton of the root-window registration routines to the NativeWindowSystem class. --- src-qt5/core/libLumina/LuminaX11.cpp | 6 +- src-qt5/core/libLumina/NativeWindowSystem.cpp | 110 ++++++++++++++++++++++++-- src-qt5/core/libLumina/NativeWindowSystem.h | 12 ++- 3 files changed, 117 insertions(+), 11 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaX11.cpp b/src-qt5/core/libLumina/LuminaX11.cpp index ab6cd880..3bd248b6 100644 --- a/src-qt5/core/libLumina/LuminaX11.cpp +++ b/src-qt5/core/libLumina/LuminaX11.cpp @@ -1514,7 +1514,7 @@ void LXCB::WM_Set_Client_List(QList list, bool 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); - } + } } @@ -1528,7 +1528,7 @@ unsigned int LXCB::WM_Get_Number_Desktops(){ } void LXCB::WM_SetNumber_Desktops(unsigned int number){ - //NOTE: number should be at least 1 + //NOTE: number should be at least 1 xcb_ewmh_set_number_of_desktops(&EWMH, QX11Info::appScreen(), number); } @@ -1555,7 +1555,7 @@ QList LXCB::WM_Get_Desktop_Viewport(){ 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; } diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index d25d441f..4b9c9e62 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -98,7 +98,7 @@ public: xcb_ewmh_set_supporting_wm_check(&EWMH, wm_window, wm_window); //Now also setup the root event mask on the wm_window status = xcb_request_check( QX11Info::connection(), xcb_change_window_attributes_checked(QX11Info::connection(), wm_window, XCB_CW_EVENT_MASK, value_list)); - if(status!=0){ return false; } + if(status!=0){ return false; } return true; } @@ -201,7 +201,10 @@ bool NativeWindowSystem::start(){ if( !obj->init_ATOMS() ){ return false; } } //Done with private object init bool ok = obj->register_wm(); - if(ok){ ok = obj->start_system_tray(); } + if(ok){ + setRoot_supportedActions(); + ok = obj->start_system_tray(); + } return ok; } @@ -408,13 +411,110 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native // === PUBLIC SLOTS === -//These are the slots which are only used by the desktop system itself or the NativeEventFilter -void NativeWindowSystem::RegisterVirtualRoot(WId){ +//These are the slots which are typically only used by the desktop system itself or the NativeEventFilter +void NativeWindowSystem::RegisterVirtualRoot(WId id){ + //Convert to XCB array + xcb_window_t array[1]; + array[0] = id; + //Set the property + xcb_ewmh_set_virtual_roots(&obj->EWMH, QX11Info::appScreen(), 1, array); +} + +void NativeWindowSystem::setRoot_supportedActions(){ +//NET_WM standards (ICCCM implied - no standard way to list those) + xcb_atom_t list[] = {obj->EWMH._NET_WM_NAME, + obj->EWMH._NET_WM_ICON, + obj->EWMH._NET_WM_ICON_NAME, + obj->EWMH._NET_WM_DESKTOP, + /*_NET_WINDOW_TYPE (and all the various types)*/ + obj->EWMH._NET_WM_WINDOW_TYPE, obj->EWMH._NET_WM_WINDOW_TYPE_DESKTOP, obj->EWMH._NET_WM_WINDOW_TYPE_DOCK, + obj->EWMH._NET_WM_WINDOW_TYPE_TOOLBAR, obj->EWMH._NET_WM_WINDOW_TYPE_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_UTILITY, + obj->EWMH._NET_WM_WINDOW_TYPE_SPLASH, obj->EWMH._NET_WM_WINDOW_TYPE_DIALOG, obj->EWMH._NET_WM_WINDOW_TYPE_NORMAL, + obj->EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_TOOLTIP, + obj->EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION, obj->EWMH._NET_WM_WINDOW_TYPE_COMBO, obj->EWMH._NET_WM_WINDOW_TYPE_DND, + }; + xcb_ewmh_set_supported(&obj->EWMH, QX11Info::appScreen(), 0,list); +} + +void NativeWindowSystem::setRoot_numberOfWorkspaces(QStringList names){ + if(names.isEmpty()){ names << "one"; } + //First set the overall number of workspaces + xcb_ewmh_set_number_of_desktops(&obj->EWMH, QX11Info::appScreen(), names.length()); + //Now set the names for the workspaces + //EWMH LIBRARY BROKEN - appears to be a mismatch in the function header (looking for a single char array, instead of a list of char arrays) + // Ken Moore - 6/27/17 + /* + char *array[ names.length() ]; + for(int i=0; iEWMH, QX11Info::appScreen(), names.length(), array); + */ +} + +void NativeWindowSystem::setRoot_currentWorkspace(int num){ + xcb_ewmh_set_current_desktop(&obj->EWMH, QX11Info::appScreen(), num); +} + +void NativeWindowSystem::setRoot_clientList(QList list, bool stackorder){ + //convert the QList into a generic array + xcb_window_t array[list.length()]; + for(int i=0; iEWMH, QX11Info::appScreen(), list.length(), array); + }else{ + xcb_ewmh_set_client_list(&obj->EWMH, QX11Info::appScreen(), list.length(), array); + } +} + +void NativeWindowSystem::setRoot_desktopGeometry(QRect geom){ + //This one is a combo function + // This will set the "DESKTOP_VIEWPORT" property (point) + // as well as the "DESKTOP_GEOMETRY" property (size) + //Turn the QList into xcb_ewmh_coordinates_t* + xcb_ewmh_coordinates_t array[1]; + array[0].x=geom.x(); array[0].y=geom.y(); + //Now set the property + xcb_ewmh_set_desktop_viewport(&obj->EWMH, QX11Info::appScreen(), 1, array); + xcb_ewmh_set_desktop_geometry(&obj->EWMH, QX11Info::appScreen(), geom.width(), geom.height()); +} +void NativeWindowSystem::setRoot_desktopWorkarea(QList list){ + //Convert to the XCB/EWMH data structures + xcb_ewmh_geometry_t array[list.length()]; + for(int i=0; iEWMH, QX11Info::appScreen(), list.length(), array); +} + +void NativeWindowSystem::setRoot_activeWindow(WId win){ + xcb_ewmh_set_active_window(&obj->EWMH, QX11Info::appScreen(), win); + //Also send the active window a message to take input focus + //Send the window a WM_TAKE_FOCUS message + xcb_client_message_event_t event; + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.window = win; + event.type = obj->ATOMS["WM_PROTOCOLS"]; + event.data.data32[0] = obj->ATOMS["WM_TAKE_FOCUS"]; + event.data.data32[1] = XCB_TIME_CURRENT_TIME; //CurrentTime; + event.data.data32[2] = 0; + event.data.data32[3] = 0; + event.data.data32[4] = 0; + + xcb_send_event(QX11Info::connection(), 0, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); + xcb_flush(QX11Info::connection()); } int NativeWindowSystem::currentWorkspace(){ - return 0; + xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop_unchecked(&obj->EWMH, QX11Info::appScreen()); + uint32_t num = 0; + if(1==xcb_ewmh_get_current_desktop_reply(&obj->EWMH, cookie, &num, NULL) ){ + return num; + }else{ + return 0; + } } //NativeWindowEventFilter interactions diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h index c82c70fd..53abd633 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/core/libLumina/NativeWindowSystem.h @@ -96,13 +96,19 @@ public slots: screenLocked = lock; } - //RootWindow interactions + //Root Window property registrations void RegisterVirtualRoot(WId); + void setRoot_supportedActions(); + void setRoot_numberOfWorkspaces(QStringList names); + void setRoot_currentWorkspace(int); + void setRoot_clientList(QList, bool stackorder = false); + void setRoot_desktopGeometry(QRect); + void setRoot_desktopWorkarea(QList); + void setRoot_activeWindow(WId); + // - Workspaces int currentWorkspace(); //void GoToWorkspace(int); - //void RegisterWorkspaces(QStringList); //Names of workspaces, in ascending order - //void RegisterKnownInteractions(); //NativeWindowEventFilter interactions -- cgit From cd5553238538bb4dc62aee43a5e1a0cd9c070e68 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 13:18:55 -0400 Subject: Commit a bunch more root-level session changes - should be almost ready to start testing and see if windows respond to the EWMH hints. --- src-qt5/core/libLumina/LuminaX11.cpp | 7 ++----- src-qt5/core/libLumina/NativeEventFilter.cpp | 26 +++++++++++++++++--------- src-qt5/core/libLumina/RootWindow.cpp | 2 +- src-qt5/core/libLumina/RootWindow.h | 2 +- 4 files changed, 21 insertions(+), 16 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaX11.cpp b/src-qt5/core/libLumina/LuminaX11.cpp index 3bd248b6..b5dd62cd 100644 --- a/src-qt5/core/libLumina/LuminaX11.cpp +++ b/src-qt5/core/libLumina/LuminaX11.cpp @@ -75,9 +75,6 @@ void LXCB::createWMAtoms(){ i--; } } - - - } // === WindowList() === @@ -91,13 +88,13 @@ QList LXCB::WindowList(bool rawlist){ if( 1 == xcb_ewmh_get_client_list_reply( &EWMH, cookie, &winlist, NULL) ){ //qDebug() << " - Loop over items"; unsigned int wkspace = CurrentWorkspace(); - for(unsigned int i=0; i +//#include +#include +#include #include #include #define DEBUG 0 //Special objects/variables for XCB parsing -static LXCB *XCB = 0; +static xcb_ewmh_connection_t EWMH; +//static LXCB *XCB = 0; static xcb_atom_t _NET_SYSTEM_TRAY_OPCODE = 0; inline void ParsePropertyEvent(xcb_property_notify_event_t *ev, NativeEventFilter *obj){ //qDebug() << "Got Property Event:" << ev->window << ev->atom; NativeWindow::Property prop = NativeWindow::None; //Now determine which properties are getting changed, and update the native window as appropriate - if(ev->atom == XCB->EWMH._NET_WM_NAME){ prop = NativeWindow::Title; } - else if(ev->atom == XCB->EWMH._NET_WM_ICON){ prop = NativeWindow::Icon; } - else if(ev->atom == XCB->EWMH._NET_WM_ICON_NAME){ prop = NativeWindow::ShortTitle; } - else if(ev->atom == XCB->EWMH._NET_WM_DESKTOP){ prop = NativeWindow::Workspace; } - else if(ev->atom == XCB->EWMH._NET_WM_WINDOW_TYPE ){ prop = NativeWindow::WinTypes; } - else if( ev->atom == XCB->EWMH._NET_WM_STATE){ prop = NativeWindow::States; } + if(ev->atom == EWMH._NET_WM_NAME){ prop = NativeWindow::Title; } + else if(ev->atom == EWMH._NET_WM_ICON){ prop = NativeWindow::Icon; } + else if(ev->atom == EWMH._NET_WM_ICON_NAME){ prop = NativeWindow::ShortTitle; } + else if(ev->atom == EWMH._NET_WM_DESKTOP){ prop = NativeWindow::Workspace; } + else if(ev->atom == EWMH._NET_WM_WINDOW_TYPE ){ prop = NativeWindow::WinTypes; } + else if( ev->atom == EWMH._NET_WM_STATE){ prop = NativeWindow::States; } //Send out the signal if necessary if(prop!=NativeWindow::None){ obj->emit WindowPropertyChanged(ev->window, prop); @@ -81,6 +84,12 @@ inline void ParsePropertyEvent(xcb_property_notify_event_t *ev, NativeEventFilte //Constructor for the Event Filter wrapper NativeEventFilter::NativeEventFilter() : QObject(){ EF = new EventFilter(this); + if(EWMH.nb_screens <=0){ + xcb_intern_atom_cookie_t *cookie = xcb_ewmh_init_atoms(QX11Info::connection(), &EWMH); + if(!xcb_ewmh_init_atoms_replies(&EWMH, cookie, NULL) ){ + qDebug() << "Error with XCB atom initializations"; + } + } if(_NET_SYSTEM_TRAY_OPCODE==0){ //_NET_SYSTEM_TRAY_OPCODE xcb_intern_atom_cookie_t cookie = xcb_intern_atom(QX11Info::connection(), 0, 23,"_NET_SYSTEM_TRAY_OPCODE"); @@ -90,7 +99,6 @@ NativeEventFilter::NativeEventFilter() : QObject(){ free(r); } } - if(XCB==0){ XCB = new LXCB(); } } void NativeEventFilter::start(){ diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp index f7b73eac..65fb6083 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/RootWindow.cpp @@ -130,7 +130,7 @@ void RootWindow::ResizeRoot(){ //Trigger a repaint and send out any signals this->setGeometry(fullscreen); this->update(); - emit RootResized(); + emit RootResized(fullscreen); if(!valid.isEmpty()){ emit NewScreens(valid); } if(!invalid.isEmpty()){ emit RemovedScreens(invalid); } } diff --git a/src-qt5/core/libLumina/RootWindow.h b/src-qt5/core/libLumina/RootWindow.h index 080c4bd1..a7792752 100644 --- a/src-qt5/core/libLumina/RootWindow.h +++ b/src-qt5/core/libLumina/RootWindow.h @@ -65,7 +65,7 @@ protected: signals: void RegisterVirtualRoot(WId); - void RootResized(); + void RootResized(QRect); void NewScreens(QStringList); // [screen_id_1, screen_id_2, etc..] void RemovedScreens(QStringList); // [screen_id_1, screen_id_2, etc..] -- cgit From 48f91b4a3892f8431021e10454cebca33430bb3e Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 13:27:51 -0400 Subject: Oops - make sure we initialize the EWMH class before using it. --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 4b9c9e62..5e119baf 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -58,6 +58,12 @@ public: //Functions for setting up these objects as needed bool init_ATOMS(){ + xcb_intern_atom_cookie_t *cookie = xcb_ewmh_init_atoms(QX11Info::connection(), &EWMH); + if(!xcb_ewmh_init_atoms_replies(&EWMH, cookie, NULL) ){ + qDebug() << "Error with XCB atom initializations"; + return false; + } + QStringList atoms; atoms << "WM_TAKE_FOCUS" << "WM_DELETE_WINDOW" << "WM_PROTOCOLS" << "WM_CHANGE_STATE" << "_NET_SYSTEM_TRAY_OPCODE" << "_NET_SYSTEM_TRAY_ORIENTATION" @@ -98,7 +104,7 @@ public: xcb_ewmh_set_supporting_wm_check(&EWMH, wm_window, wm_window); //Now also setup the root event mask on the wm_window status = xcb_request_check( QX11Info::connection(), xcb_change_window_attributes_checked(QX11Info::connection(), wm_window, XCB_CW_EVENT_MASK, value_list)); - if(status!=0){ return false; } + if(status!=0){ return false; } return true; } @@ -204,6 +210,8 @@ bool NativeWindowSystem::start(){ if(ok){ setRoot_supportedActions(); ok = obj->start_system_tray(); + }else{ + qWarning() << "Could not register the WM"; } return ok; } -- cgit From ee425989c2c2519d803a416aa0030e9e488bf70b Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Jun 2017 13:48:55 -0400 Subject: Cleanup a bit more of the root level property setting. Now things seem to be properly getting registered for the session. --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 5e119baf..13d6221c 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -441,7 +441,7 @@ void NativeWindowSystem::setRoot_supportedActions(){ obj->EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_TOOLTIP, obj->EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION, obj->EWMH._NET_WM_WINDOW_TYPE_COMBO, obj->EWMH._NET_WM_WINDOW_TYPE_DND, }; - xcb_ewmh_set_supported(&obj->EWMH, QX11Info::appScreen(), 0,list); + xcb_ewmh_set_supported(&obj->EWMH, QX11Info::appScreen(), 19,list); } void NativeWindowSystem::setRoot_numberOfWorkspaces(QStringList names){ -- cgit From b02fd1721f71e3f120c2fe56d866fac5b3a796d1 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 28 Jun 2017 10:20:24 -0400 Subject: Work on making a new NativeWindow property "RelatedWindows" which is a special property used only for seeing which Window ID's are also associated with a given window. --- src-qt5/core/libLumina/NativeWindow.cpp | 8 +++++--- src-qt5/core/libLumina/NativeWindow.h | 15 ++++++++------- src-qt5/core/libLumina/NativeWindowSystem.h | 4 ++-- 3 files changed, 15 insertions(+), 12 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index 020e4596..1fcaa552 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -35,11 +35,13 @@ QWindow* NativeWindow::window(){ QVariant NativeWindow::property(NativeWindow::Property prop){ if(hash.contains(prop)){ return hash.value(prop); } + else if(prop == NativeWindow::RelatedWindows){ return QVariant::fromValue(relatedTo); } return QVariant(); //null variant } void NativeWindow::setProperty(NativeWindow::Property prop, QVariant val){ - if(prop == NativeWindow::None || hash.value(prop)==val){ return; } + if(prop == NativeWindow::RelatedWindows){ relatedTo = val.value< QList >(); } + else if(prop == NativeWindow::None || hash.value(prop)==val){ return; } hash.insert(prop, val); emit PropertiesChanged(QList() << prop, QList() << val); } @@ -54,7 +56,7 @@ void NativeWindow::setProperties(QList props, QList() << prop, QList() << val); } @@ -62,7 +64,7 @@ void NativeWindow::requestProperties(QList props, QList< //Verify/adjust inputs as needed for(int i=0; i=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this property - if(props[i] == NativeWindow::None || hash.value(props[i])==vals[i] ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value + if(props[i] == NativeWindow::None || props[i] == NativeWindow::RelatedWindows || hash.value(props[i])==vals[i] ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value } emit RequestPropertiesChange(winid, props, vals); } diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index a3efd234..e6e90825 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -30,9 +30,9 @@ public: enum Property{ /*QVariant Type*/ None, /*null*/ - MinSize, /*QSize*/ - MaxSize, /*QSize*/ - Size, /*QSize*/ + MinSize, /*QSize*/ + MaxSize, /*QSize*/ + Size, /*QSize*/ GlobalPos, /*QPoint*/ Title, /*QString*/ ShortTitle, /*QString*/ @@ -41,17 +41,18 @@ public: Workspace, /*int*/ States, /*QList : Current state of the window */ WinTypes, /*QList : Current type of window (typically does not change)*/ - WinActions, /*QList : Current actions that the window allows (Managed/set by the WM)*/ - FrameExtents, /*QList : [Left, Right, Top, Bottom] in pixels */ + WinActions, /*QList : Current actions that the window allows (Managed/set by the WM)*/ + FrameExtents, /*QList : [Left, Right, Top, Bottom] in pixels */ + RelatedWindows, /* QList - better to use the "isRelatedTo(WId)" function instead of reading this directly*/ Active, /*bool*/ Visible /*bool*/ }; static QList allProperties(){ - //Return all the available properties (excluding "None") + //Return all the available properties (excluding "None" and "FrameExtents" (WM control only) ) QList props; props << MinSize << MaxSize << Size << GlobalPos << Title << ShortTitle << Icon << Name << Workspace \ - << States << WinTypes << WinActions << Active << Visible; + << States << WinTypes << WinActions << RelatedWindows << Active << Visible; return props; }; diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h index 53abd633..00841903 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/core/libLumina/NativeWindowSystem.h @@ -26,9 +26,9 @@ private: NativeWindow* findWindow(WId id){ qDebug() << "Find Window:" << id; for(int i=0; iid(); if(NWindows[i]->isRelatedTo(id)){ qDebug() << " -- Got Match!"; return NWindows[i]; } } + qDebug() << " -- Could not find Window!"; return 0; } @@ -69,7 +69,7 @@ private: bool screenLocked; public: - enum Property{ None, CurrentWorkspace, Workspaces, VirtualRoots, WorkAreas }; + //enum Property{ None, CurrentWorkspace, Workspaces, VirtualRoots, WorkAreas }; enum MouseButton{NoButton, LeftButton, RightButton, MidButton, BackButton, ForwardButton, TaskButton, WheelUp, WheelDown, WheelLeft, WheelRight}; NativeWindowSystem(); -- cgit From 431e837ead4e8fd7f7aef6b7d198dac50156c2b2 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 28 Jun 2017 17:18:57 -0400 Subject: Get a lot more of the Lumina2 window-management functionality working. --- src-qt5/core/libLumina/LuminaX11.cpp | 2 +- src-qt5/core/libLumina/NativeEventFilter.cpp | 9 +- src-qt5/core/libLumina/NativeEventFilter.h | 1 + src-qt5/core/libLumina/NativeWindow.cpp | 10 +- src-qt5/core/libLumina/NativeWindow.h | 8 +- src-qt5/core/libLumina/NativeWindowSystem.cpp | 142 ++++++++++++++++++++++++-- src-qt5/core/libLumina/NativeWindowSystem.h | 19 +--- src-qt5/core/libLumina/RootSubWindow.cpp | 60 +++++++++-- src-qt5/core/libLumina/RootSubWindow.h | 7 ++ src-qt5/core/libLumina/RootWindow.cpp | 4 +- 10 files changed, 220 insertions(+), 42 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaX11.cpp b/src-qt5/core/libLumina/LuminaX11.cpp index b5dd62cd..86af1a00 100644 --- a/src-qt5/core/libLumina/LuminaX11.cpp +++ b/src-qt5/core/libLumina/LuminaX11.cpp @@ -497,7 +497,7 @@ QIcon LXCB::WindowIcon(WId win){ uint* dat = iter.data; //dat+=2; //remember the first 2 element offset for(int i=0; iatom == EWMH._NET_WM_STATE){ prop = NativeWindow::States; } //Send out the signal if necessary if(prop!=NativeWindow::None){ + qDebug() << "Detected Property Change:" << ev->window << prop; obj->emit WindowPropertyChanged(ev->window, prop); + }else{ + //qDebug() << "Unknown Property Change:" << ev->window << ev->atom; } } @@ -175,7 +178,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, //============================== case XCB_MAP_NOTIFY: qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; - obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible ); + obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible, true); break; //This is just a notification that a window was mapped - nothing needs to change here case XCB_MAP_REQUEST: qDebug() << "Window Map Request Event"; @@ -188,7 +191,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, //============================== case XCB_UNMAP_NOTIFY: qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; - obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible ); + obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible, false); break; //============================== case XCB_DESTROY_NOTIFY: @@ -205,7 +208,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, break; //============================== case XCB_PROPERTY_NOTIFY: - qDebug() << "Property Notify Event:"; + //qDebug() << "Property Notify Event:"; ParsePropertyEvent((xcb_property_notify_event_t*)ev, obj); break; //============================== diff --git a/src-qt5/core/libLumina/NativeEventFilter.h b/src-qt5/core/libLumina/NativeEventFilter.h index 2d5fbc61..2c6bfb6b 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.h +++ b/src-qt5/core/libLumina/NativeEventFilter.h @@ -34,6 +34,7 @@ signals: void WindowCreated(WId); void WindowDestroyed(WId); void WindowPropertyChanged(WId, NativeWindow::Property); + void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); //System Tray Signals void TrayWindowCreated(WId); diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index 1fcaa552..68610ce2 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -9,6 +9,7 @@ // === PUBLIC === NativeWindow::NativeWindow(WId id) : QObject(){ winid = id; + frameid = 0; WIN = QWindow::fromWinId(winid); } @@ -18,11 +19,11 @@ NativeWindow::~NativeWindow(){ } void NativeWindow::addFrameWinID(WId fid){ - relatedTo << fid; + frameid = fid; } bool NativeWindow::isRelatedTo(WId tmp){ - return (relatedTo.contains(tmp) || winid == tmp); + return (relatedTo.contains(tmp) || winid == tmp || frameid == tmp); } WId NativeWindow::id(){ @@ -65,6 +66,11 @@ void NativeWindow::requestProperties(QList props, QList< for(int i=0; i=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this property if(props[i] == NativeWindow::None || props[i] == NativeWindow::RelatedWindows || hash.value(props[i])==vals[i] ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value + if( (props[i] == NativeWindow::Visible || props[i] == NativeWindow::Active) && frameid !=0){ + //These particular properties needs to change the frame - not the window itself + emit RequestPropertiesChange(frameid, QList() << props[i], QList() << vals[i]); + props.removeAt(i); vals.removeAt(i); i--; + } } emit RequestPropertiesChange(winid, props, vals); } diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index e6e90825..a1cb7c1a 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -29,7 +29,7 @@ public: enum Action {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}; enum Property{ /*QVariant Type*/ - None, /*null*/ + None=0, /*null*/ MinSize, /*QSize*/ MaxSize, /*QSize*/ Size, /*QSize*/ @@ -79,7 +79,7 @@ public slots: private: QHash hash; QWindow *WIN; - WId winid; + WId winid, frameid; QList relatedTo; signals: @@ -92,9 +92,9 @@ signals: //Action Requests (not automatically emitted - typically used to ask the WM to do something) //Note: "WId" should be the NativeWindow id() void RequestClose(WId); //Close the window - void RequestKill(WId); //Kill the window/app (usually from being unresponsive) + void RequestKill(WId); //Kill the window/app (usually from being unresponsive) void RequestPing(WId); //Verify that the window is still active (such as not closing after a request - + void RequestReparent(WId, WId, QPoint); //client window, frame window, relative origin point in frame // System Tray Icon Embed/Unembed Requests //void RequestEmbed(WId, QWidget*); //void RequestUnEmbed(WId, QWidget*); diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 13d6221c..a6bcd718 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -87,6 +87,16 @@ public: return (ATOMS.keys().length() == atoms.length()); } + WId getTransientFor(WId win){ + xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_transient_for_unchecked(QX11Info::connection(), win); + xcb_window_t trans; + if(1!= xcb_icccm_get_wm_transient_for_reply(QX11Info::connection(), cookie, &trans, NULL) ){ + return win; //error in fetching transient window ID (or none found) + }else{ + return trans; + } +} + bool register_wm(){ uint32_t value_list[1] = {ROOT_WIN_EVENT_MASK}; xcb_generic_error_t *status = xcb_request_check( QX11Info::connection(), xcb_change_window_attributes_checked(QX11Info::connection(), root_window, XCB_CW_EVENT_MASK, value_list)); @@ -253,6 +263,25 @@ NativeWindowSystem::MouseButton NativeWindowSystem::MouseToQt(int keycode){ } // === PRIVATE === +NativeWindow* NativeWindowSystem::findWindow(WId id){ + //qDebug() << "Find Window:" << id; + for(int i=0; iisRelatedTo(id)){ qDebug() << " -- Got Window Match!" << id; return NWindows[i]; } + } + //Check to see if this is a transient for some other window + WId tid = obj->getTransientFor(id); + if(tid!=id){ return findWindow(tid); } //call it recursively as needed + //qDebug() << " -- Could not find Window!"; + return 0; +} + +NativeWindow* NativeWindowSystem::findTrayWindow(WId id){ + for(int i=0; iisRelatedTo(id)){ return TWindows[i]; } + } + return 0; +} + void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props){ //Put the properties in logical groups as appropriate (some XCB calls return multiple properties) if(props.contains(NativeWindow::Title)){ @@ -285,7 +314,7 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native xcb_icccm_get_text_property_reply_wipe(&reply); } } - win->setProperty(NativeWindow::Name, name); + win->setProperty(NativeWindow::Title, name); } //end TITLE property if(props.contains(NativeWindow::ShortTitle)){ @@ -415,8 +444,85 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native }*/ win->setProperty(NativeWindow::Workspace, wkspace); } + + if(props.contains(NativeWindow::RelatedWindows)){ + WId orig = win->id(); + WId tid = obj->getTransientFor(orig); + QList list; + while(tid != orig){ + list << tid; + orig = tid; + tid = obj->getTransientFor(orig); + } + win->setProperty(NativeWindow::RelatedWindows, QVariant::fromValue(list)); + } + if(props.contains(NativeWindow::Visible)){ + xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(QX11Info::connection(), xcb_get_window_attributes(QX11Info::connection(), win->id()) , NULL); + if(attr != 0){ + win->setProperty(NativeWindow::Visible, attr->map_state == XCB_MAP_STATE_VIEWABLE); + free(attr); + } + } } +void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList vals){ + qDebug() << "Change Window Properties:" << props << vals; + if(props.contains(NativeWindow::Title)){ + + } + if(props.contains(NativeWindow::ShortTitle)){ + + } + if(props.contains(NativeWindow::Icon)){ + + } + if(props.contains(NativeWindow::MinSize) || props.contains(NativeWindow::MaxSize) + || props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ + + } + if(props.contains(NativeWindow::Name)){ + + } + if(props.contains(NativeWindow::Workspace)){ + int num = vals[ props.indexOf(NativeWindow::Workspace) ].toInt(); + xcb_ewmh_set_wm_desktop(&obj->EWMH, win->id(), (num<0 ? 0xFFFFFFFF : qAbs(num) ) ); + } + if(props.contains(NativeWindow::RelatedWindows)){ + + } + if(props.contains(NativeWindow::Visible)){ + qDebug() << "Check Window Visibility:" << vals[ props.indexOf(NativeWindow::Visible) ]; + if( vals[ props.indexOf(NativeWindow::Visible) ].toBool() ){ + qDebug() << " - Map it!"; + xcb_map_window(QX11Info::connection(), win->id()); + }else{ + qDebug() << " - Unmap it!"; + xcb_unmap_window(QX11Info::connection(), win->id()); + } + } + if(props.contains(NativeWindow::Active)){ + //Only one window can be "Active" at a time - so only do anything if this window wants to be active + if(vals[props.indexOf(NativeWindow::Active)].toBool() ){ + xcb_ewmh_set_active_window(&obj->EWMH, QX11Info::appScreen(), win->id()); + //Also send the active window a message to take input focus + //Send the window a WM_TAKE_FOCUS message + xcb_client_message_event_t event; + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.window = win->id(); + event.type = obj->ATOMS["WM_PROTOCOLS"]; + event.data.data32[0] = obj->ATOMS["WM_TAKE_FOCUS"]; + event.data.data32[1] = XCB_TIME_CURRENT_TIME; //CurrentTime; + event.data.data32[2] = 0; + event.data.data32[3] = 0; + event.data.data32[4] = 0; + + xcb_send_event(QX11Info::connection(), 0, win->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); + xcb_flush(QX11Info::connection()); + } + } + +} // === PUBLIC SLOTS === //These are the slots which are typically only used by the desktop system itself or the NativeEventFilter @@ -534,6 +640,8 @@ void NativeWindowSystem::NewWindowDetected(WId id){ if(attr == 0){ return; } //could not get attributes of window if(attr->override_redirect){ free(attr); return; } //window has override redirect set (do not manage) free(attr); + //Now go ahead and create/populate the container for this window + NativeWindow *win = new NativeWindow(id); //Register for events from this window #define NORMAL_WIN_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ XCB_EVENT_MASK_BUTTON_RELEASE | \ @@ -543,14 +651,20 @@ void NativeWindowSystem::NewWindowDetected(WId id){ XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_ENTER_WINDOW) + XCB_EVENT_MASK_ENTER_WINDOW| \ + XCB_EVENT_MASK_PROPERTY_CHANGE) uint32_t value_list[1] = {NORMAL_WIN_EVENT_MASK}; xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, value_list); - //Now go ahead and create/populate the container for this window - NativeWindow *win = new NativeWindow(id); NWindows << win; UpdateWindowProperties(win, NativeWindow::allProperties()); + qDebug() << "New Window [associated ID's]:" << win->property(NativeWindow::RelatedWindows); + //Now setup the connections with this window + connect(win, SIGNAL(RequestClose(WId)), this, SLOT(RequestClose(WId)) ); + connect(win, SIGNAL(RequestKill(WId)), this, SLOT(RequestKill(WId)) ); + connect(win, SIGNAL(RequestPing(WId)), this, SLOT(RequestPing(WId)) ); + connect(win, SIGNAL(RequestReparent(WId, WId, QPoint)), this, SLOT(RequestReparent(WId, WId, QPoint)) ); + connect(win, SIGNAL(RequestPropertiesChange(WId, QList, QList)), this, SLOT(RequestPropertiesChange(WId, QList, QList)) ); emit NewWindowAvailable(win); } @@ -608,6 +722,14 @@ void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property pr } } +void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop, QVariant val){ + NativeWindow *win = findWindow(id); + if(win==0){ win = findTrayWindow(id); } + if(win!=0){ + win->setProperty(prop, val); + } +} + void NativeWindowSystem::GotPong(WId id){ if(waitingForPong.contains(id)){ waitingForPong.remove(id); @@ -655,9 +777,7 @@ void NativeWindowSystem::RequestPropertiesChange(WId win, QListstart(); } + +void NativeWindowSystem::RequestReparent(WId client, WId parent, QPoint relorigin){ + xcb_reparent_window(QX11Info::connection(), client, parent, relorigin.x(), relorigin.y()); + //Now enable compositing between these two windows as well + // TODO + + xcb_map_window(QX11Info::connection(), parent); +} diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h index 00841903..5b71249e 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/core/libLumina/NativeWindowSystem.h @@ -23,21 +23,9 @@ private: QList TWindows; //Simplifications to find an already-created window object - NativeWindow* findWindow(WId id){ - qDebug() << "Find Window:" << id; - for(int i=0; iisRelatedTo(id)){ qDebug() << " -- Got Match!"; return NWindows[i]; } - } - qDebug() << " -- Could not find Window!"; - return 0; - } + NativeWindow* findWindow(WId id); - NativeWindow* findTrayWindow(WId id){ - for(int i=0; iisRelatedTo(id)){ return TWindows[i]; } - } - return 0; - } + NativeWindow* findTrayWindow(WId id); //Now define a simple private_objects class so that each implementation // has a storage container for defining/placing private objects as needed @@ -64,6 +52,7 @@ private: // Since some properties may be easier to update in bulk // let the native system interaction do them in whatever logical groups are best void UpdateWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props); + void ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList vals); //Generic private variables bool screenLocked; @@ -116,6 +105,7 @@ public slots: void NewTrayWindowDetected(WId); //will automatically create the new NativeWindow object void WindowCloseDetected(WId); //will update the lists and make changes if needed void WindowPropertyChanged(WId, NativeWindow::Property); //will rescan the window and update the object as needed + void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); //will save that property/value to the right object void GotPong(WId); void NewKeyPress(int keycode, WId win = 0); @@ -130,6 +120,7 @@ private slots: void RequestClose(WId); void RequestKill(WId); void RequestPing(WId); + void RequestReparent(WId, WId, QPoint); //client, parent, relative origin point in parent signals: void NewWindowAvailable(NativeWindow*); diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index fdb9ac76..04deacf9 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -8,7 +8,8 @@ #include #include #include -#include +#include +#include #define WIN_BORDER 5 @@ -19,12 +20,14 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ //Create the QWindow and QWidget containers for the window WIN = win; closing = false; - WinWidget = QWidget::createWindowContainer( WIN->window(), this); + //WinWidget = QWidget::createWindowContainer( WIN->window(), this); initWindowFrame(); - LoadProperties( NativeWindow::allProperties() ); //Hookup the signals/slots connect(WIN, SIGNAL(PropertiesChanged(QList, QList)), this, SLOT(propertiesChanged(QList, QList))); - WIN->addFrameWinID(this->winId()); + WIN->addFrameWinID(WinWidget->winId()); + WIN->emit RequestReparent(WIN->id(), WinWidget->winId(), QPoint(0,0)); + LoadAllProperties(); + //QTimer::singleShot(20, this, SLOT(LoadAllProperties()) ); } RootSubWindow::~RootSubWindow(){ @@ -126,7 +129,7 @@ void RootSubWindow::setMouseCursor(ModState state, bool override){ void RootSubWindow::initWindowFrame(){ //qDebug() << "Create RootSubWindow Frame"; mainLayout = new QVBoxLayout(this); - titleBar = new QHBoxLayout(this); + titleBar = new QHBoxLayout(); closeB = new QToolButton(this); maxB = new QToolButton(this); minB = new QToolButton(this); @@ -137,6 +140,7 @@ void RootSubWindow::initWindowFrame(){ otherB->setMenu(otherM); otherB->setPopupMode(QToolButton::InstantPopup); otherB->setAutoRaise(true); + WinWidget = new QWidget(this); connect(closeB, SIGNAL(clicked()), this, SLOT(triggerClose()) ); connect(maxB, SIGNAL(clicked()), this, SLOT(toggleMaximize()) ); connect(minB, SIGNAL(clicked()), this, SLOT(toggleMinimize()) ); @@ -169,9 +173,12 @@ void RootSubWindow::initWindowFrame(){ void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ QList vals; for(int i=0; iproperty(list[i]); + qDebug() << "Property:" << list[i] << vals[i]; } propertiesChanged(list, vals); + WIN->requestProperty(NativeWindow::Visible, true); } // === PUBLIC SLOTS === @@ -181,6 +188,13 @@ void RootSubWindow::clientClosed(){ this->close(); } +void RootSubWindow::LoadAllProperties(){ + QList< NativeWindow::Property> list = WIN->allProperties(); + /*list.removeAll(NativeWindow::Visible); + list << NativeWindow::Visible;*/ + LoadProperties(list); +} + //Button Actions - public so they can be tied to key shortcuts and stuff as well void RootSubWindow::toggleMinimize(){ @@ -227,21 +241,31 @@ void RootSubWindow::startResizing(){ // === PRIVATE SLOTS === void RootSubWindow::propertiesChanged(QList props, QList vals){ for(int i=0; ishow(); } + qDebug() << "Got Visibility Change:" << vals[i]; + if(vals[i].toBool()){ WinWidget->setVisible(true); this->show(); } else{ this->hide(); } break; case NativeWindow::Title: titleLabel->setText(vals[i].toString()); break; case NativeWindow::Icon: + //qDebug() << "Got Icon Change:" << vals[i]; otherB->setIcon(vals[i].value< QIcon>()); break; + case NativeWindow::GlobalPos: + //qDebug() << "Got Global Pos:" << vals[i].toPoint(); + this->move( vals[i].toPoint() ); + break; case NativeWindow::Size: - WinWidget->resize(vals[i].toSize()); + //qDebug() << "Got Widget Size:" << vals[i].toSize(); + //WinWidget->setSizeHint( vals[i].toSize() ); + //WinWidget->resize(vals[i].toSize() ); + this->resize( vals[i].toSize()+QSize( this->width()-WinWidget->width(), this->height()-WinWidget->height() ) ); + //qDebug() << " - Size after change:" << WinWidget->size() << this->size(); break; case NativeWindow::MinSize: WinWidget->setMinimumSize(vals[i].toSize()); @@ -250,7 +274,7 @@ void RootSubWindow::propertiesChanged(QList props, QList WinWidget->setMaximumSize(vals[i].toSize()); break; case NativeWindow::Active: - if(vals[i].toBool()){ WinWidget->setFocus(); } + //if(vals[i].toBool()){ WinWidget->setFocus(); } break; /*case NativeWindow::WindowFlags: this->setWindowFlags( val.value< Qt::WindowFlags >() ); @@ -380,3 +404,19 @@ void RootSubWindow::leaveEvent(QEvent *ev){ setMouseCursor(Normal); } } + +/*void RootSubWindow::hideEvent(QHideEvent *ev){ + WIN->requestProperty(NativeWindow::Visible, false); + QFrame::hideEvent(ev); +}*/ + +void RootSubWindow::resizeEvent(QResizeEvent *ev){ + qDebug() << "Got Resize Event:" << ev->size(); + WIN->requestProperty(NativeWindow::Size, WinWidget->size()); + QFrame::resizeEvent(ev); +} +/*void RootSubWindow::showEvent(QShowEvent *ev){ + WIN->requestProperty(NativeWindow::Visible, true); + QFrame::showEvent(ev); +}*/ + diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index 779f783b..e1b992c9 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -53,6 +53,7 @@ private: public slots: void clientClosed(); + void LoadAllProperties(); //Button Actions - public so they can be tied to key shortcuts and stuff as well void toggleMinimize(); @@ -74,6 +75,12 @@ protected: void mouseReleaseEvent(QMouseEvent*); void leaveEvent(QEvent *ev); + //void hideEvent(QHideEvent *ev); + void resizeEvent(QResizeEvent *ev); + //void showEvent(QShowEvent *ev); + //void moveEvent(QMoveEvent *ev); + + }; #endif diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp index 65fb6083..17a9ecd7 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/RootWindow.cpp @@ -177,7 +177,9 @@ void RootWindow::NewWindow(NativeWindow *win){ connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(CloseWindow(WId)) ); WINDOWS << subwin; } - subwin->show(); + //win->setProperty(NativeWindow::Visible, true); + //win->requestProperty( NativeWindow::Active, true); + win->requestProperties(QList() << NativeWindow::Visible << NativeWindow::Active, QList() << true << true); } void RootWindow::CloseWindow(WId win){ -- cgit From c47e7ca51fcf653a3d3078924a93f2dca2c25359 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 08:37:37 -0400 Subject: Clean up some of the rootSubWindow overrides --- src-qt5/core/libLumina/RootSubWindow.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 04deacf9..f45258a3 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -245,7 +245,7 @@ void RootSubWindow::propertiesChanged(QList props, QList //qDebug() << "RootSubWindow: Property Changed:" << props[i] << vals[i]; switch(props[i]){ case NativeWindow::Visible: - qDebug() << "Got Visibility Change:" << vals[i]; + //qDebug() << "Got Visibility Change:" << vals[i]; if(vals[i].toBool()){ WinWidget->setVisible(true); this->show(); } else{ this->hide(); } break; @@ -301,11 +301,11 @@ void RootSubWindow::mousePressEvent(QMouseEvent *ev){ activeState = getStateAtPoint(ev->pos(), true); //also have it set the offset variable } setMouseCursor(activeState, true); //this one is an override cursor - + QFrame::mousePressEvent(ev); } void RootSubWindow::mouseMoveEvent(QMouseEvent *ev){ - ev->accept(); + //ev->accept(); if(activeState == Normal){ setMouseCursor( getStateAtPoint(ev->pos()) ); //just update the mouse cursor }else{ @@ -382,12 +382,13 @@ void RootSubWindow::mouseMoveEvent(QMouseEvent *ev){ this->setGeometry(geom); } + QFrame::mouseMoveEvent(ev); } void RootSubWindow::mouseReleaseEvent(QMouseEvent *ev){ //Check for a right-click event //qDebug() << "Frame Mouse Release Event"; - ev->accept(); + QFrame::mouseReleaseEvent(ev); if( (activeState==Normal) && (titleBar->geometry().contains(ev->pos())) && (ev->button()==Qt::RightButton) ){ otherM->popup(ev->globalPos()); return; @@ -419,4 +420,3 @@ void RootSubWindow::resizeEvent(QResizeEvent *ev){ WIN->requestProperty(NativeWindow::Visible, true); QFrame::showEvent(ev); }*/ - -- cgit From 4fa1cdda33d5fbdf3f1d496e705cddd76f7e1cfa Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 10:18:18 -0400 Subject: Get the window size/position change detection implemented. --- src-qt5/core/libLumina/LuminaX11.cpp | 8 ++--- src-qt5/core/libLumina/NativeEventFilter.cpp | 14 ++++++++ src-qt5/core/libLumina/NativeEventFilter.h | 46 ++---------------------- src-qt5/core/libLumina/NativeWindowSystem.cpp | 52 +++++++++++++++++---------- src-qt5/core/libLumina/NativeWindowSystem.h | 4 ++- src-qt5/core/libLumina/RootSubWindow.cpp | 4 +-- 6 files changed, 59 insertions(+), 69 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaX11.cpp b/src-qt5/core/libLumina/LuminaX11.cpp index 86af1a00..dd98d12c 100644 --- a/src-qt5/core/libLumina/LuminaX11.cpp +++ b/src-qt5/core/libLumina/LuminaX11.cpp @@ -179,7 +179,7 @@ void LXCB::SetCurrentWorkspace(int number){ event.data.data32[4] = 0; xcb_send_event(QX11Info::connection(), 0, QX11Info::appRootWindow(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); - + //EWMH function (does not seem to be recognized by Fluxbox) xcb_ewmh_request_change_showing_desktop(&EWMH, QX11Info::appScreen(), number); } @@ -190,7 +190,7 @@ QString LXCB::WindowClass(WId win){ QString out; if(win==0){ return ""; } xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class_unchecked(QX11Info::connection(), win); - if(cookie.sequence == 0){ return out; } + if(cookie.sequence == 0){ return out; } xcb_icccm_get_wm_class_reply_t value; if( 1== xcb_icccm_get_wm_class_reply( QX11Info::connection(), cookie, &value, NULL) ){ out = QString::fromUtf8(value.class_name); @@ -207,7 +207,7 @@ unsigned int LXCB::WindowWorkspace(WId win){ uint32_t wkspace = 0; xcb_get_property_cookie_t scookie = xcb_ewmh_get_wm_state_unchecked(&EWMH, win); xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_desktop_unchecked(&EWMH, win); - if(cookie.sequence == 0){ return wkspace; } + if(cookie.sequence == 0){ return wkspace; } xcb_ewmh_get_wm_desktop_reply(&EWMH, cookie, &wkspace, NULL); xcb_ewmh_get_atoms_reply_t reply; if(1==xcb_ewmh_get_wm_state_reply(&EWMH,scookie, &reply, NULL)){ @@ -217,7 +217,7 @@ unsigned int LXCB::WindowWorkspace(WId win){ } } //qDebug() << " - done: " << wkspace; - return wkspace; + return wkspace; } // === WindowGeometry() === diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp index c4873d6b..28432222 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -227,11 +227,25 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, //============================== case XCB_CONFIGURE_NOTIFY: //qDebug() << "Configure Notify Event"; + obj->emit WindowPropertiesChanged( ((xcb_configure_notify_event_t*)ev)->window, + QList() << NativeWindow::GlobalPos << NativeWindow::Size, + QList() << QPoint(((xcb_configure_notify_event_t*)ev)->x, ((xcb_configure_notify_event_t*)ev)->y) << + QSize(((xcb_configure_notify_event_t*)ev)->width, ((xcb_configure_notify_event_t*)ev)->height) ); break; //============================== case XCB_CONFIGURE_REQUEST: //qDebug() << "Configure Request Event"; + obj->emit RequestWindowPropertiesChange( ((xcb_configure_request_event_t*)ev)->window, + QList() << NativeWindow::GlobalPos << NativeWindow::Size, + QList() << QPoint(((xcb_configure_request_event_t*)ev)->x, ((xcb_configure_request_event_t*)ev)->y) << + QSize(((xcb_configure_request_event_t*)ev)->width, ((xcb_configure_request_event_t*)ev)->height) ); break; +//============================== + case XCB_RESIZE_REQUEST: + //qDebug() << "Resize Request Event"; + obj->emit RequestWindowPropertyChange( ((xcb_resize_request_event_t*)ev)->window, + NativeWindow::Size, QSize(((xcb_resize_request_event_t*)ev)->width, ((xcb_resize_request_event_t*)ev)->height) ); + break; //============================== case XCB_SELECTION_CLEAR: //qDebug() << "Selection Clear Event"; diff --git a/src-qt5/core/libLumina/NativeEventFilter.h b/src-qt5/core/libLumina/NativeEventFilter.h index 2c6bfb6b..2b184f99 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.h +++ b/src-qt5/core/libLumina/NativeEventFilter.h @@ -35,6 +35,9 @@ signals: void WindowDestroyed(WId); void WindowPropertyChanged(WId, NativeWindow::Property); void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); + void WindowPropertiesChanged(WId, QList, QList); + void RequestWindowPropertyChange(WId, NativeWindow::Property, QVariant); + void RequestWindowPropertiesChange(WId, QList, QList); //System Tray Signals void TrayWindowCreated(WId); @@ -60,51 +63,8 @@ public: virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *); - //System Tray Functions - //QList trayApps(); //return the list of all current tray apps - //bool startSystemTray(); - //bool stopSystemTray(); - - //Window List Functions - //QList windowList(); - private: NativeEventFilter *obj; - /*QList WinNotifyAtoms, SysNotifyAtoms; - xcb_atom_t _NET_SYSTEM_TRAY_OPCODE; - void InitAtoms(); - - bool BlockInputEvent(WId win = 0); //Checks the current state of the system to see if the event should be stopped - WId InputWindow(WId win = 0); //Checks the window ID and determines if this is an external window or returns 0 (for desktop/root windows) - Lumina::MouseButton MouseKey(int keycode); //convert the keycode into the mouse button code - - //System Tray Variables - WId SystemTrayID; - int TrayDmgID; - QList RunningTrayApps; - //System Tray functions - void addTrayApp(WId); - bool rmTrayApp(WId); //returns "true" if the tray app was found and removed - void checkDamageID(WId); - - //Window List Variables - QList windows; - QList waitingToShow; - - //Longer Event handling functions - void SetupNewWindow(xcb_map_request_event_t *ev); - - //bool ParseKeyPressEvent(); - //bool ParseKeyReleaseEvent(); - //bool ParseButtonPressEvent(); - //bool ParseButtonReleaseEvent(); - //bool ParseMotionEvent(); - void ParsePropertyEvent(xcb_property_notify_event_t *ev); - //bool ParseClientMessageEvent(); - //bool ParseDestroyEvent(); - //bool ParseConfigureEvent(); - //bool ParseKeySelectionClearEvent(); - */ }; #endif diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index a6bcd718..8d732d8c 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -644,21 +644,21 @@ void NativeWindowSystem::NewWindowDetected(WId id){ NativeWindow *win = new NativeWindow(id); //Register for events from this window #define NORMAL_WIN_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ - XCB_EVENT_MASK_BUTTON_RELEASE | \ - XCB_EVENT_MASK_POINTER_MOTION | \ - XCB_EVENT_MASK_BUTTON_MOTION | \ - XCB_EVENT_MASK_EXPOSURE | \ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_ENTER_WINDOW| \ - XCB_EVENT_MASK_PROPERTY_CHANGE) + XCB_EVENT_MASK_BUTTON_RELEASE | \ + XCB_EVENT_MASK_POINTER_MOTION | \ + XCB_EVENT_MASK_BUTTON_MOTION | \ + XCB_EVENT_MASK_EXPOSURE | \ + XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ + XCB_EVENT_MASK_ENTER_WINDOW| \ + XCB_EVENT_MASK_PROPERTY_CHANGE) uint32_t value_list[1] = {NORMAL_WIN_EVENT_MASK}; xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, value_list); NWindows << win; UpdateWindowProperties(win, NativeWindow::allProperties()); - qDebug() << "New Window [associated ID's]:" << win->property(NativeWindow::RelatedWindows); + qDebug() << "New Window [& associated ID's]:" << win->id() << win->property(NativeWindow::RelatedWindows); //Now setup the connections with this window connect(win, SIGNAL(RequestClose(WId)), this, SLOT(RequestClose(WId)) ); connect(win, SIGNAL(RequestKill(WId)), this, SLOT(RequestKill(WId)) ); @@ -730,6 +730,29 @@ void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property pr } } +void NativeWindowSystem::WindowPropertiesChanged(WId id, QList props, QList vals){ + NativeWindow *win = findWindow(id); + if(win==0){ win = findTrayWindow(id); } + if(win!=0){ + for(int i=0; isetProperty(props[i], vals[i]); } + } +} + +void NativeWindowSystem::RequestPropertyChange(WId id, NativeWindow::Property prop, QVariant val){ + //This is just a simplified version of the multiple-property function + RequestPropertiesChange(id, QList() << prop, QList() << val); +} + +void NativeWindowSystem::RequestPropertiesChange(WId win, QList props, QList vals){ + //Find the window object associated with this id + bool istraywin = false; //just in case we care later if it is a tray window or a regular window + NativeWindow *WIN = findWindow(win); + if(WIN==0){ istraywin = true; WIN = findTrayWindow(win); } + if(WIN==0){ return; } //invalid window ID - no longer available + //Now make any changes as needed + ChangeWindowProperties(WIN, props, vals); +} + void NativeWindowSystem::GotPong(WId id){ if(waitingForPong.contains(id)){ waitingForPong.remove(id); @@ -770,15 +793,6 @@ void NativeWindowSystem::CheckDamageID(WId win){ // === PRIVATE SLOTS === //These are the slots which are built-in and automatically connected when a new NativeWindow is created -void NativeWindowSystem::RequestPropertiesChange(WId win, QList props, QList vals){ - //Find the window object associated with this id - bool istraywin = false; //just in case we care later if it is a tray window or a regular window - NativeWindow *WIN = findWindow(win); - if(WIN==0){ istraywin = true; WIN = findTrayWindow(win); } - if(WIN==0){ return; } //invalid window ID - no longer available - //Now make any changes as needed - ChangeWindowProperties(WIN, props, vals); -} void NativeWindowSystem::RequestClose(WId win){ //Send the window a WM_DELETE_WINDOW message diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h index 5b71249e..7786c87d 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/core/libLumina/NativeWindowSystem.h @@ -106,6 +106,9 @@ public slots: void WindowCloseDetected(WId); //will update the lists and make changes if needed void WindowPropertyChanged(WId, NativeWindow::Property); //will rescan the window and update the object as needed void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); //will save that property/value to the right object + void WindowPropertiesChanged(WId, QList, QList); + void RequestPropertyChange(WId, NativeWindow::Property, QVariant); + void RequestPropertiesChange(WId, QList, QList); void GotPong(WId); void NewKeyPress(int keycode, WId win = 0); @@ -116,7 +119,6 @@ public slots: private slots: //These are the slots which are built-in and automatically connected when a new NativeWindow is created - void RequestPropertiesChange(WId, QList, QList); void RequestClose(WId); void RequestKill(WId); void RequestPing(WId); diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index f45258a3..66cfbc6a 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -261,11 +261,11 @@ void RootSubWindow::propertiesChanged(QList props, QList this->move( vals[i].toPoint() ); break; case NativeWindow::Size: - //qDebug() << "Got Widget Size:" << vals[i].toSize(); + qDebug() << "Got Widget Size:" << vals[i].toSize(); //WinWidget->setSizeHint( vals[i].toSize() ); //WinWidget->resize(vals[i].toSize() ); this->resize( vals[i].toSize()+QSize( this->width()-WinWidget->width(), this->height()-WinWidget->height() ) ); - //qDebug() << " - Size after change:" << WinWidget->size() << this->size(); + qDebug() << " - Size after change:" << WinWidget->size() << this->size(); break; case NativeWindow::MinSize: WinWidget->setMinimumSize(vals[i].toSize()); -- cgit From fd0224378284bb98a03a87220eef0c02894619de Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 10:28:23 -0400 Subject: Add the ability to change the "Size" property for windows. --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 8d732d8c..d540d86e 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -476,9 +476,16 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native if(props.contains(NativeWindow::Icon)){ } - if(props.contains(NativeWindow::MinSize) || props.contains(NativeWindow::MaxSize) - || props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ - + if(props.contains(NativeWindow::Size) ){ + xcb_configure_window_value_list_t valList; + uint16_t mask = 0; + //if(props.contains(NativeWindow::Size)){ + QSize sz = vals[ props.indexOf(NativeWindow::Size) ] .toSize(); + valList.width = sz.width(); + valList.height = sz.height(); + mask = mask & XCB_CONFIG_WINDOW_WIDTH & XCB_CONFIG_WINDOW_HEIGHT; + //} + xcb_configure_window_aux(QX11Info::connection(), win->id(), mask, &valList); } if(props.contains(NativeWindow::Name)){ -- cgit From f7ef0f0a21d56e3c9c946c6f4010a713835c8cbe Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 10:41:12 -0400 Subject: Make sure the global position of a window is/can be set as needed. --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 12 +++++++++--- src-qt5/core/libLumina/RootSubWindow.cpp | 9 ++++++++- src-qt5/core/libLumina/RootSubWindow.h | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index d540d86e..791271cc 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -476,15 +476,21 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native if(props.contains(NativeWindow::Icon)){ } - if(props.contains(NativeWindow::Size) ){ + if(props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ xcb_configure_window_value_list_t valList; uint16_t mask = 0; - //if(props.contains(NativeWindow::Size)){ + if(props.contains(NativeWindow::Size)){ QSize sz = vals[ props.indexOf(NativeWindow::Size) ] .toSize(); valList.width = sz.width(); valList.height = sz.height(); mask = mask & XCB_CONFIG_WINDOW_WIDTH & XCB_CONFIG_WINDOW_HEIGHT; - //} + } + if(props.contains(NativeWindow::GlobalPos)){ + QPoint pt = vals[ props.indexOf(NativeWindow::GlobalPos) ] .toPoint(); + valList.x = pt.x(); + valList.y = pt.y(); + mask = mask & XCB_CONFIG_WINDOW_X & XCB_CONFIG_WINDOW_Y; + } xcb_configure_window_aux(QX11Info::connection(), win->id(), mask, &valList); } if(props.contains(NativeWindow::Name)){ diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 66cfbc6a..59cfc662 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -412,11 +412,18 @@ void RootSubWindow::leaveEvent(QEvent *ev){ }*/ void RootSubWindow::resizeEvent(QResizeEvent *ev){ - qDebug() << "Got Resize Event:" << ev->size(); + //qDebug() << "Got Resize Event:" << ev->size(); WIN->requestProperty(NativeWindow::Size, WinWidget->size()); QFrame::resizeEvent(ev); } + /*void RootSubWindow::showEvent(QShowEvent *ev){ WIN->requestProperty(NativeWindow::Visible, true); QFrame::showEvent(ev); }*/ + +void RootSubWindow::moveEvent(QMoveEvent *ev){ + //qDebug() << "Got Move Event:" << ev->pos(); + WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); + QFrame::moveEvent(ev); +} diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index e1b992c9..cb502107 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -78,7 +78,7 @@ protected: //void hideEvent(QHideEvent *ev); void resizeEvent(QResizeEvent *ev); //void showEvent(QShowEvent *ev); - //void moveEvent(QMoveEvent *ev); + void moveEvent(QMoveEvent *ev); }; -- cgit From d911eba7e870937803e68562729b38173cdd5857 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 11:02:42 -0400 Subject: Ensure that the Global Position (and Size) properties *always* reference the embedded window. Also make a new "geometry()" function in NativeWindow to return the full window+frame geometry. --- src-qt5/core/libLumina/NativeWindow.cpp | 10 ++++++++++ src-qt5/core/libLumina/NativeWindow.h | 2 ++ src-qt5/core/libLumina/RootSubWindow.cpp | 8 ++++---- 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index 68610ce2..8853c48e 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -75,6 +75,16 @@ void NativeWindow::requestProperties(QList props, QList< emit RequestPropertiesChange(winid, props, vals); } +QRect NativeWindow::geometry(){ + //Calculate the "full" geometry of the window + frame (if any) + QRect geom( hash.value(NativeWindow::GlobalPos).toPoint(), hash.value(NativeWindow::Size).toSize() ); + //Now adjust the window geom by the frame margins + QList frame = hash.value(NativeWindow::FrameExtents).value< QList >(); //Left,Right,Top,Bottom + if(frame.length()==4){ + geom = geom.adjusted( -frame[0], -frame[2], frame[1], frame[3] ); + } + return geom; +} // ==== PUBLIC SLOTS === void NativeWindow::requestClose(){ emit RequestClose(winid); diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index a1cb7c1a..c87ccb2d 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -71,6 +71,8 @@ public: void requestProperty(NativeWindow::Property, QVariant); void requestProperties(QList, QList); + QRect geometry(); //this returns the "full" geometry of the window (window + frame) + public slots: void requestClose(); //ask the app to close the window (may/not depending on activity) void requestKill(); //ask the WM to kill the app associated with this window (harsh - only use if not responding) diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 59cfc662..f17ee9a1 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -254,17 +254,17 @@ void RootSubWindow::propertiesChanged(QList props, QList break; case NativeWindow::Icon: //qDebug() << "Got Icon Change:" << vals[i]; - otherB->setIcon(vals[i].value< QIcon>()); + otherB->setIcon(vals[i].value()); break; case NativeWindow::GlobalPos: //qDebug() << "Got Global Pos:" << vals[i].toPoint(); - this->move( vals[i].toPoint() ); + this->move( WIN->geometry().topLeft() ); break; case NativeWindow::Size: qDebug() << "Got Widget Size:" << vals[i].toSize(); //WinWidget->setSizeHint( vals[i].toSize() ); //WinWidget->resize(vals[i].toSize() ); - this->resize( vals[i].toSize()+QSize( this->width()-WinWidget->width(), this->height()-WinWidget->height() ) ); + this->resize( WIN->geometry().size() ); qDebug() << " - Size after change:" << WinWidget->size() << this->size(); break; case NativeWindow::MinSize: @@ -305,7 +305,7 @@ void RootSubWindow::mousePressEvent(QMouseEvent *ev){ } void RootSubWindow::mouseMoveEvent(QMouseEvent *ev){ - //ev->accept(); + activate(); //make sure this window is "Active" if(activeState == Normal){ setMouseCursor( getStateAtPoint(ev->pos()) ); //just update the mouse cursor }else{ -- cgit From 44f14e37bd0ad573590d92cc6e1052b8d8711021 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 11:16:20 -0400 Subject: Clean up the handling of the frameExtents property quite a bit. --- src-qt5/core/libLumina/RootSubWindow.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index f17ee9a1..213e07ca 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -162,7 +162,7 @@ void RootSubWindow::initWindowFrame(){ titleLabel->setObjectName("Label_Title"); this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; }"); //And adjust the margins - mainLayout->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); + mainLayout->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); //default border mainLayout->setSpacing(0); titleBar->setSpacing(1); titleBar->setContentsMargins(0,0,0,0); @@ -175,6 +175,13 @@ void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ for(int i=0; iproperty(list[i]); + if(list[i] == NativeWindow::FrameExtents){ + if(vals[i].isNull()){ + QList frame; frame << WIN_BORDER << WIN_BORDER << WIN_BORDER+titleLabel->height() << WIN_BORDER; + vals[i] = QVariant::fromValue< QList >(frame); //use this by default + WIN->requestProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(frame)); //make sure these values get saved permanently + } + } qDebug() << "Property:" << list[i] << vals[i]; } propertiesChanged(list, vals); @@ -276,6 +283,9 @@ void RootSubWindow::propertiesChanged(QList props, QList case NativeWindow::Active: //if(vals[i].toBool()){ WinWidget->setFocus(); } break; + case NativeWindow::FrameExtents: + mainLayout->setContentsMargins( vals[i].value< QList >().at(0),vals[i].value< QList >().at(2) - titleLabel->height(),vals[i].value< QList >().at(1),vals[i].value< QList >().at(3)); + break; /*case NativeWindow::WindowFlags: this->setWindowFlags( val.value< Qt::WindowFlags >() ); break;*/ -- cgit From 1d301fca58db2a1ba171a1c3c423a7e32f6a059e Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 11:22:28 -0400 Subject: Oops - fix how the new/initial frame extents get saved into the structure.. --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 1 + src-qt5/core/libLumina/RootSubWindow.cpp | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 791271cc..5f2c8b6e 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -466,6 +466,7 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native } void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList vals){ + if(props.length() == 0 || vals.length()!=props.length() || win ==0 ){ return; } qDebug() << "Change Window Properties:" << props << vals; if(props.contains(NativeWindow::Title)){ diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 213e07ca..bbbbf644 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -180,6 +180,7 @@ void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ QList frame; frame << WIN_BORDER << WIN_BORDER << WIN_BORDER+titleLabel->height() << WIN_BORDER; vals[i] = QVariant::fromValue< QList >(frame); //use this by default WIN->requestProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(frame)); //make sure these values get saved permanently + WIN->setProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(frame)); } } qDebug() << "Property:" << list[i] << vals[i]; @@ -271,6 +272,7 @@ void RootSubWindow::propertiesChanged(QList props, QList qDebug() << "Got Widget Size:" << vals[i].toSize(); //WinWidget->setSizeHint( vals[i].toSize() ); //WinWidget->resize(vals[i].toSize() ); + WinWidget->resize(vals[i].toSize()); this->resize( WIN->geometry().size() ); qDebug() << " - Size after change:" << WinWidget->size() << this->size(); break; -- cgit From 9134d5971398e6de38465ca47b583d32bf8aaf94 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 11:50:20 -0400 Subject: Try to fix up the looping of the size/resize between X and the window --- src-qt5/core/libLumina/RootSubWindow.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index bbbbf644..075f94c5 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -269,12 +269,12 @@ void RootSubWindow::propertiesChanged(QList props, QList this->move( WIN->geometry().topLeft() ); break; case NativeWindow::Size: - qDebug() << "Got Widget Size:" << vals[i].toSize(); - //WinWidget->setSizeHint( vals[i].toSize() ); - //WinWidget->resize(vals[i].toSize() ); - WinWidget->resize(vals[i].toSize()); - this->resize( WIN->geometry().size() ); - qDebug() << " - Size after change:" << WinWidget->size() << this->size(); + if(WinWidget->size() != vals[i].toSize()){ + qDebug() << "Got Widget Size Change:" << vals[i].toSize(); + WinWidget->resize(vals[i].toSize()); + this->resize( WIN->geometry().size() ); + qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); + } break; case NativeWindow::MinSize: WinWidget->setMinimumSize(vals[i].toSize()); @@ -425,7 +425,9 @@ void RootSubWindow::leaveEvent(QEvent *ev){ void RootSubWindow::resizeEvent(QResizeEvent *ev){ //qDebug() << "Got Resize Event:" << ev->size(); - WIN->requestProperty(NativeWindow::Size, WinWidget->size()); + if(WinWidget->size() != WIN->property(NativeWindow::Size).toSize()){ + WIN->requestProperty(NativeWindow::Size, WinWidget->size()); + } QFrame::resizeEvent(ev); } -- cgit From 1030649f5c8e831f1e7abae0b999173c6aed65ec Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 11:53:39 -0400 Subject: Quick fix to disable setting the new global position on window move (temporary) --- src-qt5/core/libLumina/RootSubWindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 075f94c5..190ec3aa 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -265,7 +265,7 @@ void RootSubWindow::propertiesChanged(QList props, QList otherB->setIcon(vals[i].value()); break; case NativeWindow::GlobalPos: - //qDebug() << "Got Global Pos:" << vals[i].toPoint(); + qDebug() << "Got Global Pos:" << vals[i].toPoint(); this->move( WIN->geometry().topLeft() ); break; case NativeWindow::Size: @@ -437,7 +437,7 @@ void RootSubWindow::resizeEvent(QResizeEvent *ev){ }*/ void RootSubWindow::moveEvent(QMoveEvent *ev){ - //qDebug() << "Got Move Event:" << ev->pos(); - WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); + qDebug() << "Got Move Event:" << ev->pos() << WinWidget->mapToGlobal(QPoint(0,0)); + //WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); QFrame::moveEvent(ev); } -- cgit From a06db39550f3ee0a96dd5e75aa4a5cc724587324 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 12:00:02 -0400 Subject: Fix the bitwise operations for the resize XCB operation --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 5f2c8b6e..cea0e924 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -484,13 +484,13 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native QSize sz = vals[ props.indexOf(NativeWindow::Size) ] .toSize(); valList.width = sz.width(); valList.height = sz.height(); - mask = mask & XCB_CONFIG_WINDOW_WIDTH & XCB_CONFIG_WINDOW_HEIGHT; + mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; } if(props.contains(NativeWindow::GlobalPos)){ QPoint pt = vals[ props.indexOf(NativeWindow::GlobalPos) ] .toPoint(); valList.x = pt.x(); valList.y = pt.y(); - mask = mask & XCB_CONFIG_WINDOW_X & XCB_CONFIG_WINDOW_Y; + mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; } xcb_configure_window_aux(QX11Info::connection(), win->id(), mask, &valList); } -- cgit From 9a8aa1fdf09be158a35737c3331ca1e08d844993 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 12:13:12 -0400 Subject: Quick change to some debugging --- src-qt5/core/libLumina/RootSubWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 190ec3aa..568c5dee 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -265,7 +265,7 @@ void RootSubWindow::propertiesChanged(QList props, QList otherB->setIcon(vals[i].value()); break; case NativeWindow::GlobalPos: - qDebug() << "Got Global Pos:" << vals[i].toPoint(); + qDebug() << "Got Global Pos:" << WIN->geometry().topLeft() << vals[i].toPoint(); this->move( WIN->geometry().topLeft() ); break; case NativeWindow::Size: -- cgit From 4f98326bc7c3b8f93c0f86059c813bdf866c2ddf Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 12:41:49 -0400 Subject: Fix up the saving/using of the global position property --- src-qt5/core/libLumina/RootSubWindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 568c5dee..abaceca2 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -265,8 +265,8 @@ void RootSubWindow::propertiesChanged(QList props, QList otherB->setIcon(vals[i].value()); break; case NativeWindow::GlobalPos: - qDebug() << "Got Global Pos:" << WIN->geometry().topLeft() << vals[i].toPoint(); - this->move( WIN->geometry().topLeft() ); + qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); + this->move( vals[i].toPoint() - (WinWidget->mapToGlobal(QPoint(0,0)) - this->pos()) ); //WIN->geometry().topLeft() ); break; case NativeWindow::Size: if(WinWidget->size() != vals[i].toSize()){ @@ -438,6 +438,6 @@ void RootSubWindow::resizeEvent(QResizeEvent *ev){ void RootSubWindow::moveEvent(QMoveEvent *ev){ qDebug() << "Got Move Event:" << ev->pos() << WinWidget->mapToGlobal(QPoint(0,0)); - //WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); + WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); QFrame::moveEvent(ev); } -- cgit From c4e76b7425783af1e72ea76b8ab885e97abe9b0b Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 12:48:09 -0400 Subject: Try to fix up the set geometry/position routine so it does not change the other property --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index cea0e924..b076f474 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -485,12 +485,18 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native valList.width = sz.width(); valList.height = sz.height(); mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + }else{ + valList.width = win->property(NativeWindow::Size).toSize().width(); + valList.height = win->property(NativeWindow::Size).toSize().height(); } if(props.contains(NativeWindow::GlobalPos)){ QPoint pt = vals[ props.indexOf(NativeWindow::GlobalPos) ] .toPoint(); valList.x = pt.x(); valList.y = pt.y(); mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; + }else{ + valList.x = win->property(NativeWindow::GlobalPos).toPoint().x(); + valList.y = win->property(NativeWindow::GlobalPos).toPoint().y(); } xcb_configure_window_aux(QX11Info::connection(), win->id(), mask, &valList); } -- cgit From 796d84c2a1716002c07cdfc9dfabc3f8dc718df9 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 12:57:13 -0400 Subject: Ensure that we never change the x11 position property on a window - that should always be (0,0) relative to the parent. --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index b076f474..9359b9f2 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -477,19 +477,19 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native if(props.contains(NativeWindow::Icon)){ } - if(props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ + if(props.contains(NativeWindow::Size) ){//|| props.contains(NativeWindow::GlobalPos) ){ xcb_configure_window_value_list_t valList; uint16_t mask = 0; - if(props.contains(NativeWindow::Size)){ + //if(props.contains(NativeWindow::Size)){ QSize sz = vals[ props.indexOf(NativeWindow::Size) ] .toSize(); valList.width = sz.width(); valList.height = sz.height(); mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - }else{ + /*}else{ valList.width = win->property(NativeWindow::Size).toSize().width(); valList.height = win->property(NativeWindow::Size).toSize().height(); - } - if(props.contains(NativeWindow::GlobalPos)){ + }*/ + /*if(props.contains(NativeWindow::GlobalPos)){ QPoint pt = vals[ props.indexOf(NativeWindow::GlobalPos) ] .toPoint(); valList.x = pt.x(); valList.y = pt.y(); @@ -497,7 +497,7 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native }else{ valList.x = win->property(NativeWindow::GlobalPos).toPoint().x(); valList.y = win->property(NativeWindow::GlobalPos).toPoint().y(); - } + }*/ xcb_configure_window_aux(QX11Info::connection(), win->id(), mask, &valList); } if(props.contains(NativeWindow::Name)){ -- cgit From a4b1242e9516a52f0b0b3dc3377f5fd1620ce5a6 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 13:00:34 -0400 Subject: de-activate the global position change notifications within the event filter - the WM handles that. --- src-qt5/core/libLumina/NativeEventFilter.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp index 28432222..754bdb8f 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -227,10 +227,12 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, //============================== case XCB_CONFIGURE_NOTIFY: //qDebug() << "Configure Notify Event"; - obj->emit WindowPropertiesChanged( ((xcb_configure_notify_event_t*)ev)->window, + /*obj->emit WindowPropertiesChanged( ((xcb_configure_notify_event_t*)ev)->window, QList() << NativeWindow::GlobalPos << NativeWindow::Size, QList() << QPoint(((xcb_configure_notify_event_t*)ev)->x, ((xcb_configure_notify_event_t*)ev)->y) << - QSize(((xcb_configure_notify_event_t*)ev)->width, ((xcb_configure_notify_event_t*)ev)->height) ); + QSize(((xcb_configure_notify_event_t*)ev)->width, ((xcb_configure_notify_event_t*)ev)->height) );*/ + obj->emit WindowPropertyChanged( ((xcb_configure_notify_event_t*)ev)->window, NativeWindow::Size, + QSize(((xcb_configure_notify_event_t*)ev)->width, ((xcb_configure_notify_event_t*)ev)->height) ); break; //============================== case XCB_CONFIGURE_REQUEST: -- cgit From 5a3ce5ac4fbc5f2169ab9eb7330e2096c73dd639 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 13:16:53 -0400 Subject: Get the RootSubWindow loading/using icons for the various buttons now. --- src-qt5/core/libLumina/LIconCache.h | 2 +- src-qt5/core/libLumina/RootSubWindow.cpp | 12 +++++++++--- src-qt5/core/libLumina/RootWindow.pri | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LIconCache.h b/src-qt5/core/libLumina/LIconCache.h index 0344e0f3..f58a5510 100644 --- a/src-qt5/core/libLumina/LIconCache.h +++ b/src-qt5/core/libLumina/LIconCache.h @@ -69,7 +69,7 @@ private: private slots: void IconLoaded(QString id, QDateTime sync, QByteArray *data); - + signals: void InternalIconLoaded(QString, QDateTime, QByteArray*); //INTERNAL SIGNAL - DO NOT USE in other classes/objects void IconAvailable(QString); //way for classes to listen/reload icons as they change diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index abaceca2..d2ec7503 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -13,6 +13,8 @@ #define WIN_BORDER 5 +#include + // === PUBLIC === RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ this->setAttribute(Qt::WA_DeleteOnClose); @@ -166,8 +168,11 @@ void RootSubWindow::initWindowFrame(){ mainLayout->setSpacing(0); titleBar->setSpacing(1); titleBar->setContentsMargins(0,0,0,0); - //this->setLayout(mainLayout); - //qDebug() << " - Done"; + //Now load the icons for the button + LIconCache::instance()->loadIcon(closeB, "window-close"); + LIconCache::instance()->loadIcon(maxB, "window-maximize"); + LIconCache::instance()->loadIcon(minB, "window-minimize"); + LIconCache::instance()->loadIcon(otherB, "list"); } void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ @@ -262,7 +267,8 @@ void RootSubWindow::propertiesChanged(QList props, QList break; case NativeWindow::Icon: //qDebug() << "Got Icon Change:" << vals[i]; - otherB->setIcon(vals[i].value()); + if(vals[i].value().isNull() ){ LIconCache::instance()->loadIcon(otherB, "window-close"); } + else{ otherB->setIcon(vals[i].value()); } break; case NativeWindow::GlobalPos: qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); diff --git a/src-qt5/core/libLumina/RootWindow.pri b/src-qt5/core/libLumina/RootWindow.pri index 35e0e770..e4d5f00b 100644 --- a/src-qt5/core/libLumina/RootWindow.pri +++ b/src-qt5/core/libLumina/RootWindow.pri @@ -10,4 +10,5 @@ INCLUDEPATH *= ${PWD} # include other library dependencies include(LUtils.pri) -include(NativeWindow.pri); +include(NativeWindow.pri) +include(LIconCache.pri) -- cgit From 8fb12e24a67156e0ed6087592a4c5fe564f4462d Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 13:20:59 -0400 Subject: Also clean up the default stylesheet for the window frame right now --- src-qt5/core/libLumina/RootSubWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index d2ec7503..cab02db4 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -162,7 +162,7 @@ void RootSubWindow::initWindowFrame(){ maxB->setObjectName("Button_Maximize"); otherM->setObjectName("Menu_Actions"); titleLabel->setObjectName("Label_Title"); - this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; }"); + this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border-color: transparent; } QToolButton::hover{border-color: white;}"); //And adjust the margins mainLayout->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); //default border mainLayout->setSpacing(0); -- cgit From 1325f89e7b9b8baee10c47ef8473bffd5052e9b5 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 13:29:00 -0400 Subject: Some more tweaks to the default stylesheet for the window frame. --- src-qt5/core/libLumina/RootSubWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index cab02db4..1814776a 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -162,7 +162,7 @@ void RootSubWindow::initWindowFrame(){ maxB->setObjectName("Button_Maximize"); otherM->setObjectName("Menu_Actions"); titleLabel->setObjectName("Label_Title"); - this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border-color: transparent; } QToolButton::hover{border-color: white;}"); + this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border: 1px solid transparent; } QToolButton::hover{border-color: white;} QToolButton::menu-arrow{ image: none; }"); //And adjust the margins mainLayout->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); //default border mainLayout->setSpacing(0); -- cgit From 06e86f64225d09ce1896f1ba860dbb1cedd71568 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 13:40:19 -0400 Subject: Add in a "show" animation for windows when they appear This is a good example of how animations can be setup/used in the window --- src-qt5/core/libLumina/RootSubWindow.cpp | 14 ++++++++++++-- src-qt5/core/libLumina/RootSubWindow.h | 3 +++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 1814776a..bf242eff 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -136,6 +136,9 @@ void RootSubWindow::initWindowFrame(){ maxB = new QToolButton(this); minB = new QToolButton(this); otherB = new QToolButton(this); + anim = new QPropertyAnimation(this); + anim->setTargetObject(this); + anim->setDuration(300); //1/3 second (appx) titleLabel = new QLabel(this); titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); otherM = new QMenu(this); //menu of other actions @@ -162,12 +165,13 @@ void RootSubWindow::initWindowFrame(){ maxB->setObjectName("Button_Maximize"); otherM->setObjectName("Menu_Actions"); titleLabel->setObjectName("Label_Title"); - this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border: 1px solid transparent; } QToolButton::hover{border-color: white;} QToolButton::menu-arrow{ image: none; }"); + this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border: 1px solid transparent; } QToolButton::hover{border-color: white;} QToolButton::pressed{ background-color: white; } QToolButton::menu-arrow{ image: none; }"); //And adjust the margins mainLayout->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); //default border mainLayout->setSpacing(0); titleBar->setSpacing(1); titleBar->setContentsMargins(0,0,0,0); + //Now load the icons for the button LIconCache::instance()->loadIcon(closeB, "window-close"); LIconCache::instance()->loadIcon(maxB, "window-maximize"); @@ -259,7 +263,13 @@ void RootSubWindow::propertiesChanged(QList props, QList switch(props[i]){ case NativeWindow::Visible: //qDebug() << "Got Visibility Change:" << vals[i]; - if(vals[i].toBool()){ WinWidget->setVisible(true); this->show(); } + if(vals[i].toBool()){ + WinWidget->setVisible(true); + this->show(); + anim->setPropertyName("windowOpacity"); + anim->setStartValue(0.0); anim->setEndValue(1.0); + anim->start(); + } else{ this->hide(); } break; case NativeWindow::Title: diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index cb502107..5e291aa3 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -47,6 +48,8 @@ private: QToolButton *closeB, *maxB, *minB, *otherB; QLabel *titleLabel; QMenu *otherM; //menu of other actions + //Other random objects (animations,etc) + QPropertyAnimation *anim; void initWindowFrame(); void LoadProperties( QList< NativeWindow::Property> list); -- cgit From 8e9676547274d3bd63d5f54a583ceb79f775f359 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 13:49:55 -0400 Subject: Make sure we set the root flag that window opacity is supported. --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 7 ++++--- src-qt5/core/libLumina/RootSubWindow.cpp | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 9359b9f2..d90b9dc1 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -65,7 +65,7 @@ public: } QStringList atoms; - atoms << "WM_TAKE_FOCUS" << "WM_DELETE_WINDOW" << "WM_PROTOCOLS" + atoms << "WM_TAKE_FOCUS" << "WM_DELETE_WINDOW" << "WM_PROTOCOLS" << "_NET_WM_WINDOW_OPACITY" << "WM_CHANGE_STATE" << "_NET_SYSTEM_TRAY_OPCODE" << "_NET_SYSTEM_TRAY_ORIENTATION" << "_NET_SYSTEM_TRAY_VISUAL" << QString("_NET_SYSTEM_TRAY_S%1").arg(QString::number(QX11Info::appScreen())); //Create all the requests for the atoms @@ -560,14 +560,15 @@ void NativeWindowSystem::setRoot_supportedActions(){ obj->EWMH._NET_WM_ICON, obj->EWMH._NET_WM_ICON_NAME, obj->EWMH._NET_WM_DESKTOP, - /*_NET_WINDOW_TYPE (and all the various types)*/ + obj->ATOMS["_NET_WM_WINDOW_OPACITY"], + /*_NET_WINDOW_TYPE (and all the various types - 15 in total*/ obj->EWMH._NET_WM_WINDOW_TYPE, obj->EWMH._NET_WM_WINDOW_TYPE_DESKTOP, obj->EWMH._NET_WM_WINDOW_TYPE_DOCK, obj->EWMH._NET_WM_WINDOW_TYPE_TOOLBAR, obj->EWMH._NET_WM_WINDOW_TYPE_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_UTILITY, obj->EWMH._NET_WM_WINDOW_TYPE_SPLASH, obj->EWMH._NET_WM_WINDOW_TYPE_DIALOG, obj->EWMH._NET_WM_WINDOW_TYPE_NORMAL, obj->EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_TOOLTIP, obj->EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION, obj->EWMH._NET_WM_WINDOW_TYPE_COMBO, obj->EWMH._NET_WM_WINDOW_TYPE_DND, }; - xcb_ewmh_set_supported(&obj->EWMH, QX11Info::appScreen(), 19,list); + xcb_ewmh_set_supported(&obj->EWMH, QX11Info::appScreen(), 20,list); } void NativeWindowSystem::setRoot_numberOfWorkspaces(QStringList names){ diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index bf242eff..88dca132 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -265,10 +265,10 @@ void RootSubWindow::propertiesChanged(QList props, QList //qDebug() << "Got Visibility Change:" << vals[i]; if(vals[i].toBool()){ WinWidget->setVisible(true); - this->show(); anim->setPropertyName("windowOpacity"); anim->setStartValue(0.0); anim->setEndValue(1.0); anim->start(); + this->show(); } else{ this->hide(); } break; -- cgit From 1b8947f958d5ad1600a9eff5fe5fdf0f327d6926 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 14:08:35 -0400 Subject: Add some window close debugging, and change the setVisible animation to a window zoom rather than opacity (the frame is not technically an independant window). --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 2 ++ src-qt5/core/libLumina/RootSubWindow.cpp | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index d90b9dc1..ad5c969c 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -721,9 +721,11 @@ void NativeWindowSystem::WindowCloseDetected(WId id){ NativeWindow *win = findWindow(id); qDebug() << "Got Window Closed" << id << win; if(win!=0){ + qDebug() << "Old Window List:" << NWindows.length(); NWindows.removeAll(win); win->emit WindowClosed(id); win->deleteLater(); + qDebug() << " - Now:" << NWindows.length(); }else{ win = findTrayWindow(id); if(win!=0){ diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 88dca132..0aa97c54 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -265,8 +265,9 @@ void RootSubWindow::propertiesChanged(QList props, QList //qDebug() << "Got Visibility Change:" << vals[i]; if(vals[i].toBool()){ WinWidget->setVisible(true); - anim->setPropertyName("windowOpacity"); - anim->setStartValue(0.0); anim->setEndValue(1.0); + anim->setPropertyName("geometry"); + anim->setStartValue( QRect(this->geometry().center(), QSize(0,0)) ); + anim->setEndValue(this->geometry()); anim->start(); this->show(); } -- cgit From a512f8b35b20fe2c1ab8f1c26a2261b22dc0a253 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 14:25:50 -0400 Subject: Clean up a bunch of debugging, and add a "closing" animation to the rootSubWindow as well. --- src-qt5/core/libLumina/NativeEventFilter.cpp | 6 +++--- src-qt5/core/libLumina/NativeWindowSystem.cpp | 14 ++++++++------ src-qt5/core/libLumina/NativeWindowSystem.h | 2 +- src-qt5/core/libLumina/RootSubWindow.cpp | 20 +++++++++++++------- 4 files changed, 25 insertions(+), 17 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp index 754bdb8f..74402690 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -177,7 +177,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, break; //============================== case XCB_MAP_NOTIFY: - qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; + //qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible, true); break; //This is just a notification that a window was mapped - nothing needs to change here case XCB_MAP_REQUEST: @@ -186,11 +186,11 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, break; //============================== case XCB_CREATE_NOTIFY: - qDebug() << "Window Create Event"; + //qDebug() << "Window Create Event"; break; //============================== case XCB_UNMAP_NOTIFY: - qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; + //qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible, false); break; //============================== diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index ad5c969c..82ce8d1f 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -263,15 +263,17 @@ NativeWindowSystem::MouseButton NativeWindowSystem::MouseToQt(int keycode){ } // === PRIVATE === -NativeWindow* NativeWindowSystem::findWindow(WId id){ +NativeWindow* NativeWindowSystem::findWindow(WId id, bool checkRelated){ //qDebug() << "Find Window:" << id; for(int i=0; iisRelatedTo(id)){ qDebug() << " -- Got Window Match!" << id; return NWindows[i]; } + if(NWindows[i]->isRelatedTo(id)){ return NWindows[i]; } } //Check to see if this is a transient for some other window - WId tid = obj->getTransientFor(id); - if(tid!=id){ return findWindow(tid); } //call it recursively as needed - //qDebug() << " -- Could not find Window!"; + if(checkRelated){ + WId tid = obj->getTransientFor(id); + if(tid!=id){ return findWindow(tid, checkRelated); } //call it recursively as needed + //qDebug() << " -- Could not find Window!"; + } return 0; } @@ -718,7 +720,7 @@ void NativeWindowSystem::NewTrayWindowDetected(WId id){ } void NativeWindowSystem::WindowCloseDetected(WId id){ - NativeWindow *win = findWindow(id); + NativeWindow *win = findWindow(id, false); qDebug() << "Got Window Closed" << id << win; if(win!=0){ qDebug() << "Old Window List:" << NWindows.length(); diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h index 7786c87d..008a204f 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/core/libLumina/NativeWindowSystem.h @@ -23,7 +23,7 @@ private: QList TWindows; //Simplifications to find an already-created window object - NativeWindow* findWindow(WId id); + NativeWindow* findWindow(WId id, bool checkRelated = true); NativeWindow* findTrayWindow(WId id); diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 0aa97c54..eae5aa39 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -138,7 +138,7 @@ void RootSubWindow::initWindowFrame(){ otherB = new QToolButton(this); anim = new QPropertyAnimation(this); anim->setTargetObject(this); - anim->setDuration(300); //1/3 second (appx) + anim->setDuration(200); //1/5 second (appx) titleLabel = new QLabel(this); titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); otherM = new QMenu(this); //menu of other actions @@ -165,7 +165,7 @@ void RootSubWindow::initWindowFrame(){ maxB->setObjectName("Button_Maximize"); otherM->setObjectName("Menu_Actions"); titleLabel->setObjectName("Label_Title"); - this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border: 1px solid transparent; } QToolButton::hover{border-color: white;} QToolButton::pressed{ background-color: white; } QToolButton::menu-arrow{ image: none; }"); + this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border: 1px solid transparent; border-radius: 3px; } QToolButton::hover{background-color: rgba(255,255,255,150); } QToolButton::pressed{ background-color: white; } QToolButton::menu-arrow{ image: none; }"); //And adjust the margins mainLayout->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); //default border mainLayout->setSpacing(0); @@ -266,12 +266,18 @@ void RootSubWindow::propertiesChanged(QList props, QList if(vals[i].toBool()){ WinWidget->setVisible(true); anim->setPropertyName("geometry"); - anim->setStartValue( QRect(this->geometry().center(), QSize(0,0)) ); + anim->setStartValue( QRect(this->geometry().center(), QSize(0,0)) ); anim->setEndValue(this->geometry()); anim->start(); this->show(); + }else{ + anim->setPropertyName("geometry"); + anim->setStartValue(this->geometry()); + anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); + anim->start(); + QTimer::singleShot(anim->duration(), this, SLOT(hide()) ); + //this->hide(); } - else{ this->hide(); } break; case NativeWindow::Title: titleLabel->setText(vals[i].toString()); @@ -282,12 +288,12 @@ void RootSubWindow::propertiesChanged(QList props, QList else{ otherB->setIcon(vals[i].value()); } break; case NativeWindow::GlobalPos: - qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); + //qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); this->move( vals[i].toPoint() - (WinWidget->mapToGlobal(QPoint(0,0)) - this->pos()) ); //WIN->geometry().topLeft() ); break; case NativeWindow::Size: if(WinWidget->size() != vals[i].toSize()){ - qDebug() << "Got Widget Size Change:" << vals[i].toSize(); + //qDebug() << "Got Widget Size Change:" << vals[i].toSize(); WinWidget->resize(vals[i].toSize()); this->resize( WIN->geometry().size() ); qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); @@ -454,7 +460,7 @@ void RootSubWindow::resizeEvent(QResizeEvent *ev){ }*/ void RootSubWindow::moveEvent(QMoveEvent *ev){ - qDebug() << "Got Move Event:" << ev->pos() << WinWidget->mapToGlobal(QPoint(0,0)); + //qDebug() << "Got Move Event:" << ev->pos() << WinWidget->mapToGlobal(QPoint(0,0)); WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); QFrame::moveEvent(ev); } -- cgit From f5aa2fcb72bdfdcf7025912b277d9aaf20e038a0 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 14:31:32 -0400 Subject: Try to fix up some window close/re-open issues --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 82ce8d1f..c80920c8 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -469,7 +469,7 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList vals){ if(props.length() == 0 || vals.length()!=props.length() || win ==0 ){ return; } - qDebug() << "Change Window Properties:" << props << vals; + //qDebug() << "Change Window Properties:" << props << vals; if(props.contains(NativeWindow::Title)){ } @@ -513,12 +513,12 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native } if(props.contains(NativeWindow::Visible)){ - qDebug() << "Check Window Visibility:" << vals[ props.indexOf(NativeWindow::Visible) ]; + //qDebug() << "Check Window Visibility:" << vals[ props.indexOf(NativeWindow::Visible) ]; if( vals[ props.indexOf(NativeWindow::Visible) ].toBool() ){ - qDebug() << " - Map it!"; + //qDebug() << " - Map it!"; xcb_map_window(QX11Info::connection(), win->id()); }else{ - qDebug() << " - Unmap it!"; + //qDebug() << " - Unmap it!"; xcb_unmap_window(QX11Info::connection(), win->id()); } } @@ -657,7 +657,7 @@ int NativeWindowSystem::currentWorkspace(){ //NativeWindowEventFilter interactions void NativeWindowSystem::NewWindowDetected(WId id){ //Make sure this can be managed first - if(findWindow(id) != 0){ return; } //already managed + if(findWindow(id, false) != 0){ qDebug() << "Window Already Managed!!!!"; return; } //already managed xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(QX11Info::connection(), id); xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(QX11Info::connection(), cookie, NULL); if(attr == 0){ return; } //could not get attributes of window -- cgit From acfb339551b824f1e89c24364df9c9f330fd8549 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 14:42:08 -0400 Subject: Some more fixes for the window animations --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 4 ++-- src-qt5/core/libLumina/RootSubWindow.cpp | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index c80920c8..9c55062d 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -722,12 +722,11 @@ void NativeWindowSystem::NewTrayWindowDetected(WId id){ void NativeWindowSystem::WindowCloseDetected(WId id){ NativeWindow *win = findWindow(id, false); qDebug() << "Got Window Closed" << id << win; + qDebug() << "Old Window List:" << NWindows.length(); if(win!=0){ - qDebug() << "Old Window List:" << NWindows.length(); NWindows.removeAll(win); win->emit WindowClosed(id); win->deleteLater(); - qDebug() << " - Now:" << NWindows.length(); }else{ win = findTrayWindow(id); if(win!=0){ @@ -736,6 +735,7 @@ void NativeWindowSystem::WindowCloseDetected(WId id){ win->deleteLater(); } } + qDebug() << " - Now:" << NWindows.length(); } void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop){ diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index eae5aa39..80d5c82b 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -202,7 +202,12 @@ void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ void RootSubWindow::clientClosed(){ qDebug() << "Client Closed"; closing = true; - this->close(); + anim->setPropertyName("geometry"); + anim->setStartValue(this->geometry()); + anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); + anim->start(); + QTimer::singleShot(anim->duration(), this, SLOT(close()) ); + //this->close(); } void RootSubWindow::LoadAllProperties(){ @@ -266,8 +271,8 @@ void RootSubWindow::propertiesChanged(QList props, QList if(vals[i].toBool()){ WinWidget->setVisible(true); anim->setPropertyName("geometry"); - anim->setStartValue( QRect(this->geometry().center(), QSize(0,0)) ); - anim->setEndValue(this->geometry()); + anim->setStartValue( QRect(WIN->geometry().center(), QSize(0,0)) ); + anim->setEndValue(WIN->geometry()); anim->start(); this->show(); }else{ @@ -284,7 +289,7 @@ void RootSubWindow::propertiesChanged(QList props, QList break; case NativeWindow::Icon: //qDebug() << "Got Icon Change:" << vals[i]; - if(vals[i].value().isNull() ){ LIconCache::instance()->loadIcon(otherB, "window-close"); } + if(vals[i].value().isNull() ){ LIconCache::instance()->loadIcon(otherB, "list"); } else{ otherB->setIcon(vals[i].value()); } break; case NativeWindow::GlobalPos: @@ -448,7 +453,7 @@ void RootSubWindow::leaveEvent(QEvent *ev){ void RootSubWindow::resizeEvent(QResizeEvent *ev){ //qDebug() << "Got Resize Event:" << ev->size(); - if(WinWidget->size() != WIN->property(NativeWindow::Size).toSize()){ + if(WinWidget->size() != WIN->property(NativeWindow::Size).toSize() && anim->state()!=QAbstractAnimation::Running){ WIN->requestProperty(NativeWindow::Size, WinWidget->size()); } QFrame::resizeEvent(ev); @@ -461,6 +466,6 @@ void RootSubWindow::resizeEvent(QResizeEvent *ev){ void RootSubWindow::moveEvent(QMoveEvent *ev){ //qDebug() << "Got Move Event:" << ev->pos() << WinWidget->mapToGlobal(QPoint(0,0)); - WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); + if(!closing && anim->state()!=QAbstractAnimation::Running){ WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); } QFrame::moveEvent(ev); } -- cgit From e0e184fab30995de316bb6c9bb111785ad9d4f6b Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 14:46:57 -0400 Subject: Add an animation finished routine so we can re-load any Window settings which are ignored during the animation. --- src-qt5/core/libLumina/RootSubWindow.cpp | 8 ++++++-- src-qt5/core/libLumina/RootSubWindow.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 80d5c82b..d5a2795d 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -139,6 +139,7 @@ void RootSubWindow::initWindowFrame(){ anim = new QPropertyAnimation(this); anim->setTargetObject(this); anim->setDuration(200); //1/5 second (appx) + connect(anim, SIGNAL(finished()), this, SLOT(animFinished()) ); titleLabel = new QLabel(this); titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); otherM = new QMenu(this); //menu of other actions @@ -258,8 +259,6 @@ void RootSubWindow::startResizing(){ } - - // === PRIVATE SLOTS === void RootSubWindow::propertiesChanged(QList props, QList vals){ for(int i=0; i props, QList } } +void RootSubWindow::animFinished(){ + if(anim->propertyName()=="geometry"){ this->setGeometry(this->geometry()); } //make sure to send one more resize/move event + +} + // === PROTECTED === void RootSubWindow::mousePressEvent(QMouseEvent *ev){ //qDebug() << "Frame Mouse Press Event"; diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index 5e291aa3..25c6596a 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -71,6 +71,7 @@ public slots: private slots: void propertiesChanged(QList, QList); + void animFinished(); protected: void mousePressEvent(QMouseEvent*); -- cgit From aff9df01be61d2fb969ba38ba8c5721fac8384f6 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 14:50:28 -0400 Subject: Fix up the animation finished routine - should work fine now --- src-qt5/core/libLumina/RootSubWindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index d5a2795d..2e773e9d 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -325,7 +325,10 @@ void RootSubWindow::propertiesChanged(QList props, QList } void RootSubWindow::animFinished(){ - if(anim->propertyName()=="geometry"){ this->setGeometry(this->geometry()); } //make sure to send one more resize/move event + if(anim->propertyName()=="geometry"){ + WIN->requestProperty(NativeWindow::Size, WinWidget->size()); + WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); + } } -- cgit From 5911c0b061840588626edee15d44ffbe16470301 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 14:55:39 -0400 Subject: add some debugging for the new window routine (need window ID's) --- src-qt5/core/libLumina/RootSubWindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 2e773e9d..9eb1ff58 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -28,6 +28,7 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ connect(WIN, SIGNAL(PropertiesChanged(QList, QList)), this, SLOT(propertiesChanged(QList, QList))); WIN->addFrameWinID(WinWidget->winId()); WIN->emit RequestReparent(WIN->id(), WinWidget->winId(), QPoint(0,0)); + qDebug() << "[NEW WINDOW]" << WIN->id() << WinWidget->winId() << this->winId(); LoadAllProperties(); //QTimer::singleShot(20, this, SLOT(LoadAllProperties()) ); } @@ -300,7 +301,7 @@ void RootSubWindow::propertiesChanged(QList props, QList //qDebug() << "Got Widget Size Change:" << vals[i].toSize(); WinWidget->resize(vals[i].toSize()); this->resize( WIN->geometry().size() ); - qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); + //qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); } break; case NativeWindow::MinSize: -- cgit From e4823c69c27494cf206cc9b856303deb08740579 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 15:01:06 -0400 Subject: Add a secondary window ID for all window destroy events. --- src-qt5/core/libLumina/NativeEventFilter.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp index 74402690..dba3146b 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -197,6 +197,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, case XCB_DESTROY_NOTIFY: qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; obj->emit WindowDestroyed( ((xcb_destroy_notify_event_t *) ev)->window ); + obj->emit WindowDestroyed( ((xcb_destroy_notify_event_t *) ev)->event ); //sometimes this is the right window instead (window that sent the event) break; //============================== case XCB_FOCUS_IN: -- cgit From 0c877d64113f029e953d3bf27e47ca2c3d21b19c Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 15:05:04 -0400 Subject: Back out that secondary close ID - unrelated to the actual window that was closed (some internal event identifier) --- src-qt5/core/libLumina/NativeEventFilter.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp index dba3146b..74402690 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -197,7 +197,6 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, case XCB_DESTROY_NOTIFY: qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; obj->emit WindowDestroyed( ((xcb_destroy_notify_event_t *) ev)->window ); - obj->emit WindowDestroyed( ((xcb_destroy_notify_event_t *) ev)->event ); //sometimes this is the right window instead (window that sent the event) break; //============================== case XCB_FOCUS_IN: -- cgit From 3cc4bb91529afd0a3454a3db86a7d8a7f51fde96 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 29 Jun 2017 22:31:49 -0400 Subject: Commit another large block of work on Lumina2. 1. Starting to get the compositing put together, but not functional yet. 2. Get the window close routines completely finished, with memory being freed properly on close. 3. Get some of the "reset" of window properties after an animation all setup. Not quite finished yet. --- src-qt5/core/libLumina/NativeEventFilter.cpp | 6 +- src-qt5/core/libLumina/NativeWindow.cpp | 43 +++++--- src-qt5/core/libLumina/NativeWindow.h | 17 ++-- src-qt5/core/libLumina/NativeWindowSystem.cpp | 135 ++++++++++++++++++++------ src-qt5/core/libLumina/RootSubWindow.cpp | 42 +++++--- src-qt5/core/libLumina/RootSubWindow.h | 1 + src-qt5/core/libLumina/RootWindow.cpp | 2 +- 7 files changed, 178 insertions(+), 68 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp index 74402690..b85965ef 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -181,7 +181,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible, true); break; //This is just a notification that a window was mapped - nothing needs to change here case XCB_MAP_REQUEST: - qDebug() << "Window Map Request Event"; + //qDebug() << "Window Map Request Event"; obj->emit WindowCreated( ((xcb_map_request_event_t *) ev)->window ); break; //============================== @@ -195,7 +195,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, break; //============================== case XCB_DESTROY_NOTIFY: - qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; + //qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; obj->emit WindowDestroyed( ((xcb_destroy_notify_event_t *) ev)->window ); break; //============================== @@ -262,7 +262,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, obj->emit PossibleDamageEvent( ((xcb_damage_notify_event_t*)ev)->drawable ); //checkDamageID( ((xcb_damage_notify_event_t*)ev)->drawable ); //}else{ - qDebug() << "Default Event:" << (ev->response_type & ~0x80); + //qDebug() << "Default Event:" << (ev->response_type & ~0x80); //} //============================== } diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index 8853c48e..819661d5 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -10,7 +10,8 @@ NativeWindow::NativeWindow(WId id) : QObject(){ winid = id; frameid = 0; - WIN = QWindow::fromWinId(winid); + dmgID = 0; + //WIN = QWindow::fromWinId(winid); } NativeWindow::~NativeWindow(){ @@ -22,6 +23,10 @@ void NativeWindow::addFrameWinID(WId fid){ frameid = fid; } +void NativeWindow::addDamageID(unsigned int dmg){ + dmgID = dmg; +} + bool NativeWindow::isRelatedTo(WId tmp){ return (relatedTo.contains(tmp) || winid == tmp || frameid == tmp); } @@ -30,47 +35,55 @@ WId NativeWindow::id(){ return winid; } -QWindow* NativeWindow::window(){ - return WIN; +WId NativeWindow::frameId(){ + return frameid; +} + +unsigned int NativeWindow::damageId(){ + return dmgID; } +/*QWindow* NativeWindow::window(){ + return WIN; +}*/ + QVariant NativeWindow::property(NativeWindow::Property prop){ if(hash.contains(prop)){ return hash.value(prop); } else if(prop == NativeWindow::RelatedWindows){ return QVariant::fromValue(relatedTo); } return QVariant(); //null variant } -void NativeWindow::setProperty(NativeWindow::Property prop, QVariant val){ +void NativeWindow::setProperty(NativeWindow::Property prop, QVariant val, bool force){ if(prop == NativeWindow::RelatedWindows){ relatedTo = val.value< QList >(); } - else if(prop == NativeWindow::None || hash.value(prop)==val){ return; } - hash.insert(prop, val); + else if(prop == NativeWindow::None || (!force && hash.value(prop)==val)){ return; } + else{ hash.insert(prop, val); } emit PropertiesChanged(QList() << prop, QList() << val); } -void NativeWindow::setProperties(QList props, QList vals){ +void NativeWindow::setProperties(QList props, QList vals, bool force){ for(int i=0; i=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this propertu - if(props[i] == NativeWindow::None || (hash.value(props[i]) == vals[i]) ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value + if(i>=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this property + if(props[i] == NativeWindow::None || (!force && (hash.value(props[i]) == vals[i])) ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value hash.insert(props[i], vals[i]); } emit PropertiesChanged(props, vals); } -void NativeWindow::requestProperty(NativeWindow::Property prop, QVariant val){ - if(prop == NativeWindow::None || prop == NativeWindow::RelatedWindows || hash.value(prop)==val ){ return; } +void NativeWindow::requestProperty(NativeWindow::Property prop, QVariant val, bool force){ + if(prop == NativeWindow::None || prop == NativeWindow::RelatedWindows || (!force && hash.value(prop)==val) ){ return; } emit RequestPropertiesChange(winid, QList() << prop, QList() << val); } -void NativeWindow::requestProperties(QList props, QList vals){ +void NativeWindow::requestProperties(QList props, QList vals, bool force){ //Verify/adjust inputs as needed for(int i=0; i=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this property - if(props[i] == NativeWindow::None || props[i] == NativeWindow::RelatedWindows || hash.value(props[i])==vals[i] ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value - if( (props[i] == NativeWindow::Visible || props[i] == NativeWindow::Active) && frameid !=0){ + if(props[i] == NativeWindow::None || props[i] == NativeWindow::RelatedWindows || (!force && hash.value(props[i])==vals[i]) ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value + /*if( (props[i] == NativeWindow::Visible || props[i] == NativeWindow::Active) && frameid !=0){ //These particular properties needs to change the frame - not the window itself emit RequestPropertiesChange(frameid, QList() << props[i], QList() << vals[i]); props.removeAt(i); vals.removeAt(i); i--; - } + }*/ } emit RequestPropertiesChange(winid, props, vals); } diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index c87ccb2d..62bb74b5 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -60,16 +60,20 @@ public: ~NativeWindow(); void addFrameWinID(WId); + void addDamageID(unsigned int); bool isRelatedTo(WId); WId id(); - QWindow* window(); + WId frameId(); + unsigned int damageId(); + + //QWindow* window(); QVariant property(NativeWindow::Property); - void setProperty(NativeWindow::Property, QVariant); - void setProperties(QList, QList); - void requestProperty(NativeWindow::Property, QVariant); - void requestProperties(QList, QList); + void setProperty(NativeWindow::Property, QVariant, bool force = false); + void setProperties(QList, QList, bool force = false); + void requestProperty(NativeWindow::Property, QVariant, bool force = false); + void requestProperties(QList, QList, bool force = false); QRect geometry(); //this returns the "full" geometry of the window (window + frame) @@ -80,9 +84,10 @@ public slots: private: QHash hash; - QWindow *WIN; + //QWindow *WIN; WId winid, frameid; QList relatedTo; + unsigned int dmgID; signals: //General Notifications diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 9c55062d..a8fb550e 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include //XCB Library includes #include @@ -48,6 +50,22 @@ XCB_EVENT_MASK_FOCUS_CHANGE | \ XCB_EVENT_MASK_ENTER_WINDOW) +#define NORMAL_WIN_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ + XCB_EVENT_MASK_BUTTON_RELEASE | \ + XCB_EVENT_MASK_POINTER_MOTION | \ + XCB_EVENT_MASK_BUTTON_MOTION | \ + XCB_EVENT_MASK_EXPOSURE | \ + XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ + XCB_EVENT_MASK_ENTER_WINDOW| \ + XCB_EVENT_MASK_PROPERTY_CHANGE) + +inline void registerClientEvents(WId id){ + uint32_t value_list[1] = {NORMAL_WIN_EVENT_MASK}; + xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, value_list); +} + //Internal XCB private objects class class NativeWindowSystem::p_objects{ public: @@ -66,7 +84,7 @@ public: QStringList atoms; atoms << "WM_TAKE_FOCUS" << "WM_DELETE_WINDOW" << "WM_PROTOCOLS" << "_NET_WM_WINDOW_OPACITY" - << "WM_CHANGE_STATE" << "_NET_SYSTEM_TRAY_OPCODE" << "_NET_SYSTEM_TRAY_ORIENTATION" + << "WM_CHANGE_STATE" << "_NET_SYSTEM_TRAY_OPCODE" << "_NET_SYSTEM_TRAY_ORIENTATION" << "_XEMBED" << "_NET_SYSTEM_TRAY_VISUAL" << QString("_NET_SYSTEM_TRAY_S%1").arg(QString::number(QX11Info::appScreen())); //Create all the requests for the atoms QList reply; @@ -266,7 +284,8 @@ NativeWindowSystem::MouseButton NativeWindowSystem::MouseToQt(int keycode){ NativeWindow* NativeWindowSystem::findWindow(WId id, bool checkRelated){ //qDebug() << "Find Window:" << id; for(int i=0; iisRelatedTo(id)){ return NWindows[i]; } + if(checkRelated && NWindows[i]->isRelatedTo(id)){ return NWindows[i]; } + else if(!checkRelated && id==NWindows[i]->id()){ return NWindows[i]; } } //Check to see if this is a transient for some other window if(checkRelated){ @@ -446,7 +465,10 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native }*/ win->setProperty(NativeWindow::Workspace, wkspace); } - + if(props.contains(NativeWindow::FrameExtents)){ + //Just assign default values to this - need to automate it later + win->setProperty(NativeWindow::FrameExtents, QVariant::fromValue >(QList() << 5 << 5 << 5+QFontMetrics(QFont()).height() << 5) ); + } if(props.contains(NativeWindow::RelatedWindows)){ WId orig = win->id(); WId tid = obj->getTransientFor(orig); @@ -481,6 +503,8 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native } if(props.contains(NativeWindow::Size) ){//|| props.contains(NativeWindow::GlobalPos) ){ xcb_configure_window_value_list_t valList; + valList.x = 0; + valList.y = 0; uint16_t mask = 0; //if(props.contains(NativeWindow::Size)){ QSize sz = vals[ props.indexOf(NativeWindow::Size) ] .toSize(); @@ -494,9 +518,9 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native /*if(props.contains(NativeWindow::GlobalPos)){ QPoint pt = vals[ props.indexOf(NativeWindow::GlobalPos) ] .toPoint(); valList.x = pt.x(); - valList.y = pt.y(); + valList.y = pt.y();*/ mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; - }else{ + /*}else{ valList.x = win->property(NativeWindow::GlobalPos).toPoint().x(); valList.y = win->property(NativeWindow::GlobalPos).toPoint().y(); }*/ @@ -525,7 +549,7 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native if(props.contains(NativeWindow::Active)){ //Only one window can be "Active" at a time - so only do anything if this window wants to be active if(vals[props.indexOf(NativeWindow::Active)].toBool() ){ - xcb_ewmh_set_active_window(&obj->EWMH, QX11Info::appScreen(), win->id()); + xcb_ewmh_set_active_window(&obj->EWMH, QX11Info::appScreen(), (win->frameId()==0 ?win->id() : win->frameId())); //Also send the active window a message to take input focus //Send the window a WM_TAKE_FOCUS message xcb_client_message_event_t event; @@ -657,7 +681,7 @@ int NativeWindowSystem::currentWorkspace(){ //NativeWindowEventFilter interactions void NativeWindowSystem::NewWindowDetected(WId id){ //Make sure this can be managed first - if(findWindow(id, false) != 0){ qDebug() << "Window Already Managed!!!!"; return; } //already managed + if(findWindow(id, false) != 0){ qDebug() << "Window Already Managed!!!!"; findWindow(id,false)->setProperty(NativeWindow::Visible, true, true); return; } //already managed xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(QX11Info::connection(), id); xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(QX11Info::connection(), cookie, NULL); if(attr == 0){ return; } //could not get attributes of window @@ -666,19 +690,7 @@ void NativeWindowSystem::NewWindowDetected(WId id){ //Now go ahead and create/populate the container for this window NativeWindow *win = new NativeWindow(id); //Register for events from this window - #define NORMAL_WIN_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ - XCB_EVENT_MASK_BUTTON_RELEASE | \ - XCB_EVENT_MASK_POINTER_MOTION | \ - XCB_EVENT_MASK_BUTTON_MOTION | \ - XCB_EVENT_MASK_EXPOSURE | \ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_ENTER_WINDOW| \ - XCB_EVENT_MASK_PROPERTY_CHANGE) - - uint32_t value_list[1] = {NORMAL_WIN_EVENT_MASK}; - xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, value_list); + registerClientEvents(win->id()); NWindows << win; UpdateWindowProperties(win, NativeWindow::allProperties()); qDebug() << "New Window [& associated ID's]:" << win->id() << win->property(NativeWindow::RelatedWindows); @@ -721,12 +733,14 @@ void NativeWindowSystem::NewTrayWindowDetected(WId id){ void NativeWindowSystem::WindowCloseDetected(WId id){ NativeWindow *win = findWindow(id, false); - qDebug() << "Got Window Closed" << id << win; - qDebug() << "Old Window List:" << NWindows.length(); + //qDebug() << "Got Window Closed" << id << win; + //qDebug() << "Old Window List:" << NWindows.length(); if(win!=0){ NWindows.removeAll(win); + //RequestReparent(id, QX11Info::appRootWindow(), QPoint(0,0)); win->emit WindowClosed(id); - win->deleteLater(); + //qDebug() << "Visible Window Closed!!!"; + //win->deleteLater(); }else{ win = findTrayWindow(id); if(win!=0){ @@ -735,7 +749,7 @@ void NativeWindowSystem::WindowCloseDetected(WId id){ win->deleteLater(); } } - qDebug() << " - Now:" << NWindows.length(); + //qDebug() << " - Now:" << NWindows.length(); } void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop){ @@ -810,6 +824,29 @@ void NativeWindowSystem::NewMouseRelease(int buttoncode, WId win){ } void NativeWindowSystem::CheckDamageID(WId win){ + for(int i=0; idamageId() == win || NWindows[i]->id() == win || NWindows[i]->frameId()==win){ + //qDebug() << "Got DAMAGE Event"; + /*NativeWindow *WIN = NWindows[i]; + QSize sz = WIN->property(NativeWindow::Size).toSize(); + //Need the graphics context of the window + xcb_gcontext_t gc = xcb_generate_id(QX11Info::connection()); + xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(QX11Info::connection())).data; + uint32_t values[1]; + values[0] = screen->black_pixel; + xcb_create_gc(QX11Info::connection(), + gc, + WIN->frameId(), + XCB_GC_BACKGROUND, + values ); + xcb_pixmap_t pix = xcb_generate_id(QX11Info::connection()); + xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), pix); + //Now put this pixmap onto the frame window + xcb_copy_area(QX11Info::connection(), pix, WIN->frameId(), gc, 0,0,0,0,sz.width(), sz.height());*/ + /*xcb_put_image(QX11Info::connection(), XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc, sz.width(), sz.height(), 0, 0, */ + return; + } + } NativeWindow *WIN = findTrayWindow(win); if(WIN!=0){ UpdateWindowProperties(WIN, QList() << NativeWindow::Icon); @@ -851,10 +888,52 @@ void NativeWindowSystem::RequestPing(WId win){ pingTimer->start(); } -void NativeWindowSystem::RequestReparent(WId client, WId parent, QPoint relorigin){ +void NativeWindowSystem::RequestReparent(WId win, WId container, QPoint relorigin){ + NativeWindow *WIN = findWindow(win); + if(WIN==0){ return; } //could not find corresponding window structure +//Reparent the window into the container + xcb_reparent_window(QX11Info::connection(), win, container, relorigin.x(), relorigin.y()); + //xcb_map_window(QX11Info::connection(), win); + + //Now send the embed event to the app + //qDebug() << " - send _XEMBED event"; + xcb_client_message_event_t event; + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.window = win; + event.type = obj->ATOMS["_XEMBED"]; //_XEMBED + event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; + event.data.data32[1] = 0; //XEMBED_EMBEDDED_NOTIFY + event.data.data32[2] = 0; + event.data.data32[3] = container; //WID of the container + event.data.data32[4] = 0; + + xcb_send_event(QX11Info::connection(), 0, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); + + //Now setup any redirects and return + //this->SelectInput(win, true); //Notify of structure changes + registerClientEvents(win); + //xcb_composite_redirect_window(QX11Info::connection(), win, XCB_COMPOSITE_REDIRECT_MANUAL); //XCB_COMPOSITE_REDIRECT_[MANUAL/AUTOMATIC]); + + //Now map the window (will be a transparent child of the container) + xcb_map_window(QX11Info::connection(), win); + xcb_map_window(QX11Info::connection(), container); + //Now create/register the damage handler + // -- XCB (Note: The XCB damage registration is completely broken at the moment - 9/15/15, Ken Moore) + // -- Retested 6/29/17 (no change) Ken Moore + //xcb_damage_damage_t dmgID = xcb_generate_id(QX11Info::connection()); //This is a typedef for a 32-bit unsigned integer + //xcb_damage_create(QX11Info::connection(), dmgID, win, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES); + // -- XLib (Note: This is only used because the XCB routine above does not work - needs to be fixed upstream in XCB itself). + Damage dmgID = XDamageCreate(QX11Info::display(), win, XDamageReportRawRectangles); + WIN->addDamageID( (uint) dmgID); //save this for later + //qDebug() << " - Done"; + //return ( (uint) dmgID ); +} +/* xcb_reparent_window(QX11Info::connection(), client, parent, relorigin.x(), relorigin.y()); - //Now enable compositing between these two windows as well - // TODO + //Now ensure that we still get event for these windows + registerClientEvents(client); //make sure we re-do this after reparenting + registerClientEvents(parent); xcb_map_window(QX11Info::connection(), parent); -} +}*/ diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 9eb1ff58..92a85291 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -30,11 +30,11 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ WIN->emit RequestReparent(WIN->id(), WinWidget->winId(), QPoint(0,0)); qDebug() << "[NEW WINDOW]" << WIN->id() << WinWidget->winId() << this->winId(); LoadAllProperties(); - //QTimer::singleShot(20, this, SLOT(LoadAllProperties()) ); } RootSubWindow::~RootSubWindow(){ - + //qDebug() << "Visible Window Destroyed"; + WIN->deleteLater(); } WId RootSubWindow::id(){ @@ -202,30 +202,30 @@ void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ // === PUBLIC SLOTS === void RootSubWindow::clientClosed(){ - qDebug() << "Client Closed"; + //qDebug() << "Client Closed"; closing = true; + /*animResetProp = QRect(WIN->property(NativeWindow::GlobalPos).toPoint(), WIN->property(NativeWindow::Size).toSize()); anim->setPropertyName("geometry"); anim->setStartValue(this->geometry()); anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); anim->start(); - QTimer::singleShot(anim->duration(), this, SLOT(close()) ); - //this->close(); + QTimer::singleShot(anim->duration(), this, SLOT(close()) );*/ + if(anim->state()!=QAbstractAnimation::Running){ this->close(); } } void RootSubWindow::LoadAllProperties(){ QList< NativeWindow::Property> list = WIN->allProperties(); - /*list.removeAll(NativeWindow::Visible); - list << NativeWindow::Visible;*/ LoadProperties(list); } //Button Actions - public so they can be tied to key shortcuts and stuff as well void RootSubWindow::toggleMinimize(){ - + WIN->setProperty(NativeWindow::Visible, false); + QTimer::singleShot(2000, this, SLOT(toggleMaximize()) ); } void RootSubWindow::toggleMaximize(){ - + WIN->setProperty(NativeWindow::Visible, true); } void RootSubWindow::triggerClose(){ @@ -270,12 +270,14 @@ void RootSubWindow::propertiesChanged(QList props, QList //qDebug() << "Got Visibility Change:" << vals[i]; if(vals[i].toBool()){ WinWidget->setVisible(true); + animResetProp = WIN->geometry(); //show event - might not have the right geom yet anim->setPropertyName("geometry"); anim->setStartValue( QRect(WIN->geometry().center(), QSize(0,0)) ); anim->setEndValue(WIN->geometry()); anim->start(); this->show(); }else{ + animResetProp = this->geometry(); //hide event - should already be the right geom anim->setPropertyName("geometry"); anim->setStartValue(this->geometry()); anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); @@ -298,10 +300,10 @@ void RootSubWindow::propertiesChanged(QList props, QList break; case NativeWindow::Size: if(WinWidget->size() != vals[i].toSize()){ - //qDebug() << "Got Widget Size Change:" << vals[i].toSize(); + qDebug() << "Got Widget Size Change:" << vals[i].toSize(); WinWidget->resize(vals[i].toSize()); this->resize( WIN->geometry().size() ); - //qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); + qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); } break; case NativeWindow::MinSize: @@ -326,15 +328,25 @@ void RootSubWindow::propertiesChanged(QList props, QList } void RootSubWindow::animFinished(){ - if(anim->propertyName()=="geometry"){ - WIN->requestProperty(NativeWindow::Size, WinWidget->size()); - WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); + if(closing){ this->close(); return;} + else if(anim->propertyName()=="geometry"){ + if(!animResetProp.isNull()){ + qDebug() << "Animation Finished, Reset Geometry:" << animResetProp; + qDebug() << " - Starting Value:" << anim->startValue(); + qDebug() << " - Ending Value:" << anim->endValue(); + qDebug() << " - Current Value:" << this->geometry(); + this->setGeometry( animResetProp.toRect() ); + WIN->requestProperty(NativeWindow::Size, WinWidget->size(), true); + WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)),true ); + } } - + animResetProp = QVariant(); //clear the variable } // === PROTECTED === void RootSubWindow::mousePressEvent(QMouseEvent *ev){ + activate(); + this->raise(); //qDebug() << "Frame Mouse Press Event"; offset.setX(0); offset.setY(0); if(activeState != Normal){ return; } // do nothing - already in a state of grabbed mouse diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index 25c6596a..bd20291e 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -50,6 +50,7 @@ private: QMenu *otherM; //menu of other actions //Other random objects (animations,etc) QPropertyAnimation *anim; + QVariant animResetProp; void initWindowFrame(); void LoadProperties( QList< NativeWindow::Property> list); diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp index 17a9ecd7..2fee5d96 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/RootWindow.cpp @@ -184,7 +184,7 @@ void RootWindow::NewWindow(NativeWindow *win){ void RootWindow::CloseWindow(WId win){ for(int i=0; iid() == win){ WINDOWS.takeAt(i)->clientClosed(); break; } + if(WINDOWS[i]->id() == win){ qDebug() << "Remove Window From Root List"; WINDOWS.takeAt(i)->clientClosed(); break; } } } -- cgit From c350293e4a3bccfbc255dec8e1eea35fe36c2b2d Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 5 Jul 2017 13:23:25 -0400 Subject: Add the ability to use a static "instance()" of the DesktopSettings class within a project --- src-qt5/core/libLumina/DesktopSettings.cpp | 14 ++++++++++++-- src-qt5/core/libLumina/DesktopSettings.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/DesktopSettings.cpp b/src-qt5/core/libLumina/DesktopSettings.cpp index 30bd5bc2..bd0325ec 100644 --- a/src-qt5/core/libLumina/DesktopSettings.cpp +++ b/src-qt5/core/libLumina/DesktopSettings.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include @@ -25,6 +25,16 @@ DesktopSettings::~DesktopSettings(){ if(!files.isEmpty()){ stop(); } } +DesktopSettings* DesktopSettings::instance(){ + static DesktopSettings *set = 0; + if(set==0){ + //First-time init + set = new DesktopSettings(); + set->start(); + } + return set; +} + //Start/stop routines void DesktopSettings::start(){ files.clear(); settings.clear(); //clear the internal hashes (just in case) @@ -35,7 +45,7 @@ void DesktopSettings::start(){ } parseSystemSettings(); //set the runmode appropriately locateFiles(); // - + } void DesktopSettings::stop(){ diff --git a/src-qt5/core/libLumina/DesktopSettings.h b/src-qt5/core/libLumina/DesktopSettings.h index 57eede9d..57a85791 100644 --- a/src-qt5/core/libLumina/DesktopSettings.h +++ b/src-qt5/core/libLumina/DesktopSettings.h @@ -30,6 +30,8 @@ public: DesktopSettings(QObject *parent = 0); ~DesktopSettings(); + static DesktopSettings* instance(); + //Start/stop routines void start(); void stop(); -- cgit From 0c406639a823f4cad097c8e5a98606658d44bbf4 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 7 Jul 2017 14:59:20 -0400 Subject: Commit a work-in-progress for converting an X11 keycode into a Qt::Key definition --- src-qt5/core/libLumina/NativeWindow.pri | 2 +- src-qt5/core/libLumina/NativeWindowSystem.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindow.pri b/src-qt5/core/libLumina/NativeWindow.pri index b10e472c..fef9c736 100644 --- a/src-qt5/core/libLumina/NativeWindow.pri +++ b/src-qt5/core/libLumina/NativeWindow.pri @@ -1,7 +1,7 @@ # Files QT *= x11extras -LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lXdamage +LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lxcb-keysyms -lXdamage SOURCES *= $${PWD}/NativeWindow.cpp \ $${PWD}/NativeWindowSystem.cpp \ diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index a8fb550e..6f737b27 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -27,6 +27,7 @@ #include #include #include +#include //XLib includes (XCB Damage lib does not appear to register for damage events properly) #include @@ -250,7 +251,13 @@ void NativeWindowSystem::stop(){ //Small simplification functions Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ - qDebug() << "Try to convert keycode to Qt::Key:" << keycode; + static xcb_key_symbols_t *SYM = 0; + if(SYM==0){ SYM = xcb_key_symbols_alloc(QX11Info::connection()); } + xcb_keysym_t symbol = xcb_key_symbols_get_keysym(SYM, keycode,0); + //not sure about the "column" input - we want raw keys though so ignore the "modified" key states (columns) for now + qDebug() << "Try to convert keycode to Qt::Key:" << keycode << symbol; + //Now map this symbol to the appropriate Qt::Key enumeration + qDebug() << " -- Simple Qt Map:" << (Qt::Key)(symbol); qDebug() << " - Not implemented yet"; return Qt::Key_unknown; } @@ -802,6 +809,7 @@ void NativeWindowSystem::GotPong(WId id){ void NativeWindowSystem::NewKeyPress(int keycode, WId win){ emit NewInputEvent(); if(screenLocked){ return; } + KeycodeToQt(keycode); emit KeyPressDetected(win, keycode); } -- cgit From 70cf0e8b4ef74d35f798c92634ecc129298a1d3b Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 7 Jul 2017 15:11:22 -0400 Subject: A bit more keyboard mapping debugging/parsing --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 6f737b27..ab264db5 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -256,6 +256,13 @@ Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ xcb_keysym_t symbol = xcb_key_symbols_get_keysym(SYM, keycode,0); //not sure about the "column" input - we want raw keys though so ignore the "modified" key states (columns) for now qDebug() << "Try to convert keycode to Qt::Key:" << keycode << symbol; + if(xcb_is_keypad_key(symbol)){ qDebug() << "Keypad Key"; } + else if(xcb_is_private_keypad_key(symbol)){ qDebug() << "Private Keypad Key"; } + else if(xcb_is_cursor_key(symbol)){ qDebug() << "Cursor Key"; } + else if(xcb_is_pf_key(symbol)){ qDebug() << "PF Key"; } + else if(xcb_is_function_key(symbol)){ qDebug() << "Function Key"; } + else if(xcb_is_misc_function_key(symbol)){ qDebug() << "Misc Function Key"; } + else if(xcb_is_modifier_key(symbol)){ qDebug() << "Modifier Key"; } //Now map this symbol to the appropriate Qt::Key enumeration qDebug() << " -- Simple Qt Map:" << (Qt::Key)(symbol); qDebug() << " - Not implemented yet"; -- cgit From a5bb959045ed8dac47e1c6fa3e13b1cae4b5285b Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 7 Jul 2017 15:18:05 -0400 Subject: Try a more complicated QKeySequence for the mapping protocols --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index ab264db5..93616832 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -265,6 +265,7 @@ Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ else if(xcb_is_modifier_key(symbol)){ qDebug() << "Modifier Key"; } //Now map this symbol to the appropriate Qt::Key enumeration qDebug() << " -- Simple Qt Map:" << (Qt::Key)(symbol); + qDebug() << " -- Key Sequence Map:" << QKeySequence(symbol); qDebug() << " - Not implemented yet"; return Qt::Key_unknown; } -- cgit From 3fb6466ec6b3327725c2e887dadf64e529a97d41 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 7 Jul 2017 15:19:19 -0400 Subject: Oops - forgot to add an include. --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 93616832..17e90d3f 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -16,6 +16,7 @@ #include #include #include +#include //XCB Library includes #include -- cgit From d54b6b09d5af0914551c8319138b2ee83b170362 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 7 Jul 2017 15:28:07 -0400 Subject: Get the numbers/letters conversion working from X11->Qt --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 17e90d3f..79d0e1fc 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -264,6 +264,11 @@ Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ else if(xcb_is_function_key(symbol)){ qDebug() << "Function Key"; } else if(xcb_is_misc_function_key(symbol)){ qDebug() << "Misc Function Key"; } else if(xcb_is_modifier_key(symbol)){ qDebug() << "Modifier Key"; } + else if(!QKeySequence(symbol).isEmpty()){ + //One of the standard keys, go ahead and do a direct map + qDebug() << " -- [GOT MATCH]" << QKeySequence(symbol)[0]; + return Qt::Key_unknown; //QKeySequence(symbol)[0]; //only ever one key in this method + } //Now map this symbol to the appropriate Qt::Key enumeration qDebug() << " -- Simple Qt Map:" << (Qt::Key)(symbol); qDebug() << " -- Key Sequence Map:" << QKeySequence(symbol); -- cgit From 186b10b9cc833897ee0bbb33534837165cf4bdea Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 7 Jul 2017 15:37:19 -0400 Subject: A few more updates in the X11->Qt button mapping --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 79d0e1fc..4a66f621 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -257,22 +257,25 @@ Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ xcb_keysym_t symbol = xcb_key_symbols_get_keysym(SYM, keycode,0); //not sure about the "column" input - we want raw keys though so ignore the "modified" key states (columns) for now qDebug() << "Try to convert keycode to Qt::Key:" << keycode << symbol; + //Now map this symbol to the appropriate Qt::Key enumeration if(xcb_is_keypad_key(symbol)){ qDebug() << "Keypad Key"; } else if(xcb_is_private_keypad_key(symbol)){ qDebug() << "Private Keypad Key"; } else if(xcb_is_cursor_key(symbol)){ qDebug() << "Cursor Key"; } else if(xcb_is_pf_key(symbol)){ qDebug() << "PF Key"; } else if(xcb_is_function_key(symbol)){ qDebug() << "Function Key"; } else if(xcb_is_misc_function_key(symbol)){ qDebug() << "Misc Function Key"; } - else if(xcb_is_modifier_key(symbol)){ qDebug() << "Modifier Key"; } - else if(!QKeySequence(symbol).isEmpty()){ + else if(xcb_is_modifier_key(symbol)){ + qDebug() << "Modifier Key"; + + }else if(!QKeySequence(symbol).isEmpty()){ //One of the standard keys, go ahead and do a direct map - qDebug() << " -- [GOT MATCH]" << QKeySequence(symbol)[0]; + qDebug() << " -- [GOT MATCH]" << QKeySequence(symbol); return Qt::Key_unknown; //QKeySequence(symbol)[0]; //only ever one key in this method + }else{ + qDebug() << " -- Simple Qt Map:" << (Qt::Key)(symbol); + qDebug() << " -- Key Sequence Map:" << QKeySequence(symbol); + qDebug() << " - Not implemented yet"; } - //Now map this symbol to the appropriate Qt::Key enumeration - qDebug() << " -- Simple Qt Map:" << (Qt::Key)(symbol); - qDebug() << " -- Key Sequence Map:" << QKeySequence(symbol); - qDebug() << " - Not implemented yet"; return Qt::Key_unknown; } -- cgit From 091d2cd5fa15a9ffc442892bf6f4a6ea72a62d55 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 7 Jul 2017 16:25:20 -0400 Subject: Get the F1-F35 keys all detected/mapped appropriately to Qt keys --- src-qt5/core/libLumina/NativeWindowSystem.cpp | 57 +++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 4a66f621..73bba1a9 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -18,6 +18,16 @@ #include #include + +#define XK_MISCELLANY +#define XK_XKB_KEYS +#define XK_LATIN1 +#define XK_LATIN2 +#define XK_LATIN3 +#define XK_LATIN4 +//NOTE: Look at the keysymdef.h file for additional define/characters which we may need later +#include + //XCB Library includes #include #include @@ -262,11 +272,52 @@ Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ else if(xcb_is_private_keypad_key(symbol)){ qDebug() << "Private Keypad Key"; } else if(xcb_is_cursor_key(symbol)){ qDebug() << "Cursor Key"; } else if(xcb_is_pf_key(symbol)){ qDebug() << "PF Key"; } - else if(xcb_is_function_key(symbol)){ qDebug() << "Function Key"; } - else if(xcb_is_misc_function_key(symbol)){ qDebug() << "Misc Function Key"; } + else if(xcb_is_function_key(symbol)){ + switch(symbol){ + case XK_F1: return Qt::Key_F1; + case XK_F2: return Qt::Key_F2; + case XK_F3: return Qt::Key_F3; + case XK_F4: return Qt::Key_F4; + case XK_F5: return Qt::Key_F5; + case XK_F6: return Qt::Key_F6; + case XK_F7: return Qt::Key_F7; + case XK_F8: return Qt::Key_F8; + case XK_F9: return Qt::Key_F9; + case XK_F10: return Qt::Key_F10; + case XK_F11: return Qt::Key_F11; + case XK_F12: return Qt::Key_F12; + case XK_F13: return Qt::Key_F13; + case XK_F14: return Qt::Key_F14; + case XK_F15: return Qt::Key_F15; + case XK_F16: return Qt::Key_F16; + case XK_F17: return Qt::Key_F17; + case XK_F18: return Qt::Key_F18; + case XK_F19: return Qt::Key_F19; + case XK_F20: return Qt::Key_F20; + case XK_F21: return Qt::Key_F21; + case XK_F22: return Qt::Key_F22; + case XK_F23: return Qt::Key_F23; + case XK_F24: return Qt::Key_F24; + case XK_F25: return Qt::Key_F25; + case XK_F26: return Qt::Key_F26; + case XK_F27: return Qt::Key_F27; + case XK_F28: return Qt::Key_F28; + case XK_F29: return Qt::Key_F29; + case XK_F30: return Qt::Key_F30; + case XK_F31: return Qt::Key_F31; + case XK_F32: return Qt::Key_F32; + case XK_F33: return Qt::Key_F33; + case XK_F34: return Qt::Key_F34; + case XK_F35: return Qt::Key_F35; + default: + qDebug() << "Unknown Function Key"; + } + }else if(xcb_is_misc_function_key(symbol)){ qDebug() << "Misc Function Key"; } else if(xcb_is_modifier_key(symbol)){ qDebug() << "Modifier Key"; - + /*switch(symbol){ + case: XK_ + }*/ }else if(!QKeySequence(symbol).isEmpty()){ //One of the standard keys, go ahead and do a direct map qDebug() << " -- [GOT MATCH]" << QKeySequence(symbol); -- cgit From 6f1d3946d52feceaa5d875a079a148c775140d5f Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Sat, 8 Jul 2017 11:46:00 -0400 Subject: Split out the X11->Qt conversion function into it's own file (getting too long to be mixed in with the rest of the class). Also finish up a lot more of the conversions. Should be ready for testing now. --- src-qt5/core/libLumina/NativeKeyToQt.cpp | 528 ++++++++++++++++++++++++++ src-qt5/core/libLumina/NativeWindow.pri | 1 + src-qt5/core/libLumina/NativeWindowSystem.cpp | 112 +----- src-qt5/core/libLumina/NativeWindowSystem.h | 4 +- 4 files changed, 535 insertions(+), 110 deletions(-) create mode 100644 src-qt5/core/libLumina/NativeKeyToQt.cpp (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeKeyToQt.cpp b/src-qt5/core/libLumina/NativeKeyToQt.cpp new file mode 100644 index 00000000..b6af9b6c --- /dev/null +++ b/src-qt5/core/libLumina/NativeKeyToQt.cpp @@ -0,0 +1,528 @@ + +#include + +#include +#include + +// XCB/X11 Includes +#define XK_MISCELLANY +#define XK_XKB_KEYS +#define XK_LATIN1 +#define XK_LATIN2 +#define XK_LATIN3 +#define XK_LATIN4 +#define XK_LATIN8 +#define XK_LATIN9 +//NOTE: Look at the keysymdef.h file for additional define/characters which we may need later +#include +#include + + +//Small simplification functions +Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ + static xcb_key_symbols_t *SYM = 0; + if(SYM==0){ SYM = xcb_key_symbols_alloc(QX11Info::connection()); } + xcb_keysym_t symbol = xcb_key_symbols_get_keysym(SYM, keycode,0); + //not sure about the "column" input - we want raw keys though so ignore the "modified" key states (columns) for now + //qDebug() << "Try to convert keycode to Qt::Key:" << keycode << symbol; + //Now map this symbol to the appropriate Qt::Key enumeration + switch(symbol){ + //FUNCTION KEYS + case XK_F1: return Qt::Key_F1; + case XK_F2: return Qt::Key_F2; + case XK_F3: return Qt::Key_F3; + case XK_F4: return Qt::Key_F4; + case XK_F5: return Qt::Key_F5; + case XK_F6: return Qt::Key_F6; + case XK_F7: return Qt::Key_F7; + case XK_F8: return Qt::Key_F8; + case XK_F9: return Qt::Key_F9; + case XK_F10: return Qt::Key_F10; + case XK_F11: return Qt::Key_F11; + case XK_F12: return Qt::Key_F12; + case XK_F13: return Qt::Key_F13; + case XK_F14: return Qt::Key_F14; + case XK_F15: return Qt::Key_F15; + case XK_F16: return Qt::Key_F16; + case XK_F17: return Qt::Key_F17; + case XK_F18: return Qt::Key_F18; + case XK_F19: return Qt::Key_F19; + case XK_F20: return Qt::Key_F20; + case XK_F21: return Qt::Key_F21; + case XK_F22: return Qt::Key_F22; + case XK_F23: return Qt::Key_F23; + case XK_F24: return Qt::Key_F24; + case XK_F25: return Qt::Key_F25; + case XK_F26: return Qt::Key_F26; + case XK_F27: return Qt::Key_F27; + case XK_F28: return Qt::Key_F28; + case XK_F29: return Qt::Key_F29; + case XK_F30: return Qt::Key_F30; + case XK_F31: return Qt::Key_F31; + case XK_F32: return Qt::Key_F32; + case XK_F33: return Qt::Key_F33; + case XK_F34: return Qt::Key_F34; + case XK_F35: return Qt::Key_F35; + //Miscellaneous Keys + case XK_BackSpace: return Qt::Key_Backspace; + case XK_Delete: return Qt::Key_Delete; + //case XK_LineFeed: return Qt::Key_Backspace; + case XK_Clear: return Qt::Key_Clear; + case XK_Return: return Qt::Key_Return; + case XK_Pause: return Qt::Key_Pause; + case XK_Scroll_Lock: return Qt::Key_ScrollLock; + case XK_Sys_Req: return Qt::Key_SysReq; + case XK_Escape: return Qt::Key_Escape; + case XK_Select: return Qt::Key_Select; + case XK_Print: return Qt::Key_Print; + //case XK_Execute: return Qt::Key_Execute; + case XK_Insert: return Qt::Key_Insert; + case XK_Undo: return Qt::Key_Undo; + case XK_Redo: return Qt::Key_Redo; + case XK_Menu: return Qt::Key_Menu; + case XK_Find: return Qt::Key_Find; + case XK_Cancel: return Qt::Key_Cancel; + case XK_Help: return Qt::Key_Help; + //case XK_Break: return Qt::Key_Break; + //case XK_Mode_switch: return Qt::Key_Backspace; + //case XK_script_switch: return Qt::Key_Backspace; + case XK_Num_Lock: return Qt::Key_NumLock; + //Cursor Controls + case XK_Home: return Qt::Key_Home; + case XK_Left: return Qt::Key_Left; + case XK_Up: return Qt::Key_Up; + case XK_Right: return Qt::Key_Right; + case XK_Down: return Qt::Key_Down; + //case XK_Prior: return Qt::Key_Backspace; + case XK_Page_Up: return Qt::Key_PageUp; + case XK_Page_Down: return Qt::Key_PageDown; + //case XK_Next: return Qt::Key_Backspace; + case XK_End: return Qt::Key_End; + //case XK_Begin: return Qt::Key_Backspace; + // Keypad Functions and numbers + case XK_KP_Space: return Qt::Key_Space; + case XK_KP_Tab: return Qt::Key_Tab; + case XK_KP_Enter: return Qt::Key_Enter; + case XK_KP_F1: return Qt::Key_F1; + case XK_KP_F2: return Qt::Key_F2; + case XK_KP_F3: return Qt::Key_F3; + case XK_KP_F4: return Qt::Key_F4; + case XK_KP_Home: return Qt::Key_Home; + case XK_KP_Left: return Qt::Key_Left; + case XK_KP_Up: return Qt::Key_Up; + case XK_KP_Right: return Qt::Key_Right; + case XK_KP_Down: return Qt::Key_Down; + //case XK_KP_Prior: return Qt::Key_ + case XK_KP_Page_Up: return Qt::Key_PageUp; + //case XK_KP_Next: return Qt::Key_ + case XK_KP_Page_Down: return Qt::Key_PageDown; + case XK_KP_End: return Qt::Key_End; + //case XK_KP_Begin: return Qt::Key_ + case XK_KP_Insert: return Qt::Key_Insert; + case XK_KP_Delete: return Qt::Key_Delete; + case XK_KP_Equal: return Qt::Key_Equal; + case XK_KP_Multiply: return Qt::Key_Asterisk; + case XK_KP_Add: return Qt::Key_Plus; + case XK_KP_Separator: return Qt::Key_Comma; //X11 definitions say this is often comma + case XK_KP_Subtract: return Qt::Key_Minus; + case XK_KP_Decimal: return Qt::Key_Period; + case XK_KP_Divide: return Qt::Key_Slash; + case XK_KP_0: return Qt::Key_0; + case XK_KP_1: return Qt::Key_1; + case XK_KP_2: return Qt::Key_2; + case XK_KP_3: return Qt::Key_3; + case XK_KP_4: return Qt::Key_4; + case XK_KP_5: return Qt::Key_5; + case XK_KP_6: return Qt::Key_6; + case XK_KP_7: return Qt::Key_7; + case XK_KP_8: return Qt::Key_8; + case XK_KP_9: return Qt::Key_9; + // Modifier Keys + case XK_Shift_L: return Qt::Key_Shift; + case XK_Shift_R: return Qt::Key_Shift; + case XK_Control_L: return Qt::Key_Control; + case XK_Control_R: return Qt::Key_Control; + case XK_Caps_Lock: return Qt::Key_CapsLock; + //case XK_Shift_Lock: return Qt::Key_ShiftLock; + case XK_Meta_L: return Qt::Key_Meta; + case XK_Meta_R: return Qt::Key_Meta; + case XK_Alt_L: return Qt::Key_Alt; + case XK_Alt_R: return Qt::Key_Alt; + case XK_Super_L: return Qt::Key_Super_L; + case XK_Super_R: return Qt::Key_Super_R; + case XK_Hyper_L: return Qt::Key_Hyper_L; + case XK_Hyper_R: return Qt::Key_Hyper_R; + case XK_space: return Qt::Key_Space; + case XK_exclam: return Qt::Key_Exclam; + case XK_quotedbl: return Qt::Key_QuoteDbl; + case XK_numbersign: return Qt::Key_NumberSign; + case XK_dollar: return Qt::Key_Dollar; + case XK_percent: return Qt::Key_Percent; + case XK_ampersand: return Qt::Key_Ampersand; + case XK_apostrophe: return Qt::Key_Apostrophe; + case XK_parenleft: return Qt::Key_ParenLeft; + case XK_parenright: return Qt::Key_ParenRight; + case XK_asterisk: return Qt::Key_Asterisk; + case XK_plus: return Qt::Key_Plus; + case XK_comma: return Qt::Key_Comma; + case XK_minus: return Qt::Key_Minus; + case XK_period: return Qt::Key_Period; + case XK_slash: return Qt::Key_Slash; + case XK_0: return Qt::Key_0; + case XK_1: return Qt::Key_1; + case XK_2: return Qt::Key_2; + case XK_3: return Qt::Key_3; + case XK_4: return Qt::Key_4; + case XK_5: return Qt::Key_5; + case XK_6: return Qt::Key_6; + case XK_7: return Qt::Key_7; + case XK_8: return Qt::Key_8; + case XK_9: return Qt::Key_9; + case XK_colon: return Qt::Key_Colon; + case XK_semicolon: return Qt::Key_Semicolon; + case XK_less: return Qt::Key_Less; + case XK_equal: return Qt::Key_Equal; + case XK_greater: return Qt::Key_Greater; + case XK_question: return Qt::Key_Question; + case XK_at: return Qt::Key_At; + case XK_A: return Qt::Key_A; + case XK_B: return Qt::Key_B; + case XK_C: return Qt::Key_C; + case XK_D: return Qt::Key_D; + case XK_E: return Qt::Key_E; + case XK_F: return Qt::Key_F; + case XK_G: return Qt::Key_G; + case XK_H: return Qt::Key_H; + case XK_I: return Qt::Key_I; + case XK_J: return Qt::Key_J; + case XK_K: return Qt::Key_K; + case XK_L: return Qt::Key_L; + case XK_M: return Qt::Key_M; + case XK_N: return Qt::Key_N; + case XK_O: return Qt::Key_O; + case XK_P: return Qt::Key_P; + case XK_Q: return Qt::Key_Q; + case XK_R: return Qt::Key_R; + case XK_S: return Qt::Key_S; + case XK_T: return Qt::Key_T; + case XK_U: return Qt::Key_U; + case XK_V: return Qt::Key_V; + case XK_W: return Qt::Key_W; + case XK_X: return Qt::Key_X; + case XK_Y : return Qt::Key_Y; + case XK_Z: return Qt::Key_Z; + case XK_bracketleft: return Qt::Key_BracketLeft; + case XK_backslash: return Qt::Key_Backslash; + case XK_bracketright: return Qt::Key_BracketRight; + case XK_asciicircum: return Qt::Key_AsciiCircum; + case XK_underscore: return Qt::Key_Underscore; + case XK_grave: return Qt::Key_Agrave; + case XK_a: return Qt::Key_A; + case XK_b: return Qt::Key_B; + case XK_c: return Qt::Key_C; + case XK_d: return Qt::Key_D; + case XK_e: return Qt::Key_E; + case XK_f : return Qt::Key_F; + case XK_g: return Qt::Key_G; + case XK_h: return Qt::Key_H; + case XK_i: return Qt::Key_I; + case XK_j: return Qt::Key_J; + case XK_k: return Qt::Key_K; + case XK_l: return Qt::Key_L; + case XK_m: return Qt::Key_M; + case XK_n: return Qt::Key_N; + case XK_o: return Qt::Key_O; + case XK_p: return Qt::Key_P; + case XK_q: return Qt::Key_Q; + case XK_r: return Qt::Key_R; + case XK_s: return Qt::Key_S; + case XK_t : return Qt::Key_T; + case XK_u: return Qt::Key_U; + case XK_v: return Qt::Key_V; + case XK_w: return Qt::Key_W; + case XK_x: return Qt::Key_X; + case XK_y: return Qt::Key_Y; + case XK_z: return Qt::Key_Z; + case XK_braceleft: return Qt::Key_BraceLeft; + case XK_bar: return Qt::Key_Bar; + case XK_braceright: return Qt::Key_BraceRight; + case XK_asciitilde: return Qt::Key_AsciiTilde; + + //case XK_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */ + //case XK_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */ + //case XK_cent 0x00a2 /* U+00A2 CENT SIGN */ + //case XK_sterling 0x00a3 /* U+00A3 POUND SIGN */ + //case XK_currency 0x00a4 /* U+00A4 CURRENCY SIGN */ + //case XK_yen 0x00a5 /* U+00A5 YEN SIGN */ + //case XK_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */ + //case XK_section 0x00a7 /* U+00A7 SECTION SIGN */ + //case XK_diaeresis 0x00a8 /* U+00A8 DIAERESIS */ + //case XK_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */ + //case XK_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */ + //case XK_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ + //case XK_notsign 0x00ac /* U+00AC NOT SIGN */ + //case XK_hyphen 0x00ad /* U+00AD SOFT HYPHEN */ + //case XK_registered 0x00ae /* U+00AE REGISTERED SIGN */ + //case XK_macron 0x00af /* U+00AF MACRON */ + //case XK_degree 0x00b0 /* U+00B0 DEGREE SIGN */ + //case XK_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */ + //case XK_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */ + //case XK_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */ + //case XK_acute 0x00b4 /* U+00B4 ACUTE ACCENT */ + //case XK_mu 0x00b5 /* U+00B5 MICRO SIGN */ + //case XK_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */ + //case XK_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */ + //case XK_cedilla 0x00b8 /* U+00B8 CEDILLA */ + //case XK_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */ + //case XK_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */ + //case XK_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ + //case XK_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */ + //case XK_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */ + //case XK_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */ + //case XK_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */ + //case XK_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ + //case XK_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ + //case XK_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + //case XK_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ + //case XK_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ + //case XK_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ + //case XK_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */ + //case XK_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ + //case XK_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ + //case XK_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ + //case XK_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + //case XK_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ + //case XK_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ + //case XK_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ + //case XK_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + //case XK_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ + //case XK_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */ + //case XK_Eth 0x00d0 /* deprecated */ + //case XK_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ + //case XK_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ + //case XK_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ + //case XK_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + //case XK_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ + //case XK_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ + //case XK_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */ + //case XK_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ + //case XK_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ + //case XK_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ + //case XK_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ + //case XK_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + //case XK_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ + //case XK_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ + //case XK_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */ + //case XK_Thorn 0x00de /* deprecated */ + //case XK_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */ + //case XK_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ + //case XK_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ + //case XK_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ + //case XK_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ + //case XK_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ + //case XK_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ + //case XK_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */ + //case XK_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ + //case XK_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ + //case XK_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ + //case XK_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ + //case XK_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ + //case XK_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ + //case XK_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ + //case XK_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ + //case XK_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ + //case XK_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */ + //case XK_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ + //case XK_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ + //case XK_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ + //case XK_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ + //case XK_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ + //case XK_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ + //case XK_division 0x00f7 /* U+00F7 DIVISION SIGN */ + //case XK_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ + //case XK_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ + //case XK_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ + //case XK_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ + //case XK_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ + //case XK_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ + //case XK_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ + //case XK_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */ + //case XK_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ + + //case XK_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */ + //case XK_breve 0x01a2 /* U+02D8 BREVE */ + //case XK_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */ + //case XK_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */ + //case XK_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */ + //case XK_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */ + //case XK_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */ + //case XK_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */ + //case XK_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */ + //case XK_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */ + //case XK_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + //case XK_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */ + //case XK_ogonek 0x01b2 /* U+02DB OGONEK */ + //case XK_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */ + //case XK_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */ + //case XK_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */ + //case XK_caron 0x01b7 /* U+02C7 CARON */ + //case XK_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */ + //case XK_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */ + //case XK_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */ + //case XK_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */ + //case XK_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */ + //case XK_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */ + //case XK_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */ + //case XK_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */ + //case XK_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */ + //case XK_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */ + //case XK_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */ + //case XK_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */ + //case XK_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */ + //case XK_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */ + //case XK_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */ + //case XK_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */ + //case XK_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */ + //case XK_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */ + //case XK_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + //case XK_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */ + //case XK_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */ + //case XK_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + //case XK_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */ + //case XK_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */ + //case XK_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */ + //case XK_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */ + //case XK_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */ + //case XK_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */ + //case XK_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */ + //case XK_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */ + //case XK_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */ + //case XK_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */ + //case XK_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */ + //case XK_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */ + //case XK_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + //case XK_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */ + //case XK_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */ + //case XK_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + //case XK_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */ + //case XK_abovedot 0x01ff /* U+02D9 DOT ABOVE */ + //case XK_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */ + //case XK_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + //case XK_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */ + //case XK_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */ + //case XK_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + //case XK_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */ + //case XK_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */ + //case XK_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */ + //case XK_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */ + //case XK_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */ + //case XK_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */ + //case XK_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + //case XK_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */ + //case XK_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + //case XK_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */ + //case XK_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + //case XK_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */ + //case XK_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */ + //case XK_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */ + //case XK_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */ + //case XK_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */ + //case XK_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */ + //case XK_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */ + //case XK_kappa 0x03a2 /* deprecated */ + //case XK_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */ + //case XK_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */ + //case XK_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */ + //case XK_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */ + //case XK_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */ + //case XK_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */ + //case XK_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */ + //case XK_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */ + //case XK_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */ + //case XK_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */ + //case XK_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */ + //case XK_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */ + //case XK_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */ + //case XK_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */ + //case XK_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */ + //case XK_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */ + //case XK_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */ + //case XK_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */ + //case XK_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */ + //case XK_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */ + //case XK_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */ + //case XK_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */ + //case XK_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */ + //case XK_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */ + //case XK_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */ + //case XK_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */ + //case XK_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */ + //case XK_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */ + //case XK_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */ + //case XK_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */ + //case XK_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */ + //case XK_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */ + //case XK_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */ + //case XK_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */ + //case XK_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */ + //case XK_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */ + //case XK_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */ + //case XK_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */ + //case XK_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */ + //case XK_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */ + //case XK_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */ + //case XK_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */ + //case XK_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */ + //case XK_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */ + //case XK_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */ + //case XK_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */ + //case XK_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */ + //case XK_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */ + //case XK_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */ + //case XK_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */ + //case XK_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */ + //case XK_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */ + //case XK_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */ + //case XK_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */ + //case XK_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */ + //case XK_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */ + //case XK_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */ + //case XK_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */ + //case XK_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */ + //case XK_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */ + //case XK_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */ + //case XK_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */ + //case XK_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */ + default: + qDebug() << "Unknown Key"; + } + qDebug() << " -- Simple Qt Map:" << (Qt::Key)(symbol); + qDebug() << " -- Key Sequence Map:" << QKeySequence(symbol); + qDebug() << " - Not implemented yet"; + return Qt::Key_unknown; +} + +NativeWindowSystem::MouseButton NativeWindowSystem::MouseToQt(int keycode){ + switch(keycode){ + case 1: + return NativeWindowSystem::LeftButton; + case 3: + return NativeWindowSystem::RightButton; + case 2: + return NativeWindowSystem::MidButton; + case 4: + return NativeWindowSystem::WheelUp; + case 5: + return NativeWindowSystem::WheelDown; + case 6: + return NativeWindowSystem::WheelLeft; + case 7: + return NativeWindowSystem::WheelRight; + case 8: + return NativeWindowSystem::BackButton; //Not sure if this is correct yet (1/27/17) + case 9: + return NativeWindowSystem::ForwardButton; //Not sure if this is correct yet (1/27/17) + default: + return NativeWindowSystem::NoButton; + } +} diff --git a/src-qt5/core/libLumina/NativeWindow.pri b/src-qt5/core/libLumina/NativeWindow.pri index fef9c736..013291ff 100644 --- a/src-qt5/core/libLumina/NativeWindow.pri +++ b/src-qt5/core/libLumina/NativeWindow.pri @@ -5,6 +5,7 @@ LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damag SOURCES *= $${PWD}/NativeWindow.cpp \ $${PWD}/NativeWindowSystem.cpp \ + $${PWD}/NativeKeyToQt.cpp \ $${PWD}/NativeEventFilter.cpp HEADERS *= $${PWD}/NativeWindow.h \ diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index 73bba1a9..f208cbf1 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -19,15 +19,6 @@ #include -#define XK_MISCELLANY -#define XK_XKB_KEYS -#define XK_LATIN1 -#define XK_LATIN2 -#define XK_LATIN3 -#define XK_LATIN4 -//NOTE: Look at the keysymdef.h file for additional define/characters which we may need later -#include - //XCB Library includes #include #include @@ -38,7 +29,6 @@ #include #include #include -#include //XLib includes (XCB Damage lib does not appear to register for damage events properly) #include @@ -260,101 +250,6 @@ void NativeWindowSystem::stop(){ } -//Small simplification functions -Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ - static xcb_key_symbols_t *SYM = 0; - if(SYM==0){ SYM = xcb_key_symbols_alloc(QX11Info::connection()); } - xcb_keysym_t symbol = xcb_key_symbols_get_keysym(SYM, keycode,0); - //not sure about the "column" input - we want raw keys though so ignore the "modified" key states (columns) for now - qDebug() << "Try to convert keycode to Qt::Key:" << keycode << symbol; - //Now map this symbol to the appropriate Qt::Key enumeration - if(xcb_is_keypad_key(symbol)){ qDebug() << "Keypad Key"; } - else if(xcb_is_private_keypad_key(symbol)){ qDebug() << "Private Keypad Key"; } - else if(xcb_is_cursor_key(symbol)){ qDebug() << "Cursor Key"; } - else if(xcb_is_pf_key(symbol)){ qDebug() << "PF Key"; } - else if(xcb_is_function_key(symbol)){ - switch(symbol){ - case XK_F1: return Qt::Key_F1; - case XK_F2: return Qt::Key_F2; - case XK_F3: return Qt::Key_F3; - case XK_F4: return Qt::Key_F4; - case XK_F5: return Qt::Key_F5; - case XK_F6: return Qt::Key_F6; - case XK_F7: return Qt::Key_F7; - case XK_F8: return Qt::Key_F8; - case XK_F9: return Qt::Key_F9; - case XK_F10: return Qt::Key_F10; - case XK_F11: return Qt::Key_F11; - case XK_F12: return Qt::Key_F12; - case XK_F13: return Qt::Key_F13; - case XK_F14: return Qt::Key_F14; - case XK_F15: return Qt::Key_F15; - case XK_F16: return Qt::Key_F16; - case XK_F17: return Qt::Key_F17; - case XK_F18: return Qt::Key_F18; - case XK_F19: return Qt::Key_F19; - case XK_F20: return Qt::Key_F20; - case XK_F21: return Qt::Key_F21; - case XK_F22: return Qt::Key_F22; - case XK_F23: return Qt::Key_F23; - case XK_F24: return Qt::Key_F24; - case XK_F25: return Qt::Key_F25; - case XK_F26: return Qt::Key_F26; - case XK_F27: return Qt::Key_F27; - case XK_F28: return Qt::Key_F28; - case XK_F29: return Qt::Key_F29; - case XK_F30: return Qt::Key_F30; - case XK_F31: return Qt::Key_F31; - case XK_F32: return Qt::Key_F32; - case XK_F33: return Qt::Key_F33; - case XK_F34: return Qt::Key_F34; - case XK_F35: return Qt::Key_F35; - default: - qDebug() << "Unknown Function Key"; - } - }else if(xcb_is_misc_function_key(symbol)){ qDebug() << "Misc Function Key"; } - else if(xcb_is_modifier_key(symbol)){ - qDebug() << "Modifier Key"; - /*switch(symbol){ - case: XK_ - }*/ - }else if(!QKeySequence(symbol).isEmpty()){ - //One of the standard keys, go ahead and do a direct map - qDebug() << " -- [GOT MATCH]" << QKeySequence(symbol); - return Qt::Key_unknown; //QKeySequence(symbol)[0]; //only ever one key in this method - }else{ - qDebug() << " -- Simple Qt Map:" << (Qt::Key)(symbol); - qDebug() << " -- Key Sequence Map:" << QKeySequence(symbol); - qDebug() << " - Not implemented yet"; - } - return Qt::Key_unknown; -} - -NativeWindowSystem::MouseButton NativeWindowSystem::MouseToQt(int keycode){ - switch(keycode){ - case 1: - return NativeWindowSystem::LeftButton; - case 3: - return NativeWindowSystem::RightButton; - case 2: - return NativeWindowSystem::MidButton; - case 4: - return NativeWindowSystem::WheelUp; - case 5: - return NativeWindowSystem::WheelDown; - case 6: - return NativeWindowSystem::WheelLeft; - case 7: - return NativeWindowSystem::WheelRight; - case 8: - return NativeWindowSystem::BackButton; //Not sure if this is correct yet (1/27/17) - case 9: - return NativeWindowSystem::ForwardButton; //Not sure if this is correct yet (1/27/17) - default: - return NativeWindowSystem::NoButton; - } -} - // === PRIVATE === NativeWindow* NativeWindowSystem::findWindow(WId id, bool checkRelated){ //qDebug() << "Find Window:" << id; @@ -877,14 +772,15 @@ void NativeWindowSystem::GotPong(WId id){ void NativeWindowSystem::NewKeyPress(int keycode, WId win){ emit NewInputEvent(); if(screenLocked){ return; } - KeycodeToQt(keycode); - emit KeyPressDetected(win, keycode); + Qt::Key key = KeycodeToQt(keycode); + if(key!=Qt::Key_unknown){ emit KeyPressDetected(win, key); } } void NativeWindowSystem::NewKeyRelease(int keycode, WId win){ emit NewInputEvent(); if(screenLocked){ return; } - emit KeyReleaseDetected(win, keycode); + Qt::Key key = KeycodeToQt(keycode); + if(key!=Qt::Key_unknown){ emit KeyReleaseDetected(win, key); } } void NativeWindowSystem::NewMousePress(int buttoncode, WId win){ diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h index 008a204f..97208c2f 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/core/libLumina/NativeWindowSystem.h @@ -128,8 +128,8 @@ signals: void NewWindowAvailable(NativeWindow*); void NewTrayWindowAvailable(NativeWindow*); void NewInputEvent(); //a mouse or keypress was detected (lock-state independent); - void KeyPressDetected(WId, int); //only emitted if lockstate = false - void KeyReleaseDetected(WId, int); //only emitted if lockstate = false + void KeyPressDetected(WId, Qt::Key); //only emitted if lockstate = false + void KeyReleaseDetected(WId, Qt::Key); //only emitted if lockstate = false void MousePressDetected(WId, NativeWindowSystem::MouseButton); //only emitted if lockstate = false void MouseReleaseDetected(WId, NativeWindowSystem::MouseButton); //only emitted if lockstate = false -- cgit From aec75b23b1471993287b2209d756d8b84efe22fa Mon Sep 17 00:00:00 2001 From: ZackaryWelch Date: Tue, 11 Jul 2017 11:33:44 -0400 Subject: Added more key support for Lumina 2.0 --- src-qt5/core/libLumina/NativeKeyToQt.cpp | 488 +++++++++++++++---------------- 1 file changed, 244 insertions(+), 244 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeKeyToQt.cpp b/src-qt5/core/libLumina/NativeKeyToQt.cpp index b6af9b6c..06056be7 100644 --- a/src-qt5/core/libLumina/NativeKeyToQt.cpp +++ b/src-qt5/core/libLumina/NativeKeyToQt.cpp @@ -248,251 +248,251 @@ Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ case XK_braceright: return Qt::Key_BraceRight; case XK_asciitilde: return Qt::Key_AsciiTilde; - //case XK_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */ - //case XK_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */ - //case XK_cent 0x00a2 /* U+00A2 CENT SIGN */ - //case XK_sterling 0x00a3 /* U+00A3 POUND SIGN */ - //case XK_currency 0x00a4 /* U+00A4 CURRENCY SIGN */ - //case XK_yen 0x00a5 /* U+00A5 YEN SIGN */ - //case XK_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */ - //case XK_section 0x00a7 /* U+00A7 SECTION SIGN */ - //case XK_diaeresis 0x00a8 /* U+00A8 DIAERESIS */ - //case XK_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */ - //case XK_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */ - //case XK_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ - //case XK_notsign 0x00ac /* U+00AC NOT SIGN */ - //case XK_hyphen 0x00ad /* U+00AD SOFT HYPHEN */ - //case XK_registered 0x00ae /* U+00AE REGISTERED SIGN */ - //case XK_macron 0x00af /* U+00AF MACRON */ - //case XK_degree 0x00b0 /* U+00B0 DEGREE SIGN */ - //case XK_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */ - //case XK_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */ - //case XK_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */ - //case XK_acute 0x00b4 /* U+00B4 ACUTE ACCENT */ - //case XK_mu 0x00b5 /* U+00B5 MICRO SIGN */ - //case XK_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */ - //case XK_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */ - //case XK_cedilla 0x00b8 /* U+00B8 CEDILLA */ - //case XK_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */ - //case XK_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */ - //case XK_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ - //case XK_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */ - //case XK_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */ - //case XK_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */ - //case XK_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */ - //case XK_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ - //case XK_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ - //case XK_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ - //case XK_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ - //case XK_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ - //case XK_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ - //case XK_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */ - //case XK_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ - //case XK_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ - //case XK_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ - //case XK_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ - //case XK_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ - //case XK_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ - //case XK_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ - //case XK_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ - //case XK_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ - //case XK_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */ - //case XK_Eth 0x00d0 /* deprecated */ - //case XK_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ - //case XK_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ - //case XK_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ - //case XK_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ - //case XK_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ - //case XK_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ - //case XK_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */ - //case XK_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ - //case XK_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ - //case XK_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ - //case XK_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ - //case XK_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ - //case XK_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ - //case XK_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ - //case XK_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */ - //case XK_Thorn 0x00de /* deprecated */ - //case XK_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */ - //case XK_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ - //case XK_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ - //case XK_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ - //case XK_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ - //case XK_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ - //case XK_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ - //case XK_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */ - //case XK_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ - //case XK_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ - //case XK_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ - //case XK_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ - //case XK_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ - //case XK_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ - //case XK_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ - //case XK_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ - //case XK_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ - //case XK_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */ - //case XK_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ - //case XK_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ - //case XK_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ - //case XK_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ - //case XK_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ - //case XK_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ - //case XK_division 0x00f7 /* U+00F7 DIVISION SIGN */ - //case XK_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ - //case XK_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ - //case XK_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ - //case XK_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ - //case XK_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ - //case XK_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ - //case XK_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ - //case XK_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */ - //case XK_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ + case XK_nobreakspace: return Qt::Key_nobreakspace; + case XK_exclamdown: return Qt::Key_exclamdown; + case XK_cent: return Qt::Key_cent; + case XK_sterling: return Qt::Key_sterling; + case XK_currency: return Qt::Key_currency; + case XK_yen: return Qt::Key_yen; + case XK_brokenbar: return Qt::Key_brokenbar; + case XK_section: return Qt::Key_section; + case XK_diaeresis: return Qt::Key_diaeresis; + case XK_copyright: return Qt::Key_copyright; + case XK_ordfeminine: return Qt::Key_ordfeminine; + case XK_guillemotleft: return Qt::Key_guillemotleft; + case XK_notsign: return Qt::Key_notsign; + case XK_hyphen: return Qt::Key_hyphen; + case XK_registered: return Qt::Key_registered; + case XK_macron: return Qt::Key_macron; + case XK_degree: return Qt::Key_degree; + case XK_plusminus: return Qt::Key_plusminus; + case XK_twosuperior: return Qt::Key_twosuperior; + case XK_threesuperior: return Qt::Key_threesuperior; + case XK_acute: return Qt::Key_acute; + case XK_mu: return Qt::Key_mu; + case XK_paragraph: return Qt::Key_paragraph; + case XK_periodcentered: return Qt::Key_periodcentered; + case XK_cedilla: return Qt::Key_cedilla; + case XK_onesuperior: return Qt::Key_onesuperior; + case XK_masculine: return Qt::Key_masculine; + case XK_guillemotright: return Qt::Key_guillemotright; + case XK_onequarter: return Qt::Key_onequarter; + case XK_onehalf: return Qt::Key_onehalf; + case XK_threequarters: return Qt::Key_threequarters; + case XK_questiondown: return Qt::Key_questiondown; + case XK_Agrave: return Qt::Key_Agrave; + case XK_Aacute: return Qt::Key_Aacute; + case XK_Acircumflex: return Qt::Key_Acircumflex; + case XK_Atilde: return Qt::Key_Atilde; + case XK_Adiaeresis: return Qt::Key_Adiaeresis; + case XK_Aring: return Qt::Key_Aring; + case XK_AE: return Qt::Key_AE; + case XK_Ccedilla: return Qt::Key_Ccedilla; + case XK_Egrave: return Qt::Key_Egrave; + case XK_Eacute: return Qt::Key_Eacute; + case XK_Ecircumflex: return Qt::Key_Ecircumflex; + case XK_Ediaeresis: return Qt::Key_Ediaeresis; + case XK_Igrave: return Qt::Key_Igrave; + case XK_Iacute: return Qt::Key_Iacute; + case XK_Icircumflex: return Qt::Key_Icircumflex; + case XK_Idiaeresis: return Qt::Key_Idiaeresis; + case XK_ETH: return Qt::Key_ETH; + //case XK_Eth: return Qt::Key_Eth; + case XK_Ntilde: return Qt::Key_Ntilde; + case XK_Ograve: return Qt::Key_Ograve; + case XK_Oacute: return Qt::Key_Oacute; + case XK_Ocircumflex: return Qt::Key_Ocircumflex; + case XK_Otilde: return Qt::Key_Otilde; + case XK_Odiaeresis: return Qt::Key_Odiaeresis; + case XK_multiply: return Qt::Key_multiply; + //case XK_Oslash: return Qt::Key_AsciiTilde; + case XK_Ooblique: return Qt::Key_Ooblique; + case XK_Ugrave: return Qt::Key_Ugrave; + case XK_Uacute: return Qt::Key_Uacute; + case XK_Ucircumflex: return Qt::Key_Ucircumflex; + case XK_Udiaeresis: return Qt::Key_Udiaeresis; + case XK_Yacute: return Qt::Key_Yacute; + case XK_THORN: return Qt::Key_THORN; + //case XK_Thorn: return Qt::Key_AsciiTilde; + case XK_ssharp: return Qt::Key_ssharp; + /*case XK_agrave: return Qt::Key_AsciiTilde; + case XK_aacute: return Qt::Key_AsciiTilde; + case XK_acircumflex: return Qt::Key_AsciiTilde; + case XK_atilde: return Qt::Key_AsciiTilde; + case XK_adiaeresis: return Qt::Key_AsciiTilde; + case XK_aring: return Qt::Key_AsciiTilde; + case XK_ae: return Qt::Key_AsciiTilde; + case XK_ccedilla: return Qt::Key_AsciiTilde; + case XK_egrave: return Qt::Key_AsciiTilde; + case XK_eacute: return Qt::Key_AsciiTilde; + case XK_ecircumflex: return Qt::Key_AsciiTilde; + case XK_ediaeresis: return Qt::Key_AsciiTilde; + case XK_igrave: return Qt::Key_AsciiTilde; + case XK_iacute: return Qt::Key_AsciiTilde; + case XK_icircumflex: return Qt::Key_AsciiTilde; + case XK_idiaeresis: return Qt::Key_AsciiTilde; + case XK_eth: return Qt::Key_AsciiTilde; + case XK_ntilde: return Qt::Key_AsciiTilde; + case XK_ograve: return Qt::Key_AsciiTilde; + case XK_oacute: return Qt::Key_AsciiTilde; + case XK_ocircumflex: return Qt::Key_AsciiTilde; + case XK_otilde: return Qt::Key_AsciiTilde; + case XK_odiaeresis: return Qt::Key_AsciiTilde; + case XK_division: return Qt::Key_AsciiTilde; + case XK_oslash: return Qt::Key_AsciiTilde; + case XK_ooblique: return Qt::Key_AsciiTilde; + case XK_ugrave: return Qt::Key_AsciiTilde; + case XK_uacute: return Qt::Key_AsciiTilde; + case XK_ucircumflex: return Qt::Key_AsciiTilde; + case XK_udiaeresis: return Qt::Key_AsciiTilde; + case XK_yacute: return Qt::Key_AsciiTilde; + case XK_thorn: return Qt::Key_AsciiTilde; + case XK_ydiaeresis: return Qt::Key_AsciiTilde; - //case XK_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */ - //case XK_breve 0x01a2 /* U+02D8 BREVE */ - //case XK_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */ - //case XK_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */ - //case XK_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */ - //case XK_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */ - //case XK_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */ - //case XK_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */ - //case XK_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */ - //case XK_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */ - //case XK_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */ - //case XK_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */ - //case XK_ogonek 0x01b2 /* U+02DB OGONEK */ - //case XK_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */ - //case XK_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */ - //case XK_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */ - //case XK_caron 0x01b7 /* U+02C7 CARON */ - //case XK_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */ - //case XK_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */ - //case XK_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */ - //case XK_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */ - //case XK_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */ - //case XK_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */ - //case XK_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */ - //case XK_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */ - //case XK_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */ - //case XK_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */ - //case XK_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */ - //case XK_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */ - //case XK_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */ - //case XK_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */ - //case XK_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */ - //case XK_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */ - //case XK_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */ - //case XK_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */ - //case XK_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ - //case XK_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */ - //case XK_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */ - //case XK_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ - //case XK_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */ - //case XK_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */ - //case XK_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */ - //case XK_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */ - //case XK_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */ - //case XK_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */ - //case XK_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */ - //case XK_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */ - //case XK_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */ - //case XK_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */ - //case XK_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */ - //case XK_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */ - //case XK_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */ - //case XK_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */ - //case XK_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */ - //case XK_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */ - //case XK_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */ - //case XK_abovedot 0x01ff /* U+02D9 DOT ABOVE */ - //case XK_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */ - //case XK_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ - //case XK_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */ - //case XK_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */ - //case XK_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ - //case XK_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */ - //case XK_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */ - //case XK_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */ - //case XK_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */ - //case XK_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */ - //case XK_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */ - //case XK_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ - //case XK_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */ - //case XK_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ - //case XK_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */ - //case XK_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ - //case XK_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */ - //case XK_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */ - //case XK_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */ - //case XK_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */ - //case XK_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */ - //case XK_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */ - //case XK_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */ - //case XK_kappa 0x03a2 /* deprecated */ - //case XK_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */ - //case XK_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */ - //case XK_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */ - //case XK_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */ - //case XK_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */ - //case XK_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */ - //case XK_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */ - //case XK_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */ - //case XK_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */ - //case XK_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */ - //case XK_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */ - //case XK_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */ - //case XK_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */ - //case XK_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */ - //case XK_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */ - //case XK_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */ - //case XK_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */ - //case XK_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */ - //case XK_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */ - //case XK_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */ - //case XK_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */ - //case XK_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */ - //case XK_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */ - //case XK_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */ - //case XK_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */ - //case XK_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */ - //case XK_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */ - //case XK_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */ - //case XK_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */ - //case XK_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */ - //case XK_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */ - //case XK_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */ - //case XK_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */ - //case XK_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */ - //case XK_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */ - //case XK_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */ - //case XK_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */ - //case XK_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */ - //case XK_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */ - //case XK_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */ - //case XK_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */ - //case XK_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */ - //case XK_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */ - //case XK_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */ - //case XK_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */ - //case XK_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */ - //case XK_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */ - //case XK_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */ - //case XK_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */ - //case XK_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */ - //case XK_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */ - //case XK_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */ - //case XK_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */ - //case XK_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */ - //case XK_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */ - //case XK_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */ - //case XK_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */ - //case XK_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */ - //case XK_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */ - //case XK_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */ - //case XK_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */ - //case XK_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */ - //case XK_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */ + case: XK_Agonek: return Qt::Key_AsciiTilde; + case XK_breve: return Qt::Key_AsciiTilde; + case XK_Lstroke: return Qt::Key_AsciiTilde; + case XK_Lcaron: return Qt::Key_AsciiTilde; + case XK_Sacute: return Qt::Key_AsciiTilde; + case XK_Scaron: return Qt::Key_AsciiTilde; + case XK_Scedilla: return Qt::Key_AsciiTilde; + case XK_Tcaron: return Qt::Key_AsciiTilde; + case XK_Zacute: return Qt::Key_AsciiTilde; + case XK_Zcaron: return Qt::Key_AsciiTilde; + case XK_Zabovedot: return Qt::Key_AsciiTilde; + case XK_aogonek: return Qt::Key_AsciiTilde; + case XK_ogonek: return Qt::Key_AsciiTilde; + case XK_lstroke: return Qt::Key_AsciiTilde; + case XK_lcaron: return Qt::Key_AsciiTilde; + case XK_sacute: return Qt::Key_AsciiTilde; + case XK_caron: return Qt::Key_AsciiTilde; + case XK_scaron: return Qt::Key_AsciiTilde; + case XK_scedilla: return Qt::Key_AsciiTilde; + case XK_tcaron: return Qt::Key_AsciiTilde; + case XK_zacute: return Qt::Key_AsciiTilde; + case XK_doubleacute: return Qt::Key_AsciiTilde; + case XK_zcaron: return Qt::Key_AsciiTilde; + case XK_zabovedot: return Qt::Key_AsciiTilde; + case XK_Racute: return Qt::Key_AsciiTilde; + case XK_Abreve: return Qt::Key_AsciiTilde; + case XK_Lacute: return Qt::Key_AsciiTilde; + case XK_Cacute: return Qt::Key_AsciiTilde; + case XK_Ccaron: return Qt::Key_AsciiTilde; + case XK_Eogonek: return Qt::Key_AsciiTilde; + case XK_Ecaron: return Qt::Key_AsciiTilde; + case XK_Dcaron: return Qt::Key_AsciiTilde; + case XK_Dstroke: return Qt::Key_AsciiTilde; + case XK_Nacute: return Qt::Key_AsciiTilde; + case XK_Ncaron: return Qt::Key_AsciiTilde; + case XK_Odoubleacute: return Qt::Key_AsciiTilde; + case XK_Rcaron: return Qt::Key_AsciiTilde; + case XK_Uring: return Qt::Key_AsciiTilde; + case XK_Udoubleacute: return Qt::Key_AsciiTilde; + case XK_Tcedilla: return Qt::Key_AsciiTilde; + case XK_racute: return Qt::Key_AsciiTilde; + case XK_abreve: return Qt::Key_AsciiTilde; + case XK_lacute: return Qt::Key_AsciiTilde; + case XK_cacute: return Qt::Key_AsciiTilde; + case XK_ccaron: return Qt::Key_AsciiTilde; + case XK_eogonek: return Qt::Key_AsciiTilde; + case XK_ecaron: return Qt::Key_AsciiTilde; + case XK_dcaron: return Qt::Key_AsciiTilde; + case XK_dstroke: return Qt::Key_AsciiTilde; + case XK_nacute: return Qt::Key_AsciiTilde; + case XK_ncaron: return Qt::Key_AsciiTilde; + case XK_odoubleacute: return Qt::Key_AsciiTilde; + case XK_rcaron: return Qt::Key_AsciiTilde; + case XK_uring: return Qt::Key_AsciiTilde; + case XK_udoubleacute: return Qt::Key_AsciiTilde; + case XK_tcedilla: return Qt::Key_AsciiTilde; + case XK_abovedot: return Qt::Key_AsciiTilde; + case XK_Hstroke: return Qt::Key_AsciiTilde; + case XK_Hcircumflex: return Qt::Key_AsciiTilde; + case XK_Iabovedot: return Qt::Key_AsciiTilde; + case XK_Gbreve: return Qt::Key_AsciiTilde; + case XK_Jcircumflex: return Qt::Key_AsciiTilde; + case XK_hstroke: return Qt::Key_AsciiTilde; + case XK_hcircumflex: return Qt::Key_AsciiTilde; + case XK_idotless: return Qt::Key_AsciiTilde; + case XK_gbreve: return Qt::Key_AsciiTilde; + case XK_jcircumflex: return Qt::Key_AsciiTilde; + case XK_Cabovedot: return Qt::Key_AsciiTilde; + case XK_Ccircumflex: return Qt::Key_AsciiTilde; + case XK_Gabovedot: return Qt::Key_AsciiTilde; + case XK_Gcircumflex: return Qt::Key_AsciiTilde; + case XK_Ubreve: return Qt::Key_AsciiTilde; + case XK_Scircumflex: return Qt::Key_AsciiTilde; + case XK_cabovedot: return Qt::Key_AsciiTilde; + case XK_ccircumflex: return Qt::Key_AsciiTilde; + case XK_gabovedot: return Qt::Key_AsciiTilde; + case XK_gcircumflex: return Qt::Key_AsciiTilde; + case XK_ubreve: return Qt::Key_AsciiTilde; + case XK_scircumflex: return Qt::Key_AsciiTilde; + case XK_kra: return Qt::Key_AsciiTilde; + case XK_kappa: return Qt::Key_AsciiTilde; + case XK_Rcedilla: return Qt::Key_AsciiTilde; + case XK_Itilde: return Qt::Key_AsciiTilde; + case XK_Lcedilla: return Qt::Key_AsciiTilde; + case XK_Emacron: return Qt::Key_AsciiTilde; + case XK_Gcedilla: return Qt::Key_AsciiTilde; + case XK_Tslash: return Qt::Key_AsciiTilde; + case XK_rcedilla: return Qt::Key_AsciiTilde; + case XK_itilde: return Qt::Key_AsciiTilde; + case XK_lcedilla: return Qt::Key_AsciiTilde; + case XK_emacron: return Qt::Key_AsciiTilde; + case XK_gcedilla: return Qt::Key_AsciiTilde; + case XK_tslash: return Qt::Key_AsciiTilde; + case XK_ENG: return Qt::Key_AsciiTilde; + case XK_eng: return Qt::Key_AsciiTilde; + case XK_Amacron: return Qt::Key_AsciiTilde; + case XK_Iogonek: return Qt::Key_AsciiTilde; + case XK_Eabovedot: return Qt::Key_AsciiTilde; + case XK_Imacron: return Qt::Key_AsciiTilde; + case XK_Ncedilla: return Qt::Key_AsciiTilde; + case XK_Omacron: return Qt::Key_AsciiTilde; + case XK_Kcedilla: return Qt::Key_AsciiTilde; + case XK_Uogonek: return Qt::Key_AsciiTilde; + case XK_Utilde: return Qt::Key_AsciiTilde; + case XK_Umacron: return Qt::Key_AsciiTilde; + case XK_amacron: return Qt::Key_AsciiTilde; + case XK_iogonek: return Qt::Key_AsciiTilde; + case XK_eabovedot: return Qt::Key_AsciiTilde; + case XK_imacron: return Qt::Key_AsciiTilde; + case XK_ncedilla: return Qt::Key_AsciiTilde; + case XK_omacron: return Qt::Key_AsciiTilde; + case XK_kcedilla: return Qt::Key_AsciiTilde; + case XK_uogonek: return Qt::Key_AsciiTilde; + case XK_utilde: return Qt::Key_AsciiTilde; + case XK_umacron: return Qt::Key_AsciiTilde; + case XK_Wcircumflex: return Qt::Key_AsciiTilde; + case XK_wcircumflex: return Qt::Key_AsciiTilde; + case XK_Ycircumflex: return Qt::Key_AsciiTilde; + case XK_ycircumflex: return Qt::Key_AsciiTilde; + case XK_Babovedot: return Qt::Key_AsciiTilde; + case XK_babovedot: return Qt::Key_AsciiTilde; + case XK_Dabovedot: return Qt::Key_AsciiTilde; + case XK_dabovedot: return Qt::Key_AsciiTilde; + case XK_Fabovedot: return Qt::Key_AsciiTilde; + case XK_fabovedot: return Qt::Key_AsciiTilde; + case XK_Mabovedot: return Qt::Key_AsciiTilde; + case XK_mabovedot: return Qt::Key_AsciiTilde; + case XK_Pabovedot: return Qt::Key_AsciiTilde; + case XK_pabovedot: return Qt::Key_AsciiTilde; + case XK_Sabovedot: return Qt::Key_AsciiTilde; + case XK_sabovedot: return Qt::Key_AsciiTilde; + case XK_Tabovedot: return Qt::Key_AsciiTilde; + case XK_tabovedot: return Qt::Key_AsciiTilde; + case XK_Wgrave: return Qt::Key_AsciiTilde; + case XK_wgrave: return Qt::Key_AsciiTilde; + case XK_Wacute: return Qt::Key_AsciiTilde; + case XK_wacute: return Qt::Key_AsciiTilde; + case XK_Wdiaeresis: return Qt::Key_AsciiTilde; + case XK_wdiaeresis: return Qt::Key_AsciiTilde; + case XK_Ygrave: return Qt::Key_AsciiTilde; + case XK_ygrave: return Qt::Key_AsciiTilde; + case XK_OE: return Qt::Key_AsciiTilde; + case XK_oe: return Qt::Key_AsciiTilde; + case XK_Ydiaeresis: return Qt::Key_AsciiTilde;*/ default: qDebug() << "Unknown Key"; } -- cgit From fc7146bbf3e067fc58ae9d5d21fa7403e1db5326 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 11 Jul 2017 14:06:50 -0400 Subject: Start adding some default keyboard shortcuts/files to Lumina 2. --- src-qt5/core/libLumina/DesktopSettings.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/DesktopSettings.cpp b/src-qt5/core/libLumina/DesktopSettings.cpp index bd0325ec..47dc29de 100644 --- a/src-qt5/core/libLumina/DesktopSettings.cpp +++ b/src-qt5/core/libLumina/DesktopSettings.cpp @@ -121,7 +121,7 @@ void DesktopSettings::parseSystemSettings(){ //Now determine the runmode for this user struct passwd *pw = getpwuid(getuid()); - if(pw!=0){ + if(pw!=0){ QString cuser = QString(pw->pw_name); free(pw); //done with this structure if( settings[path]->value("fulluser_users", QStringList()).toStringList().contains(cuser) ){ runmode = DesktopSettings::UserFull; } @@ -133,10 +133,10 @@ void DesktopSettings::parseSystemSettings(){ gid_t grpList[100]; int grpSize = 100; if( getgrouplist(cuser.toLocal8Bit(), getgid(), grpList, &grpSize) > 0 ){ - QStringList groups; - for(int i=0; igr_name); free(g); } @@ -146,18 +146,18 @@ void DesktopSettings::parseSystemSettings(){ if( (fromfile+groups).removeDuplicates() > 0 ){ runmode = DesktopSettings::UserFull; } else{ fromfile = settings[path]->value("fullsystem_groups", QStringList()).toStringList(); - fromfile.removeDuplicates(); + fromfile.removeDuplicates(); if((fromfile+groups).removeDuplicates() > 0 ){ runmode = DesktopSettings::SystemFull; } else{ fromfile = settings[path]->value("staticinterface_groups", QStringList()).toStringList(); - fromfile.removeDuplicates(); + fromfile.removeDuplicates(); if((fromfile+groups).removeDuplicates() > 0 ){ runmode = DesktopSettings::SystemInterface; } } } - } //end group list read + } //end group list read } }else{ - runmode = DesktopSettings::SystemFull; //could not read user name - assume system files only + runmode = DesktopSettings::SystemFull; //could not read user name - assume system files only } break; //found this file - go ahead and stop now (no hierarchy for this special file) @@ -256,7 +256,7 @@ void DesktopSettings::fileChanged(QString file){ QList< DesktopSettings::File > types = files.keys(); for(int i=0; i Date: Wed, 12 Jul 2017 09:04:58 -0400 Subject: Update the "open-with" menu for lumina-fm so that is shows recommendations directly in the menu. --- src-qt5/core/libLumina/LuminaXDG.h | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaXDG.h b/src-qt5/core/libLumina/LuminaXDG.h index d159ef43..cc250c7e 100644 --- a/src-qt5/core/libLumina/LuminaXDG.h +++ b/src-qt5/core/libLumina/LuminaXDG.h @@ -12,8 +12,6 @@ // *.desktop Exec Compliance Updated: 9/9/2014 // Mime Application Version Compliance: 1.0.1 (11/14/14) (Skips random *.desktop parsing: ~80% compliant) //=========================================== - - #ifndef _LUMINA_LIBRARY_XDG_H #define _LUMINA_LIBRARY_XDG_H @@ -83,7 +81,7 @@ public: bool saveDesktopFile(bool merge = true); //This will use the "filePath" variable for where to save the file - bool setAutoStarted(bool autostart = true); + bool setAutoStarted(bool autostart = true); }; // ======================== @@ -127,29 +125,29 @@ private: XDGDesktop *desk; void loadExtraInfo(); - + public: //Couple overloaded contructors LFileInfo(); LFileInfo(QString filepath); LFileInfo(QFileInfo info); - ~LFileInfo(){ - desk->deleteLater(); + ~LFileInfo(){ + desk->deleteLater(); } - + //Functions for accessing the extra information // -- Return the mimetype for the file QString mimetype(); - + // -- Return the icon file to use for this file QString iconfile(); //Note: This string is auto-formatted for use in the LXDG::findIcon() routine. - + // -- Check if this is an XDG desktop file bool isDesktopFile(); - + // -- Allow access to the internal XDG desktop data structure XDGDesktop* XDG(); - + //Other file type identification routines bool isImage(); //Is a readable image file (for thumbnail support) bool isAVFile(); //Is an audio/video file @@ -165,7 +163,7 @@ public: //static XDGDesktop* loadDesktopFile(QString filepath, bool&ok, QObject *parent = 0); //static bool saveDesktopFile(XDGDesktop *dFile, bool merge = true); //Check a *.desktop file for validity (showAll skips the DE-exclusivity checks) - //static bool checkValidity(XDGDesktop *dFile, bool showAll = true); + //static bool checkValidity(XDGDesktop *dFile, bool showAll = true); //Check for a valid executable static bool checkExec(QString exec); //Get a list of all the directories where *.desktop files exist @@ -210,7 +208,7 @@ public: static QStringList findAVFileExtensions(); //Load all the "globs2" mime database files static QStringList loadMimeFileGlobs2(); - + //Find all the autostart *.desktop files static QList findAutoStartFiles(bool includeInvalid = false); //static bool setAutoStarted(bool autostart, XDGDesktop *app); -- cgit From c7a44d46d9186fc243f9b66ba28260d424f9b1cb Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 12 Jul 2017 12:43:15 -0400 Subject: Fix a few random issues with Lumina2. --- src-qt5/core/libLumina/RootWindow.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp index 2fee5d96..31faaf50 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/RootWindow.cpp @@ -14,6 +14,7 @@ RootWindow::RootWindow() : QWidget(0, Qt::Window | Qt::BypassWindowManagerHint | Qt::WindowStaysOnBottomHint){ qRegisterMetaType("WId"); autoResizeTimer = 0; + this->setMouseTracking(true); } RootWindow::~RootWindow(){ -- cgit From 6a2af03c68033a9683de619b4ae6493a4f7254b7 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 13 Jul 2017 14:02:59 -0400 Subject: Large update to the window embedding systems - almost have the compositing up and running. --- src-qt5/core/libLumina/NativeEmbedWidget.cpp | 185 ++++++++++++++++++++++++++ src-qt5/core/libLumina/NativeEmbedWidget.h | 47 +++++++ src-qt5/core/libLumina/NativeWindow.cpp | 8 +- src-qt5/core/libLumina/NativeWindow.h | 1 + src-qt5/core/libLumina/NativeWindow.pri | 6 +- src-qt5/core/libLumina/NativeWindowSystem.cpp | 27 +--- src-qt5/core/libLumina/RootSubWindow.cpp | 33 +++-- src-qt5/core/libLumina/RootSubWindow.h | 4 +- 8 files changed, 263 insertions(+), 48 deletions(-) create mode 100644 src-qt5/core/libLumina/NativeEmbedWidget.cpp create mode 100644 src-qt5/core/libLumina/NativeEmbedWidget.h (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp new file mode 100644 index 00000000..fd5939dd --- /dev/null +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -0,0 +1,185 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "NativeEmbedWidget.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +//xcb_pixmap_t PIXBACK; //backend pixmap that compositing redirects to + +#define NORMAL_WIN_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ + XCB_EVENT_MASK_BUTTON_RELEASE | \ + XCB_EVENT_MASK_POINTER_MOTION | \ + XCB_EVENT_MASK_BUTTON_MOTION | \ + XCB_EVENT_MASK_EXPOSURE | \ + XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ + XCB_EVENT_MASK_ENTER_WINDOW| \ + XCB_EVENT_MASK_PROPERTY_CHANGE) + +inline void registerClientEvents(WId id){ + uint32_t value_list[1] = {NORMAL_WIN_EVENT_MASK}; + xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, value_list); +} + +// ============ +// PRIVATE +// ============ +//Simplification functions for the XCB/XLib interactions +void NativeEmbedWidget::syncWinSize(QSize sz){ + if(WIN==0){ return; } + qDebug() << "Sync Window Size:" << sz; + xcb_configure_window_value_list_t valList; + valList.x = 0; + valList.y = 0; + valList.width = sz.width(); + valList.height = sz.height(); + uint16_t mask = 0; + mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; + xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); +} + +void NativeEmbedWidget::syncWidgetSize(QSize sz){ + this->resize(sz); +} + +void NativeEmbedWidget::hideWindow(){ + xcb_unmap_window(QX11Info::connection(), WIN->id()); +} + +void NativeEmbedWidget::showWindow(){ + xcb_map_window(QX11Info::connection(), WIN->id()); +} + +QImage NativeEmbedWidget::windowImage(QRect geom){ + //Need the graphics context of the window + /*xcb_gcontext_t gc = xcb_generate_id(QX11Info::connection()); + xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(QX11Info::connection())).data; + uint32_t values[1]; + values[0] = screen->black_pixel; + xcb_create_gc(QX11Info::connection(), + gc, + this->winId(), + XCB_GC_BACKGROUND, + values ); + xcb_pixmap_t pix = xcb_generate_id(QX11Info::connection()); + xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), pix); + //Now copy this pixmap onto widget + xcb_copy_area(QX11Info::connection(), pix, this->winId(), gc, geom.x(),geom.y(),geom.x(),geom.y(),geom.width(), geom.height()); + xcb_free_pixmap(QX11Info::connection(), pix); + return QImage();*/ + + /*xcb_put_image(QX11Info::connection(), XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc, sz.width(), sz.height(), 0, 0, */ + /*xcb_image_t *img = xcb_image_get(QX11Info::connection(), WIN->id(), geom.x(), geom.y(), geom.width(), geom.height(), 1, XCB_IMAGE_FORMAT_Z_PIXMAP); + if(img==0){ return QImage(); } + QImage image(geom.size(), QImage::Format_ARGB32); + image.loadFromData(img->data, img->size); + return image;*/ + +} + +// ============ +// PUBLIC +// ============ +NativeEmbedWidget::NativeEmbedWidget(QWidget *parent) : QWidget(parent){ + WIN = 0; //nothing embedded yet + this->setStyleSheet("background: transparent;"); //this widget should be fully-transparent to Qt itself (will paint on top of that) +} + +bool NativeEmbedWidget::embedWindow(NativeWindow *window){ + WIN = window; + //PIXBACK = xcb_generate_id(QX11Info::connection()); + xcb_reparent_window(QX11Info::connection(), WIN->id(), this->winId(), 0, 0); + //Now send the embed event to the app + //qDebug() << " - send _XEMBED event"; + /*xcb_client_message_event_t event; + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.window = WIN->id(); + event.type = obj->ATOMS["_XEMBED"]; //_XEMBED + event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; + event.data.data32[1] = 0; //XEMBED_EMBEDDED_NOTIFY + event.data.data32[2] = 0; + event.data.data32[3] = this->winId(); //WID of the container + event.data.data32[4] = 0; + + xcb_send_event(QX11Info::connection(), 0, WIN->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); + */ + //Now setup any redirects and return + //this->SelectInput(WIN->id(), true); //Notify of structure changes + //xcb_composite_redirect_window(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_MANUAL); //XCB_COMPOSITE_REDIRECT_[MANUAL/AUTOMATIC]); + + //xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), PIXBACK); + //Now map the window (will be a transparent child of the container) + //xcb_map_window(QX11Info::connection(), WIN->id()); + //xcb_map_window(QX11Info::connection(), this->winId()); + //Now create/register the damage handler + // -- XCB (Note: The XCB damage registration is completely broken at the moment - 9/15/15, Ken Moore) + // -- Retested 6/29/17 (no change) Ken Moore + //xcb_damage_damage_t dmgID = xcb_generate_id(QX11Info::connection()); //This is a typedef for a 32-bit unsigned integer + //xcb_damage_create(QX11Info::connection(), dmgID, WIN->id(), XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES); + // -- XLib (Note: This is only used because the XCB routine above does not work - needs to be fixed upstream in XCB itself). + Damage dmgID = XDamageCreate(QX11Info::display(), WIN->id(), XDamageReportRawRectangles); + WIN->addDamageID( (uint) dmgID); //save this for later + WIN->addFrameWinID(this->winId()); + connect(WIN, SIGNAL(VisualChanged()), this, SLOT(update()) ); //make sure we repaint the widget on visual change + + registerClientEvents(WIN->id()); + registerClientEvents(this->winId()); + return true; +} + +bool NativeEmbedWidget::detachWindow(){ + xcb_reparent_window(QX11Info::connection(), WIN->id(), QX11Info::appRootWindow(), -1, -1); + WIN = 0; +} + +bool NativeEmbedWidget::isEmbedded(){ + return (WIN!=0); +} + +// ============== +// PROTECTED +// ============== +void NativeEmbedWidget::resizeEvent(QResizeEvent *ev){ + if(WIN!=0){ syncWinSize(ev->size()); } //syncronize the window with the new widget size + QWidget::resizeEvent(ev); +} + +void NativeEmbedWidget::showEvent(QShowEvent *ev){ + if(WIN!=0){ showWindow(); } + QWidget::showEvent(ev); +} + +void NativeEmbedWidget::hideEvent(QHideEvent *ev){ + if(WIN!=0){ hideWindow(); } + QWidget::hideEvent(ev); +} + +void NativeEmbedWidget::paintEvent(QPaintEvent *ev){ + //QWidget::paintEvent(ev); //ensure all the Qt-compositing is done first + if(WIN==0){ QWidget::paintEvent(ev); return; } + //Need to paint the image from the window onto the widget as an overlay + QImage img = windowImage(ev->rect()); + if(!img.isNull()){ + QPainter P(this); + P.drawImage( ev->rect() , img, ev->rect(), Qt::NoOpaqueDetection); //1-to-1 mapping + //Note: Qt::NoOpaqueDetection Speeds up the paint by bypassing the checks to see if there are [semi-]transparent pixels + // Since this is an embedded image - we fully expect there to be transparency most of the time. + }else{ + QWidget::paintEvent(ev); + } +} diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.h b/src-qt5/core/libLumina/NativeEmbedWidget.h new file mode 100644 index 00000000..6919249b --- /dev/null +++ b/src-qt5/core/libLumina/NativeEmbedWidget.h @@ -0,0 +1,47 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is a container object for embedding a native window into a QWidget +// and maintaining a 1-to-1 mapping of sizing and other properties +// while also providing compositing effects between the two windows +//=========================================== +#ifndef _LUMINA_NATIVE_EMBED_WIDGET_H +#define _LUMINA_NATIVE_EMBED_WIDGET_H + +#include "NativeWindow.h" +#include +#include +#include +#include +#include + +class NativeEmbedWidget : public QWidget{ + Q_OBJECT +private: + NativeWindow *WIN; + + //Simplification functions + void syncWinSize(QSize); + void syncWidgetSize(QSize); + void hideWindow(); + void showWindow(); + QImage windowImage(QRect geom); + +public: + NativeEmbedWidget(QWidget *parent); + + bool embedWindow(NativeWindow *window); + bool detachWindow(); + bool isEmbedded(); //status of the embed + +protected: + void resizeEvent(QResizeEvent *ev); + void showEvent(QShowEvent *ev); + void hideEvent(QHideEvent *ev); + void paintEvent(QPaintEvent *ev); +}; + +#endif diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index 819661d5..ff7322f6 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -11,12 +11,10 @@ NativeWindow::NativeWindow(WId id) : QObject(){ winid = id; frameid = 0; dmgID = 0; - //WIN = QWindow::fromWinId(winid); } NativeWindow::~NativeWindow(){ hash.clear(); - //WIN->deleteLater(); //This class only deals with Native windows which were created outside the app - they need to be cleaned up outside the app too } void NativeWindow::addFrameWinID(WId fid){ @@ -43,10 +41,6 @@ unsigned int NativeWindow::damageId(){ return dmgID; } -/*QWindow* NativeWindow::window(){ - return WIN; -}*/ - QVariant NativeWindow::property(NativeWindow::Property prop){ if(hash.contains(prop)){ return hash.value(prop); } else if(prop == NativeWindow::RelatedWindows){ return QVariant::fromValue(relatedTo); } @@ -93,9 +87,11 @@ QRect NativeWindow::geometry(){ QRect geom( hash.value(NativeWindow::GlobalPos).toPoint(), hash.value(NativeWindow::Size).toSize() ); //Now adjust the window geom by the frame margins QList frame = hash.value(NativeWindow::FrameExtents).value< QList >(); //Left,Right,Top,Bottom + qDebug() << "Calculate Geometry:" << geom << frame; if(frame.length()==4){ geom = geom.adjusted( -frame[0], -frame[2], frame[1], frame[3] ); } + qDebug() << " - Total:" << geom; return geom; } // ==== PUBLIC SLOTS === diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index 62bb74b5..5fa194c9 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -95,6 +95,7 @@ signals: void RequestPropertiesChange(WId, QList, QList); void WindowClosed(WId); void WindowNotResponding(WId); //will be sent out if a window does not respond to a ping request + void VisualChanged(); //Action Requests (not automatically emitted - typically used to ask the WM to do something) //Note: "WId" should be the NativeWindow id() diff --git a/src-qt5/core/libLumina/NativeWindow.pri b/src-qt5/core/libLumina/NativeWindow.pri index 013291ff..c2ac0137 100644 --- a/src-qt5/core/libLumina/NativeWindow.pri +++ b/src-qt5/core/libLumina/NativeWindow.pri @@ -6,10 +6,12 @@ LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damag SOURCES *= $${PWD}/NativeWindow.cpp \ $${PWD}/NativeWindowSystem.cpp \ $${PWD}/NativeKeyToQt.cpp \ - $${PWD}/NativeEventFilter.cpp + $${PWD}/NativeEventFilter.cpp \ + $${PWD}/NativeEmbedWidget.cpp HEADERS *= $${PWD}/NativeWindow.h \ $${PWD}/NativeWindowSystem.h \ - $${PWD}/NativeEventFilter.h + $${PWD}/NativeEventFilter.h \ + $${PWD}/NativeEmbedWidget.h INCLUDEPATH *= $${PWD} diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index f208cbf1..bf827a1b 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -254,8 +254,9 @@ void NativeWindowSystem::stop(){ NativeWindow* NativeWindowSystem::findWindow(WId id, bool checkRelated){ //qDebug() << "Find Window:" << id; for(int i=0; iisRelatedTo(id)){ return NWindows[i]; } - else if(!checkRelated && id==NWindows[i]->id()){ return NWindows[i]; } + if(id==NWindows[i]->id() || id==NWindows[i]->frameId() ){ return NWindows[i]; } + //if(checkRelated && NWindows[i]->isRelatedTo(id)){ return NWindows[i]; } + //else if(!checkRelated && id==NWindows[i]->id()){ return NWindows[i]; } } //Check to see if this is a transient for some other window if(checkRelated){ @@ -703,13 +704,13 @@ void NativeWindowSystem::NewTrayWindowDetected(WId id){ void NativeWindowSystem::WindowCloseDetected(WId id){ NativeWindow *win = findWindow(id, false); - //qDebug() << "Got Window Closed" << id << win; + qDebug() << "Got Window Closed" << id << win; //qDebug() << "Old Window List:" << NWindows.length(); if(win!=0){ NWindows.removeAll(win); //RequestReparent(id, QX11Info::appRootWindow(), QPoint(0,0)); win->emit WindowClosed(id); - //qDebug() << "Visible Window Closed!!!"; + qDebug() << "Visible Window Closed!!!"; //win->deleteLater(); }else{ win = findTrayWindow(id); @@ -798,24 +799,8 @@ void NativeWindowSystem::NewMouseRelease(int buttoncode, WId win){ void NativeWindowSystem::CheckDamageID(WId win){ for(int i=0; idamageId() == win || NWindows[i]->id() == win || NWindows[i]->frameId()==win){ + NWindows[i]->emit VisualChanged(); //qDebug() << "Got DAMAGE Event"; - /*NativeWindow *WIN = NWindows[i]; - QSize sz = WIN->property(NativeWindow::Size).toSize(); - //Need the graphics context of the window - xcb_gcontext_t gc = xcb_generate_id(QX11Info::connection()); - xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(QX11Info::connection())).data; - uint32_t values[1]; - values[0] = screen->black_pixel; - xcb_create_gc(QX11Info::connection(), - gc, - WIN->frameId(), - XCB_GC_BACKGROUND, - values ); - xcb_pixmap_t pix = xcb_generate_id(QX11Info::connection()); - xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), pix); - //Now put this pixmap onto the frame window - xcb_copy_area(QX11Info::connection(), pix, WIN->frameId(), gc, 0,0,0,0,sz.width(), sz.height());*/ - /*xcb_put_image(QX11Info::connection(), XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc, sz.width(), sz.height(), 0, 0, */ return; } } diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 92a85291..5ce3d149 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -26,10 +26,10 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ initWindowFrame(); //Hookup the signals/slots connect(WIN, SIGNAL(PropertiesChanged(QList, QList)), this, SLOT(propertiesChanged(QList, QList))); - WIN->addFrameWinID(WinWidget->winId()); - WIN->emit RequestReparent(WIN->id(), WinWidget->winId(), QPoint(0,0)); + WinWidget->embedWindow(WIN); qDebug() << "[NEW WINDOW]" << WIN->id() << WinWidget->winId() << this->winId(); LoadAllProperties(); + //this->show(); } RootSubWindow::~RootSubWindow(){ @@ -147,7 +147,7 @@ void RootSubWindow::initWindowFrame(){ otherB->setMenu(otherM); otherB->setPopupMode(QToolButton::InstantPopup); otherB->setAutoRaise(true); - WinWidget = new QWidget(this); + WinWidget = new NativeEmbedWidget(this); connect(closeB, SIGNAL(clicked()), this, SLOT(triggerClose()) ); connect(maxB, SIGNAL(clicked()), this, SLOT(toggleMaximize()) ); connect(minB, SIGNAL(clicked()), this, SLOT(toggleMinimize()) ); @@ -267,13 +267,13 @@ void RootSubWindow::propertiesChanged(QList props, QList //qDebug() << "RootSubWindow: Property Changed:" << props[i] << vals[i]; switch(props[i]){ case NativeWindow::Visible: - //qDebug() << "Got Visibility Change:" << vals[i]; + qDebug() << "Got Visibility Change:" << vals[i] << this->geometry(); if(vals[i].toBool()){ - WinWidget->setVisible(true); - animResetProp = WIN->geometry(); //show event - might not have the right geom yet + animResetProp = WIN->geometry(); //this->geometry(); anim->setPropertyName("geometry"); - anim->setStartValue( QRect(WIN->geometry().center(), QSize(0,0)) ); - anim->setEndValue(WIN->geometry()); + anim->setStartValue( QRect(animResetProp.toRect().center(), QSize(0,0)) ); + anim->setEndValue(animResetProp); + this->setGeometry( anim->startValue().toRect() ); //ensure the window is the initial geom before it becomes visible anim->start(); this->show(); }else{ @@ -283,7 +283,6 @@ void RootSubWindow::propertiesChanged(QList props, QList anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); anim->start(); QTimer::singleShot(anim->duration(), this, SLOT(hide()) ); - //this->hide(); } break; case NativeWindow::Title: @@ -295,16 +294,16 @@ void RootSubWindow::propertiesChanged(QList props, QList else{ otherB->setIcon(vals[i].value()); } break; case NativeWindow::GlobalPos: - //qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); + qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); this->move( vals[i].toPoint() - (WinWidget->mapToGlobal(QPoint(0,0)) - this->pos()) ); //WIN->geometry().topLeft() ); break; case NativeWindow::Size: - if(WinWidget->size() != vals[i].toSize()){ + //if(WinWidget->size() != vals[i].toSize()){ qDebug() << "Got Widget Size Change:" << vals[i].toSize(); - WinWidget->resize(vals[i].toSize()); + //WinWidget->resize(vals[i].toSize()); this->resize( WIN->geometry().size() ); qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); - } + //} break; case NativeWindow::MinSize: WinWidget->setMinimumSize(vals[i].toSize()); @@ -331,13 +330,13 @@ void RootSubWindow::animFinished(){ if(closing){ this->close(); return;} else if(anim->propertyName()=="geometry"){ if(!animResetProp.isNull()){ - qDebug() << "Animation Finished, Reset Geometry:" << animResetProp; + /*qDebug() << "Animation Finished, Reset Geometry:" << animResetProp; qDebug() << " - Starting Value:" << anim->startValue(); qDebug() << " - Ending Value:" << anim->endValue(); - qDebug() << " - Current Value:" << this->geometry(); + qDebug() << " - Current Value:" << this->geometry();*/ this->setGeometry( animResetProp.toRect() ); - WIN->requestProperty(NativeWindow::Size, WinWidget->size(), true); - WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)),true ); + //WIN->requestProperty(NativeWindow::Size, WinWidget->size(), true); + //WIN->requestProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)),true ); } } animResetProp = QVariant(); //clear the variable diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index bd20291e..cef6f2ff 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -20,7 +20,7 @@ #include #include #include - +#include class RootSubWindow : public QFrame{ Q_OBJECT @@ -41,7 +41,7 @@ private: void setMouseCursor(ModState, bool override = false); //Update the mouse cursor based on state //Native window embed objects NativeWindow *WIN; - QWidget *WinWidget; + NativeEmbedWidget *WinWidget; bool closing; //Title bar objects QBoxLayout *titleBar, *mainLayout; -- cgit From c6cf1c1799aa3e6f095cae0aa579e0ea2971340e Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 13 Jul 2017 15:49:07 -0400 Subject: Start working on getting the frame extents set/used properly. Still off on the geom calculations right now. --- src-qt5/core/libLumina/NativeEmbedWidget.cpp | 2 ++ src-qt5/core/libLumina/NativeWindow.cpp | 2 ++ src-qt5/core/libLumina/RootSubWindow.cpp | 40 ++++++++++++++++++++-------- 3 files changed, 33 insertions(+), 11 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp index fd5939dd..194652f0 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -89,6 +89,7 @@ QImage NativeEmbedWidget::windowImage(QRect geom){ image.loadFromData(img->data, img->size); return image;*/ + return QImage(); } // ============ @@ -145,6 +146,7 @@ bool NativeEmbedWidget::embedWindow(NativeWindow *window){ bool NativeEmbedWidget::detachWindow(){ xcb_reparent_window(QX11Info::connection(), WIN->id(), QX11Info::appRootWindow(), -1, -1); WIN = 0; + return true; } bool NativeEmbedWidget::isEmbedded(){ diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index ff7322f6..94d39cb7 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -6,6 +6,8 @@ //=========================================== #include "NativeWindow.h" +#include + // === PUBLIC === NativeWindow::NativeWindow(WId id) : QObject(){ winid = id; diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 5ce3d149..11bfde29 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -173,6 +173,9 @@ void RootSubWindow::initWindowFrame(){ mainLayout->setSpacing(0); titleBar->setSpacing(1); titleBar->setContentsMargins(0,0,0,0); + this->setFrameRect(QRect(0,0,0,0)); + this->setFrameShape(QFrame::NoFrame); + this->setContentsMargins(0,0,0,0); //Now load the icons for the button LIconCache::instance()->loadIcon(closeB, "window-close"); @@ -186,15 +189,18 @@ void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ for(int i=0; iproperty(list[i]); - if(list[i] == NativeWindow::FrameExtents){ + /*if(list[i] == NativeWindow::FrameExtents){ + qDebug() << "Check Frame Extents:" << vals[i]; if(vals[i].isNull()){ - QList frame; frame << WIN_BORDER << WIN_BORDER << WIN_BORDER+titleLabel->height() << WIN_BORDER; + qDebug() << " - supply default frame extents"; + QList frame; frame << WinWidget->geometry().x() << this->width()-WinWidget->geometry().x()-WinWidget->geometry().width() << WinWidget->y() << this->height() - WinWidget->y() - WinWidget->geometry().height(); vals[i] = QVariant::fromValue< QList >(frame); //use this by default WIN->requestProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(frame)); //make sure these values get saved permanently WIN->setProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(frame)); + qDebug() << " - Default values:" << frame; } - } - qDebug() << "Property:" << list[i] << vals[i]; + }*/ + //qDebug() << "Property:" << list[i] << vals[i]; } propertiesChanged(list, vals); WIN->requestProperty(NativeWindow::Visible, true); @@ -215,6 +221,7 @@ void RootSubWindow::clientClosed(){ void RootSubWindow::LoadAllProperties(){ QList< NativeWindow::Property> list = WIN->allProperties(); + list << NativeWindow::FrameExtents; LoadProperties(list); } @@ -264,10 +271,10 @@ void RootSubWindow::startResizing(){ void RootSubWindow::propertiesChanged(QList props, QList vals){ for(int i=0; igeometry(); + qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); if(vals[i].toBool()){ animResetProp = WIN->geometry(); //this->geometry(); anim->setPropertyName("geometry"); @@ -294,16 +301,21 @@ void RootSubWindow::propertiesChanged(QList props, QList else{ otherB->setIcon(vals[i].value()); } break; case NativeWindow::GlobalPos: - qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); + //qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); this->move( vals[i].toPoint() - (WinWidget->mapToGlobal(QPoint(0,0)) - this->pos()) ); //WIN->geometry().topLeft() ); break; case NativeWindow::Size: - //if(WinWidget->size() != vals[i].toSize()){ - qDebug() << "Got Widget Size Change:" << vals[i].toSize(); - //WinWidget->resize(vals[i].toSize()); + qDebug() << " - SIZE CHANGE"; + if(WIN->property(NativeWindow::FrameExtents).isNull() && (istate() != QPropertyAnimation::Running){ + qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); this->resize( WIN->geometry().size() ); qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); - //} + } break; case NativeWindow::MinSize: WinWidget->setMinimumSize(vals[i].toSize()); @@ -315,6 +327,12 @@ void RootSubWindow::propertiesChanged(QList props, QList //if(vals[i].toBool()){ WinWidget->setFocus(); } break; case NativeWindow::FrameExtents: + qDebug() << " - FRAME CHANGE"; + if(vals[i].isNull()){ + vals[i] = QVariant::fromValue >( QList() << WinWidget->geometry().x() << this->width()-WinWidget->geometry().x()-WinWidget->geometry().width() << WinWidget->y() << this->height() - WinWidget->y() - WinWidget->geometry().height() ); + WIN->setProperty(NativeWindow::FrameExtents, vals[i]); + } + qDebug() << "Setting Frame Extents:" << vals[i].value >(); mainLayout->setContentsMargins( vals[i].value< QList >().at(0),vals[i].value< QList >().at(2) - titleLabel->height(),vals[i].value< QList >().at(1),vals[i].value< QList >().at(3)); break; /*case NativeWindow::WindowFlags: -- cgit From c2ae980ffa96dc8982e5c87f346f2763fcf38d4f Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 18 Jul 2017 14:26:38 -0400 Subject: Get a lot more of the geometry calculations/movements working. Almost ready to start adding additional window property support --- src-qt5/core/libLumina/NativeEmbedWidget.cpp | 3 +- src-qt5/core/libLumina/NativeEmbedWidget.h | 3 + src-qt5/core/libLumina/NativeEventFilter.cpp | 55 +---------- src-qt5/core/libLumina/NativeWindow.h | 7 ++ src-qt5/core/libLumina/NativeWindowSystem.cpp | 43 +++++---- src-qt5/core/libLumina/RootSubWindow.cpp | 126 ++++++++++++++++---------- src-qt5/core/libLumina/RootSubWindow.h | 5 +- 7 files changed, 118 insertions(+), 124 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp index 194652f0..2f3691ae 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -40,7 +40,7 @@ inline void registerClientEvents(WId id){ //Simplification functions for the XCB/XLib interactions void NativeEmbedWidget::syncWinSize(QSize sz){ if(WIN==0){ return; } - qDebug() << "Sync Window Size:" << sz; + //qDebug() << "Sync Window Size:" << sz; xcb_configure_window_value_list_t valList; valList.x = 0; valList.y = 0; @@ -53,6 +53,7 @@ void NativeEmbedWidget::syncWinSize(QSize sz){ } void NativeEmbedWidget::syncWidgetSize(QSize sz){ + //qDebug() << "Sync Widget Size:" << sz; this->resize(sz); } diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.h b/src-qt5/core/libLumina/NativeEmbedWidget.h index 6919249b..55d655f2 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.h +++ b/src-qt5/core/libLumina/NativeEmbedWidget.h @@ -37,6 +37,9 @@ public: bool detachWindow(); bool isEmbedded(); //status of the embed +public slots: + void resyncWindow(){ syncWinSize(this->size()); } + protected: void resizeEvent(QResizeEvent *ev); void showEvent(QShowEvent *ev); diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp index b85965ef..d6c2da50 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/core/libLumina/NativeEventFilter.cpp @@ -76,7 +76,7 @@ inline void ParsePropertyEvent(xcb_property_notify_event_t *ev, NativeEventFilte else if( ev->atom == EWMH._NET_WM_STATE){ prop = NativeWindow::States; } //Send out the signal if necessary if(prop!=NativeWindow::None){ - qDebug() << "Detected Property Change:" << ev->window << prop; + if(DEBUG){ qDebug() << "Detected Property Change:" << ev->window << prop; } obj->emit WindowPropertyChanged(ev->window, prop); }else{ //qDebug() << "Unknown Property Change:" << ev->window << ev->atom; @@ -157,7 +157,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, break; case XCB_MOTION_NOTIFY: //This is a mouse movement event - qDebug() << "Motion Notify Event"; + if(DEBUG){ qDebug() << "Motion Notify Event"; } obj->emit MouseMovement(); break; case XCB_ENTER_NOTIFY: @@ -270,54 +270,3 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, return false; //never stop event handling (this will not impact the X events themselves - just the internal Qt application) } - - -//========= -// PRIVATE -//========= - - -// WINDOW HANDLING FUNCTIONS -/*void EventFilter::SetupNewWindow(xcb_map_request_event_t *ev){ - WId win = ev->window; - - bool ok = obj->XCB->WM_ManageWindow(win, true); - //Quick check if this is a transient window if we could not manage it directly - if(!ok){ - WId tran = obj->XCB->WM_ICCCM_GetTransientFor(win); - if(tran!=win && tran!=0){ - win = tran; - ok = obj->XCB->WM_ManageWindow(win); - } - } - qDebug() << "New Window:" << win << obj->XCB->WM_ICCCM_GetClass(win) << " Managed:" << ok; - obj->XCB->WM_Set_Active_Window(win); - //Determing the requested geometry/location/management within the event, - NativeWindow *nwin = new NativeWindow(win); - QObject::connect(nwin, SIGNAL(RequestClose(WId)), obj, SLOT(TryCloseWindow(WId)) ); - QObject::connect(nwin, SIGNAL(RequestActivate(WId)), obj, SLOT(TryActivateWindow(WId)) ); - windows << nwin; - bool show_now = !Lumina::SS->isLocked(); - if(!show_now){ waitingToShow << win; } //add to the list to get set visible later - //populate the native window settings as they are right now - nwin->setProperty(NativeWindow::Active, true); - nwin->setProperty(NativeWindow::Visible, show_now); - nwin->setProperty(NativeWindow::Workspace, obj->XCB->CurrentWorkspace()); - icccm_size_hints hints = obj->XCB->WM_ICCCM_GetNormalHints(win); - if(!hints.isValid()){ hints = obj->XCB->WM_ICCCM_GetSizeHints(win); } - if(hints.validMinSize()){ nwin->setProperty(NativeWindow::MinSize, QSize(hints.min_width,hints.min_height)); } - if(hints.validMaxSize()){ nwin->setProperty(NativeWindow::MaxSize, QSize(hints.max_width,hints.max_height)); } - if(hints.validBaseSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.base_width,hints.base_height)); } - else if(hints.validSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.width, hints.height)); } - nwin->setProperty(NativeWindow::Icon, obj->XCB->WM_Get_Icon(win)); - QString title = obj->XCB->WM_Get_Name(win); - if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Name(win); } - if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetName(win); } - nwin->setProperty(NativeWindow::Title, title); - title = obj->XCB->WM_Get_Icon_Name(win); - if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Icon_Name(win); } - if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetIconName(win); } - nwin->setProperty(NativeWindow::ShortTitle, title); - - obj->emit WindowCreated(nwin); -}*/ diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index 5fa194c9..47359b7d 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -107,4 +107,11 @@ signals: //void RequestEmbed(WId, QWidget*); //void RequestUnEmbed(WId, QWidget*); }; + +// Declare the enumerations as Qt MetaTypes +Q_DECLARE_METATYPE(NativeWindow::Type); +Q_DECLARE_METATYPE(NativeWindow::Action); +Q_DECLARE_METATYPE(NativeWindow::State); +Q_DECLARE_METATYPE(NativeWindow::Property); + #endif diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index bf827a1b..e0f3fe91 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -260,8 +260,8 @@ NativeWindow* NativeWindowSystem::findWindow(WId id, bool checkRelated){ } //Check to see if this is a transient for some other window if(checkRelated){ - WId tid = obj->getTransientFor(id); - if(tid!=id){ return findWindow(tid, checkRelated); } //call it recursively as needed + //WId tid = obj->getTransientFor(id); + //if(tid!=id){ return findWindow(tid, checkRelated); } //call it recursively as needed //qDebug() << " -- Could not find Window!"; } return 0; @@ -438,7 +438,7 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native } if(props.contains(NativeWindow::FrameExtents)){ //Just assign default values to this - need to automate it later - win->setProperty(NativeWindow::FrameExtents, QVariant::fromValue >(QList() << 5 << 5 << 5+QFontMetrics(QFont()).height() << 5) ); + //win->setProperty(NativeWindow::FrameExtents, QVariant::fromValue >(QList() << 5 << 5 << 5+QFontMetrics(QFont()).height() << 5) ); } if(props.contains(NativeWindow::RelatedWindows)){ WId orig = win->id(); @@ -458,6 +458,11 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native free(attr); } } + if(props.contains(NativeWindow::WinTypes)){ + QList< NativeWindow::Type> types; + types << NativeWindow::T_NORMAL; //make this load appropriately later + win->setProperty(NativeWindow::WinTypes, QVariant::fromValue< QList >(types) ); + } } void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList vals){ @@ -472,29 +477,27 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native if(props.contains(NativeWindow::Icon)){ } - if(props.contains(NativeWindow::Size) ){//|| props.contains(NativeWindow::GlobalPos) ){ + if(props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ xcb_configure_window_value_list_t valList; - valList.x = 0; + valList.x = 0; //Note that this is the relative position - should always be 0,0 relative to the embed widget valList.y = 0; - uint16_t mask = 0; - //if(props.contains(NativeWindow::Size)){ - QSize sz = vals[ props.indexOf(NativeWindow::Size) ] .toSize(); - valList.width = sz.width(); - valList.height = sz.height(); - mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - /*}else{ - valList.width = win->property(NativeWindow::Size).toSize().width(); - valList.height = win->property(NativeWindow::Size).toSize().height(); - }*/ + QSize sz = win->property(NativeWindow::Size).toSize(); + if(props.contains(NativeWindow::Size)){ + sz = vals[ props.indexOf(NativeWindow::Size) ] .toSize(); + } + valList.width = sz.width(); + valList.height = sz.height(); /*if(props.contains(NativeWindow::GlobalPos)){ QPoint pt = vals[ props.indexOf(NativeWindow::GlobalPos) ] .toPoint(); valList.x = pt.x(); - valList.y = pt.y();*/ - mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; - /*}else{ + valList.y = pt.y(); + }else{ valList.x = win->property(NativeWindow::GlobalPos).toPoint().x(); valList.y = win->property(NativeWindow::GlobalPos).toPoint().y(); }*/ + uint16_t mask = 0; + mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; + qDebug() << "Configure window Geometry:" << sz; xcb_configure_window_aux(QX11Info::connection(), win->id(), mask, &valList); } if(props.contains(NativeWindow::Name)){ @@ -725,7 +728,7 @@ void NativeWindowSystem::WindowCloseDetected(WId id){ void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop){ //NOTE: This is triggered by the NativeEventFilter - not by changes to the NativeWindow objects themselves - NativeWindow *win = findWindow(id); + NativeWindow *win = findWindow(id, prop!=NativeWindow::Visible); if(win==0){ win = findTrayWindow(id); } if(win!=0){ UpdateWindowProperties(win, QList() << prop); @@ -733,7 +736,7 @@ void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property pr } void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop, QVariant val){ - NativeWindow *win = findWindow(id); + NativeWindow *win = findWindow(id,prop!=NativeWindow::Visible); if(win==0){ win = findTrayWindow(id); } if(win!=0){ win->setProperty(prop, val); diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 11bfde29..8c7c9b1a 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -22,14 +22,12 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ //Create the QWindow and QWidget containers for the window WIN = win; closing = false; - //WinWidget = QWidget::createWindowContainer( WIN->window(), this); initWindowFrame(); //Hookup the signals/slots connect(WIN, SIGNAL(PropertiesChanged(QList, QList)), this, SLOT(propertiesChanged(QList, QList))); WinWidget->embedWindow(WIN); qDebug() << "[NEW WINDOW]" << WIN->id() << WinWidget->winId() << this->winId(); LoadAllProperties(); - //this->show(); } RootSubWindow::~RootSubWindow(){ @@ -48,10 +46,10 @@ RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset //above the frame itself - need to figure out which quadrant it is in (8-directions) if(pt.y() < WIN_BORDER){ //One of the top options - if(pt.x() < WIN_BORDER){ + if(pt.x() < this->width()/5){ if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()); } //difference from top-left corner return ResizeTopLeft; - }else if(pt.x() > (this->width()-WIN_BORDER)){ + }else if(pt.x() > (this->width()*4.0/5.0)){ if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(pt.y()); } //difference from top-right corner return ResizeTopRight; }else{ @@ -60,10 +58,10 @@ RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset } }else if(pt.y() > (this->height()-WIN_BORDER) ){ //One of the bottom options - if(pt.x() < WIN_BORDER){ + if(pt.x() < this->width()/5){ if(setoffset){ offset.setX(pt.x()); offset.setY(this->height()-pt.y()); } //difference from bottom-left corner return ResizeBottomLeft; - }else if(pt.x() > (this->width()-WIN_BORDER)){ + }else if(pt.x() > (this->width()*4.0/5.0)){ if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(this->height()-pt.y()); } //difference from bottom-right corner return ResizeBottomRight; }else{ @@ -131,8 +129,13 @@ void RootSubWindow::setMouseCursor(ModState state, bool override){ void RootSubWindow::initWindowFrame(){ //qDebug() << "Create RootSubWindow Frame"; + this->setContentsMargins(0,0,0,0); mainLayout = new QVBoxLayout(this); - titleBar = new QHBoxLayout(); + mainLayout->setContentsMargins(0,0,0,0); + titleBar = new QWidget(this); + titleBar->setContentsMargins(0,0,0,0); + titleBarL = new QHBoxLayout(titleBar); + titleBarL->setContentsMargins(0,0,0,0); closeB = new QToolButton(this); maxB = new QToolButton(this); minB = new QToolButton(this); @@ -152,13 +155,14 @@ void RootSubWindow::initWindowFrame(){ connect(maxB, SIGNAL(clicked()), this, SLOT(toggleMaximize()) ); connect(minB, SIGNAL(clicked()), this, SLOT(toggleMinimize()) ); //Now assemble the frame layout based on the current settings - titleBar->addWidget(otherB); - titleBar->addWidget(titleLabel); - titleBar->addWidget(minB); - titleBar->addWidget(maxB); - titleBar->addWidget(closeB); + titleBarL->addWidget(otherB); + titleBarL->addWidget(titleLabel); + titleBarL->addWidget(minB); + titleBarL->addWidget(maxB); + titleBarL->addWidget(closeB); WinWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - mainLayout->addLayout(titleBar); + titleBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + mainLayout->addWidget(titleBar); mainLayout->addWidget(WinWidget); //Now all the stylesheet options this->setObjectName("WindowFrame"); @@ -167,15 +171,20 @@ void RootSubWindow::initWindowFrame(){ maxB->setObjectName("Button_Maximize"); otherM->setObjectName("Menu_Actions"); titleLabel->setObjectName("Label_Title"); - this->setStyleSheet("QWidget#WindowFrame{background-color: rgba(0,0,0,125);} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border: 1px solid transparent; border-radius: 3px; } QToolButton::hover{background-color: rgba(255,255,255,150); } QToolButton::pressed{ background-color: white; } QToolButton::menu-arrow{ image: none; }"); + this->setStyleSheet("QFrame#WindowFrame{background-color: rgba(0,0,0,125)} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border: 1px solid transparent; border-radius: 3px; } QToolButton::hover{background-color: rgba(255,255,255,150); } QToolButton::pressed{ background-color: white; } QToolButton::menu-arrow{ image: none; }"); //And adjust the margins - mainLayout->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); //default border mainLayout->setSpacing(0); - titleBar->setSpacing(1); - titleBar->setContentsMargins(0,0,0,0); + titleBarL->setSpacing(1); + this->setFrameStyle(QFrame::NoFrame); + this->setLineWidth(0); + this->setMidLineWidth(0); this->setFrameRect(QRect(0,0,0,0)); - this->setFrameShape(QFrame::NoFrame); - this->setContentsMargins(0,0,0,0); + + //Setup the timer object to syncronize info + moveTimer = new QTimer(this); + moveTimer->setSingleShot(true); + moveTimer->setInterval(100); //1/10 second + connect(moveTimer, SIGNAL(timeout()), WinWidget, SLOT(resyncWindow()) ); //Now load the icons for the button LIconCache::instance()->loadIcon(closeB, "window-close"); @@ -184,26 +193,34 @@ void RootSubWindow::initWindowFrame(){ LIconCache::instance()->loadIcon(otherB, "list"); } +void RootSubWindow::enableFrame(bool on){ + //Make the individual frame elements visible as needed + if(on){ this->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); }//default border + else{ this->setContentsMargins(0, 0, 0, 0); } + titleBar->setVisible(on); + //And now calculate/save the frame extents + QList extents; extents << 0 << 0 << 0 << 0; //left, right, top, bottom + if(on){ + extents[0] = WIN_BORDER; + extents[1] = WIN_BORDER; + extents[2] = WIN_BORDER + titleBar->height(); + extents[3] = WIN_BORDER; + } + qDebug() << "SET FRAME EXTENTS:" << extents; + WIN->requestProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(extents) ); //save on raw window itself + WIN->setProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(extents) ); //save to structure now +} + void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ QList vals; + //Always ensure that visibility changes are evaluated last + bool addvisible = false; for(int i=0; iproperty(list[i]); - /*if(list[i] == NativeWindow::FrameExtents){ - qDebug() << "Check Frame Extents:" << vals[i]; - if(vals[i].isNull()){ - qDebug() << " - supply default frame extents"; - QList frame; frame << WinWidget->geometry().x() << this->width()-WinWidget->geometry().x()-WinWidget->geometry().width() << WinWidget->y() << this->height() - WinWidget->y() - WinWidget->geometry().height(); - vals[i] = QVariant::fromValue< QList >(frame); //use this by default - WIN->requestProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(frame)); //make sure these values get saved permanently - WIN->setProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(frame)); - qDebug() << " - Default values:" << frame; - } - }*/ - //qDebug() << "Property:" << list[i] << vals[i]; } + //if(addvisible){ list << NativeWindow::Visible; vals << WIN->property(NativeWindow::Visible); } propertiesChanged(list, vals); - WIN->requestProperty(NativeWindow::Visible, true); } // === PUBLIC SLOTS === @@ -220,9 +237,12 @@ void RootSubWindow::clientClosed(){ } void RootSubWindow::LoadAllProperties(){ - QList< NativeWindow::Property> list = WIN->allProperties(); - list << NativeWindow::FrameExtents; + QList< NativeWindow::Property> list; + list << NativeWindow::WinTypes << NativeWindow::WinActions << NativeWindow::States + << NativeWindow::MinSize << NativeWindow::MaxSize << NativeWindow::Title << NativeWindow::ShortTitle + << NativeWindow::Icon << NativeWindow::Size << NativeWindow::GlobalPos << NativeWindow::Visible << NativeWindow::Active; LoadProperties(list); + WIN->requestProperty(NativeWindow::Visible, true); } //Button Actions - public so they can be tied to key shortcuts and stuff as well @@ -271,10 +291,10 @@ void RootSubWindow::startResizing(){ void RootSubWindow::propertiesChanged(QList props, QList vals){ for(int i=0; igeometry() << WIN->geometry(); + //qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); if(vals[i].toBool()){ animResetProp = WIN->geometry(); //this->geometry(); anim->setPropertyName("geometry"); @@ -312,9 +332,12 @@ void RootSubWindow::propertiesChanged(QList props, QList vals << vals.takeAt(i); i--; }else if(anim->state() != QPropertyAnimation::Running){ - qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); - this->resize( WIN->geometry().size() ); - qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); + if(vals[i].toSize() != WinWidget->size()){ + qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); + WinWidget->resize(vals[i].toSize()); + this->resize( WIN->geometry().size() ); + qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); + } } break; case NativeWindow::MinSize: @@ -326,7 +349,7 @@ void RootSubWindow::propertiesChanged(QList props, QList case NativeWindow::Active: //if(vals[i].toBool()){ WinWidget->setFocus(); } break; - case NativeWindow::FrameExtents: + /*case NativeWindow::FrameExtents: qDebug() << " - FRAME CHANGE"; if(vals[i].isNull()){ vals[i] = QVariant::fromValue >( QList() << WinWidget->geometry().x() << this->width()-WinWidget->geometry().x()-WinWidget->geometry().width() << WinWidget->y() << this->height() - WinWidget->y() - WinWidget->geometry().height() ); @@ -334,10 +357,10 @@ void RootSubWindow::propertiesChanged(QList props, QList } qDebug() << "Setting Frame Extents:" << vals[i].value >(); mainLayout->setContentsMargins( vals[i].value< QList >().at(0),vals[i].value< QList >().at(2) - titleLabel->height(),vals[i].value< QList >().at(1),vals[i].value< QList >().at(3)); - break; - /*case NativeWindow::WindowFlags: - this->setWindowFlags( val.value< Qt::WindowFlags >() ); break;*/ + case NativeWindow::WinTypes: + enableFrame(vals[i].value< QList >().contains(NativeWindow::T_NORMAL) ); + break; default: qDebug() << "Window Property Unused:" << props[i] << vals[i]; } @@ -473,7 +496,7 @@ void RootSubWindow::mouseReleaseEvent(QMouseEvent *ev){ activeState = Normal; QApplication::restoreOverrideCursor(); setMouseCursor( getStateAtPoint(ev->pos()) ); - if(QWidget::mouseGrabber() == this){ this->releaseMouse(); } + if(QFrame::mouseGrabber() == this){ this->releaseMouse(); } } void RootSubWindow::leaveEvent(QEvent *ev){ @@ -490,9 +513,9 @@ void RootSubWindow::leaveEvent(QEvent *ev){ void RootSubWindow::resizeEvent(QResizeEvent *ev){ //qDebug() << "Got Resize Event:" << ev->size(); - if(WinWidget->size() != WIN->property(NativeWindow::Size).toSize() && anim->state()!=QAbstractAnimation::Running){ + /*if(WinWidget->size() != WIN->property(NativeWindow::Size).toSize() && anim->state()!=QAbstractAnimation::Running){ WIN->requestProperty(NativeWindow::Size, WinWidget->size()); - } + }*/ QFrame::resizeEvent(ev); } @@ -502,7 +525,12 @@ void RootSubWindow::resizeEvent(QResizeEvent *ev){ }*/ void RootSubWindow::moveEvent(QMoveEvent *ev){ - //qDebug() << "Got Move Event:" << ev->pos() << WinWidget->mapToGlobal(QPoint(0,0)); - if(!closing && anim->state()!=QAbstractAnimation::Running){ WIN->setProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)) ); } + qDebug() << "Got Move Event:" << ev->pos() << WinWidget->geometry(); QFrame::moveEvent(ev); + if(!closing && anim->state()!=QAbstractAnimation::Running){ + moveTimer->start(); + //WinWidget->resyncWindow(); + //WIN->requestProperty(NativeWindow::GlobalPos, ev->pos() ); + } + } diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index cef6f2ff..804dcc9d 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -44,14 +44,17 @@ private: NativeEmbedWidget *WinWidget; bool closing; //Title bar objects - QBoxLayout *titleBar, *mainLayout; + QBoxLayout *titleBarL, *mainLayout; QToolButton *closeB, *maxB, *minB, *otherB; QLabel *titleLabel; QMenu *otherM; //menu of other actions + QWidget *titleBar; //Other random objects (animations,etc) QPropertyAnimation *anim; QVariant animResetProp; + QTimer *moveTimer; void initWindowFrame(); + void enableFrame(bool); void LoadProperties( QList< NativeWindow::Property> list); -- cgit From e4ec849945d035909187149a2b36e5b5d3ba4c27 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 18 Jul 2017 14:41:24 -0400 Subject: Add some better edge-detection systems for the window borders on the left/right sides. --- src-qt5/core/libLumina/RootSubWindow.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 8c7c9b1a..d4c0ceeb 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -68,17 +68,32 @@ RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset if(setoffset){ offset.setX(0); offset.setY(this->height() - pt.y()); } //difference from bottom edge (X does not matter) return ResizeBottom; } - }else{ - //One of the side options - if(pt.x() < WIN_BORDER){ + }else if(pt.x() < WIN_BORDER){ + //Left side options + if(pt.y() < this->height()/5){ + if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()); } //difference from top-left corner + return ResizeTopLeft; + }else if(pt.y() > (this->height()*4.0/5.0)){ + if(setoffset){ offset.setX(pt.x()); offset.setY(this->height()-pt.y()); } //difference from bottom-left corner + return ResizeBottomLeft; + }else{ if(setoffset){ offset.setX(pt.x()); offset.setY(0); } //difference from left edge (Y does not matter) return ResizeLeft; - }else if(pt.x() > (this->width()-WIN_BORDER) ){ + } + }else if(pt.x() > (this->width()-WIN_BORDER) ){ + //Right side options + if(pt.y() < this->height()/5){ + if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(pt.y()); } //difference from top-right corner + return ResizeTopRight; + }else if(pt.y() > (this->height()*4.0/5.0)){ + if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(this->height()-pt.y()); } //difference from bottom-right corner + return ResizeBottomRight; + }else{ if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(0); } //difference from right edge (Y does not matter) return ResizeRight; - }else{ - return Normal; } + }else{ + return Normal; } } return Normal; @@ -525,7 +540,7 @@ void RootSubWindow::resizeEvent(QResizeEvent *ev){ }*/ void RootSubWindow::moveEvent(QMoveEvent *ev){ - qDebug() << "Got Move Event:" << ev->pos() << WinWidget->geometry(); + //qDebug() << "Got Move Event:" << ev->pos() << WinWidget->geometry(); QFrame::moveEvent(ev); if(!closing && anim->state()!=QAbstractAnimation::Running){ moveTimer->start(); -- cgit From 6331ded27b98c14295f7e7367b321e97366ad897 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 18 Jul 2017 18:56:59 -0400 Subject: Get the resize/movement functionality all finished. --- src-qt5/core/libLumina/RootSubWindow.cpp | 34 +++++++++++++++++++------------- src-qt5/core/libLumina/RootSubWindow.h | 2 ++ 2 files changed, 22 insertions(+), 14 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index d4c0ceeb..a759dc09 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -311,7 +311,8 @@ void RootSubWindow::propertiesChanged(QList props, QList case NativeWindow::Visible: //qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); if(vals[i].toBool()){ - animResetProp = WIN->geometry(); //this->geometry(); + if(lastGeom.isNull()){ animResetProp = WIN->geometry(); } + else{ animResetProp = lastGeom; } anim->setPropertyName("geometry"); anim->setStartValue( QRect(animResetProp.toRect().center(), QSize(0,0)) ); anim->setEndValue(animResetProp); @@ -320,6 +321,7 @@ void RootSubWindow::propertiesChanged(QList props, QList this->show(); }else{ animResetProp = this->geometry(); //hide event - should already be the right geom + lastGeom = this->geometry(); anim->setPropertyName("geometry"); anim->setStartValue(this->geometry()); anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); @@ -337,21 +339,25 @@ void RootSubWindow::propertiesChanged(QList props, QList break; case NativeWindow::GlobalPos: //qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); - this->move( vals[i].toPoint() - (WinWidget->mapToGlobal(QPoint(0,0)) - this->pos()) ); //WIN->geometry().topLeft() ); + if(activeState == RootSubWindow::Normal){ + this->move( vals[i].toPoint() - (WinWidget->mapToGlobal(QPoint(0,0)) - this->pos()) ); //WIN->geometry().topLeft() ); + } break; case NativeWindow::Size: - qDebug() << " - SIZE CHANGE"; - if(WIN->property(NativeWindow::FrameExtents).isNull() && (istate() != QPropertyAnimation::Running){ - if(vals[i].toSize() != WinWidget->size()){ - qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); - WinWidget->resize(vals[i].toSize()); - this->resize( WIN->geometry().size() ); - qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); + //qDebug() << " - SIZE CHANGE"; + if(activeState == RootSubWindow::Normal){ + if(WIN->property(NativeWindow::FrameExtents).isNull() && (istate() != QPropertyAnimation::Running){ + if(vals[i].toSize() != WinWidget->size()){ + //qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); + WinWidget->resize(vals[i].toSize()); + this->resize( WIN->geometry().size() ); + //qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); + } } } break; diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index 804dcc9d..9c86e2bf 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -53,6 +53,8 @@ private: QPropertyAnimation *anim; QVariant animResetProp; QTimer *moveTimer; + QRect lastGeom; //frame coordinates + void initWindowFrame(); void enableFrame(bool); -- cgit From f998c3ad846ac75776cb2cf5207968cfe90dc25d Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 18 Jul 2017 19:04:05 -0400 Subject: Clean up a bit of debugging and such --- src-qt5/core/libLumina/RootSubWindow.cpp | 64 ++++++++------------------------ src-qt5/core/libLumina/RootSubWindow.h | 3 -- 2 files changed, 16 insertions(+), 51 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index a759dc09..35b2d7cd 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -26,7 +26,7 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ //Hookup the signals/slots connect(WIN, SIGNAL(PropertiesChanged(QList, QList)), this, SLOT(propertiesChanged(QList, QList))); WinWidget->embedWindow(WIN); - qDebug() << "[NEW WINDOW]" << WIN->id() << WinWidget->winId() << this->winId(); + //qDebug() << "[NEW WINDOW]" << WIN->id() << WinWidget->winId() << this->winId(); LoadAllProperties(); } @@ -221,7 +221,7 @@ void RootSubWindow::enableFrame(bool on){ extents[2] = WIN_BORDER + titleBar->height(); extents[3] = WIN_BORDER; } - qDebug() << "SET FRAME EXTENTS:" << extents; + //qDebug() << "SET FRAME EXTENTS:" << extents; WIN->requestProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(extents) ); //save on raw window itself WIN->setProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(extents) ); //save to structure now } @@ -242,12 +242,6 @@ void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ void RootSubWindow::clientClosed(){ //qDebug() << "Client Closed"; closing = true; - /*animResetProp = QRect(WIN->property(NativeWindow::GlobalPos).toPoint(), WIN->property(NativeWindow::Size).toSize()); - anim->setPropertyName("geometry"); - anim->setStartValue(this->geometry()); - anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); - anim->start(); - QTimer::singleShot(anim->duration(), this, SLOT(close()) );*/ if(anim->state()!=QAbstractAnimation::Running){ this->close(); } } @@ -311,8 +305,7 @@ void RootSubWindow::propertiesChanged(QList props, QList case NativeWindow::Visible: //qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); if(vals[i].toBool()){ - if(lastGeom.isNull()){ animResetProp = WIN->geometry(); } - else{ animResetProp = lastGeom; } + animResetProp = WIN->geometry(); //this->geometry(); anim->setPropertyName("geometry"); anim->setStartValue( QRect(animResetProp.toRect().center(), QSize(0,0)) ); anim->setEndValue(animResetProp); @@ -321,7 +314,6 @@ void RootSubWindow::propertiesChanged(QList props, QList this->show(); }else{ animResetProp = this->geometry(); //hide event - should already be the right geom - lastGeom = this->geometry(); anim->setPropertyName("geometry"); anim->setStartValue(this->geometry()); anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); @@ -339,25 +331,21 @@ void RootSubWindow::propertiesChanged(QList props, QList break; case NativeWindow::GlobalPos: //qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); - if(activeState == RootSubWindow::Normal){ - this->move( vals[i].toPoint() - (WinWidget->mapToGlobal(QPoint(0,0)) - this->pos()) ); //WIN->geometry().topLeft() ); - } + this->move( vals[i].toPoint() - (WinWidget->mapToGlobal(QPoint(0,0)) - this->pos()) ); //WIN->geometry().topLeft() ); break; case NativeWindow::Size: - //qDebug() << " - SIZE CHANGE"; - if(activeState == RootSubWindow::Normal){ - if(WIN->property(NativeWindow::FrameExtents).isNull() && (istate() != QPropertyAnimation::Running){ - if(vals[i].toSize() != WinWidget->size()){ - //qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); - WinWidget->resize(vals[i].toSize()); - this->resize( WIN->geometry().size() ); - //qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); - } + qDebug() << " - SIZE CHANGE"; + if(WIN->property(NativeWindow::FrameExtents).isNull() && (istate() != QPropertyAnimation::Running){ + if(vals[i].toSize() != WinWidget->size()){ + qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); + WinWidget->resize(vals[i].toSize()); + this->resize( WIN->geometry().size() ); + qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); } } break; @@ -397,8 +385,6 @@ void RootSubWindow::animFinished(){ qDebug() << " - Ending Value:" << anim->endValue(); qDebug() << " - Current Value:" << this->geometry();*/ this->setGeometry( animResetProp.toRect() ); - //WIN->requestProperty(NativeWindow::Size, WinWidget->size(), true); - //WIN->requestProperty(NativeWindow::GlobalPos, WinWidget->mapToGlobal(QPoint(0,0)),true ); } } animResetProp = QVariant(); //clear the variable @@ -527,24 +513,6 @@ void RootSubWindow::leaveEvent(QEvent *ev){ } } -/*void RootSubWindow::hideEvent(QHideEvent *ev){ - WIN->requestProperty(NativeWindow::Visible, false); - QFrame::hideEvent(ev); -}*/ - -void RootSubWindow::resizeEvent(QResizeEvent *ev){ - //qDebug() << "Got Resize Event:" << ev->size(); - /*if(WinWidget->size() != WIN->property(NativeWindow::Size).toSize() && anim->state()!=QAbstractAnimation::Running){ - WIN->requestProperty(NativeWindow::Size, WinWidget->size()); - }*/ - QFrame::resizeEvent(ev); -} - -/*void RootSubWindow::showEvent(QShowEvent *ev){ - WIN->requestProperty(NativeWindow::Visible, true); - QFrame::showEvent(ev); -}*/ - void RootSubWindow::moveEvent(QMoveEvent *ev){ //qDebug() << "Got Move Event:" << ev->pos() << WinWidget->geometry(); QFrame::moveEvent(ev); diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index 9c86e2bf..de6aba89 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -85,9 +85,6 @@ protected: void mouseReleaseEvent(QMouseEvent*); void leaveEvent(QEvent *ev); - //void hideEvent(QHideEvent *ev); - void resizeEvent(QResizeEvent *ev); - //void showEvent(QShowEvent *ev); void moveEvent(QMoveEvent *ev); -- cgit From 1de88d56aa6eafc7ee347a607ae855526e5edad5 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 18 Jul 2017 20:47:10 -0400 Subject: Finish up the on-move window notification so that sub-windows (menus and such) are painted in the proper place. --- src-qt5/core/libLumina/NativeEmbedWidget.cpp | 20 ++++++++++++++++++++ src-qt5/core/libLumina/NativeEmbedWidget.h | 2 +- src-qt5/core/libLumina/RootSubWindow.cpp | 20 +++++++++++++------- 3 files changed, 34 insertions(+), 8 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp index 2f3691ae..b998c4b5 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -154,6 +154,26 @@ bool NativeEmbedWidget::isEmbedded(){ return (WIN!=0); } +// ============== +// PUBLIC SLOTS +// ============== +void NativeEmbedWidget::resyncWindow(){ + QSize sz = this->size(); + if(WIN==0){ return; } + //qDebug() << "Sync Window Size:" << sz; + xcb_configure_window_value_list_t valList; + valList.x = -1; + valList.y = 0; + valList.width = sz.width(); + valList.height = sz.height(); + uint16_t mask = 0; + mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; + xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); + valList.x = 0; + xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); +} + // ============== // PROTECTED // ============== diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.h b/src-qt5/core/libLumina/NativeEmbedWidget.h index 55d655f2..07e1c4dd 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.h +++ b/src-qt5/core/libLumina/NativeEmbedWidget.h @@ -38,7 +38,7 @@ public: bool isEmbedded(); //status of the embed public slots: - void resyncWindow(){ syncWinSize(this->size()); } + void resyncWindow(); protected: void resizeEvent(QResizeEvent *ev); diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 35b2d7cd..1059871a 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -27,6 +27,7 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ connect(WIN, SIGNAL(PropertiesChanged(QList, QList)), this, SLOT(propertiesChanged(QList, QList))); WinWidget->embedWindow(WIN); //qDebug() << "[NEW WINDOW]" << WIN->id() << WinWidget->winId() << this->winId(); + activeState = RootSubWindow::Normal; LoadAllProperties(); } @@ -96,6 +97,7 @@ RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset return Normal; } } + //if it gets this far just return normal return Normal; } @@ -305,7 +307,8 @@ void RootSubWindow::propertiesChanged(QList props, QList case NativeWindow::Visible: //qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); if(vals[i].toBool()){ - animResetProp = WIN->geometry(); //this->geometry(); + if(lastGeom.isNull()){ animResetProp = this->geometry(); } + else{ animResetProp = lastGeom; } anim->setPropertyName("geometry"); anim->setStartValue( QRect(animResetProp.toRect().center(), QSize(0,0)) ); anim->setEndValue(animResetProp); @@ -314,6 +317,7 @@ void RootSubWindow::propertiesChanged(QList props, QList this->show(); }else{ animResetProp = this->geometry(); //hide event - should already be the right geom + lastGeom = this->geometry(); anim->setPropertyName("geometry"); anim->setStartValue(this->geometry()); anim->setEndValue( QRect(this->geometry().center(), QSize(0,0) ) ); @@ -331,21 +335,23 @@ void RootSubWindow::propertiesChanged(QList props, QList break; case NativeWindow::GlobalPos: //qDebug() << "Got Global Pos:" << this->pos() << WinWidget->mapToGlobal(QPoint(0,0)) << WIN->geometry().topLeft() << vals[i].toPoint(); - this->move( vals[i].toPoint() - (WinWidget->mapToGlobal(QPoint(0,0)) - this->pos()) ); //WIN->geometry().topLeft() ); + if(activeState == RootSubWindow::Normal){ + this->move( WIN->geometry().topLeft() ); + } break; case NativeWindow::Size: - qDebug() << " - SIZE CHANGE"; + //qDebug() << " - SIZE CHANGE"; if(WIN->property(NativeWindow::FrameExtents).isNull() && (istate() != QPropertyAnimation::Running){ - if(vals[i].toSize() != WinWidget->size()){ - qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); + }else if(anim->state() != QPropertyAnimation::Running ){ + if(vals[i].toSize() != WinWidget->size() && activeState==Normal){ + //qDebug() << "Got Widget Size Change:" << vals[i].toSize() << WinWidget->size(); WinWidget->resize(vals[i].toSize()); this->resize( WIN->geometry().size() ); - qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); + //qDebug() << " - Size after change:" << WinWidget->size() << this->size() << WIN->geometry(); } } break; -- cgit From 58454338dfe1a7d259e8ff7605cef260f31cfc19 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 18 Jul 2017 21:47:06 -0400 Subject: Get the in-window compositing *nearly* working. Still a bit unstable right now (closing a window crashes X), but the compositing redirection/painting seems to be working somewhat. --- src-qt5/core/libLumina/NativeEmbedWidget.cpp | 41 ++++++++++------------------ 1 file changed, 14 insertions(+), 27 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp index b998c4b5..77a7e378 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -16,7 +16,7 @@ #include #include -//xcb_pixmap_t PIXBACK; //backend pixmap that compositing redirects to +//xcb_image_t *ximg; #define NORMAL_WIN_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ XCB_EVENT_MASK_BUTTON_RELEASE | \ @@ -66,31 +66,19 @@ void NativeEmbedWidget::showWindow(){ } QImage NativeEmbedWidget::windowImage(QRect geom){ - //Need the graphics context of the window - /*xcb_gcontext_t gc = xcb_generate_id(QX11Info::connection()); - xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(QX11Info::connection())).data; - uint32_t values[1]; - values[0] = screen->black_pixel; - xcb_create_gc(QX11Info::connection(), - gc, - this->winId(), - XCB_GC_BACKGROUND, - values ); + //Pull the XCB pixmap out of the compositing layer xcb_pixmap_t pix = xcb_generate_id(QX11Info::connection()); xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), pix); - //Now copy this pixmap onto widget - xcb_copy_area(QX11Info::connection(), pix, this->winId(), gc, geom.x(),geom.y(),geom.x(),geom.y(),geom.width(), geom.height()); + //Convert this pixmap into a QImage + //if(ximg!=0){ xcb_image_destroy(ximg); } //clean up previous image data + xcb_image_t *ximg = xcb_image_get(QX11Info::connection(), pix, geom.x(), geom.y(), geom.width(), geom.height(), ~0, XCB_IMAGE_FORMAT_Z_PIXMAP); + QImage img(ximg->data, ximg->width, ximg->height, ximg->stride, QImage::Format_ARGB32_Premultiplied); + img = img.copy(); //detach this image from the XCB data structures + //Cleanup the XCB data structures xcb_free_pixmap(QX11Info::connection(), pix); - return QImage();*/ + xcb_image_destroy(ximg); + return img.copy(); - /*xcb_put_image(QX11Info::connection(), XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc, sz.width(), sz.height(), 0, 0, */ - /*xcb_image_t *img = xcb_image_get(QX11Info::connection(), WIN->id(), geom.x(), geom.y(), geom.width(), geom.height(), 1, XCB_IMAGE_FORMAT_Z_PIXMAP); - if(img==0){ return QImage(); } - QImage image(geom.size(), QImage::Format_ARGB32); - image.loadFromData(img->data, img->size); - return image;*/ - - return QImage(); } // ============ @@ -121,13 +109,10 @@ bool NativeEmbedWidget::embedWindow(NativeWindow *window){ xcb_send_event(QX11Info::connection(), 0, WIN->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); */ //Now setup any redirects and return - //this->SelectInput(WIN->id(), true); //Notify of structure changes - //xcb_composite_redirect_window(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_MANUAL); //XCB_COMPOSITE_REDIRECT_[MANUAL/AUTOMATIC]); + xcb_composite_redirect_window(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_MANUAL); //XCB_COMPOSITE_REDIRECT_[MANUAL/AUTOMATIC]); //xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), PIXBACK); - //Now map the window (will be a transparent child of the container) - //xcb_map_window(QX11Info::connection(), WIN->id()); - //xcb_map_window(QX11Info::connection(), this->winId()); + //Now create/register the damage handler // -- XCB (Note: The XCB damage registration is completely broken at the moment - 9/15/15, Ken Moore) // -- Retested 6/29/17 (no change) Ken Moore @@ -200,9 +185,11 @@ void NativeEmbedWidget::paintEvent(QPaintEvent *ev){ if(!img.isNull()){ QPainter P(this); P.drawImage( ev->rect() , img, ev->rect(), Qt::NoOpaqueDetection); //1-to-1 mapping + qDebug() << "Painted Rect:" << ev->rect() << this->geometry(); //Note: Qt::NoOpaqueDetection Speeds up the paint by bypassing the checks to see if there are [semi-]transparent pixels // Since this is an embedded image - we fully expect there to be transparency most of the time. }else{ QWidget::paintEvent(ev); } + qDebug() << "Done Painting"; } -- cgit From 1ffb954b353346533f4f71ffb41d5d5b65cb333d Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 19 Jul 2017 09:04:15 -0400 Subject: Get compositing completely working. This broke the move-update patch a bit - need to find another way to poke the window after it gets moved. --- src-qt5/core/libLumina/NativeEmbedWidget.cpp | 41 ++++++++++++++++------------ 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp index 77a7e378..333fe6e2 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -16,8 +16,6 @@ #include #include -//xcb_image_t *ximg; - #define NORMAL_WIN_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ XCB_EVENT_MASK_BUTTON_RELEASE | \ XCB_EVENT_MASK_POINTER_MOTION | \ @@ -50,6 +48,7 @@ void NativeEmbedWidget::syncWinSize(QSize sz){ mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); + //xcb_flush(QX11Info::connection()); } void NativeEmbedWidget::syncWidgetSize(QSize sz){ @@ -69,15 +68,19 @@ QImage NativeEmbedWidget::windowImage(QRect geom){ //Pull the XCB pixmap out of the compositing layer xcb_pixmap_t pix = xcb_generate_id(QX11Info::connection()); xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), pix); + if(pix==0){ return QImage(); } + //Convert this pixmap into a QImage - //if(ximg!=0){ xcb_image_destroy(ximg); } //clean up previous image data xcb_image_t *ximg = xcb_image_get(QX11Info::connection(), pix, geom.x(), geom.y(), geom.width(), geom.height(), ~0, XCB_IMAGE_FORMAT_Z_PIXMAP); + if(ximg == 0){ return QImage(); } QImage img(ximg->data, ximg->width, ximg->height, ximg->stride, QImage::Format_ARGB32_Premultiplied); img = img.copy(); //detach this image from the XCB data structures + xcb_image_destroy(ximg); + //Cleanup the XCB data structures xcb_free_pixmap(QX11Info::connection(), pix); - xcb_image_destroy(ximg); - return img.copy(); + + return img; } @@ -110,8 +113,7 @@ bool NativeEmbedWidget::embedWindow(NativeWindow *window){ */ //Now setup any redirects and return xcb_composite_redirect_window(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_MANUAL); //XCB_COMPOSITE_REDIRECT_[MANUAL/AUTOMATIC]); - - //xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), PIXBACK); + xcb_composite_redirect_subwindows(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_MANUAL); //XCB_COMPOSITE_REDIRECT_[MANUAL/AUTOMATIC]); //Now create/register the damage handler // -- XCB (Note: The XCB damage registration is completely broken at the moment - 9/15/15, Ken Moore) @@ -120,6 +122,7 @@ bool NativeEmbedWidget::embedWindow(NativeWindow *window){ //xcb_damage_create(QX11Info::connection(), dmgID, WIN->id(), XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES); // -- XLib (Note: This is only used because the XCB routine above does not work - needs to be fixed upstream in XCB itself). Damage dmgID = XDamageCreate(QX11Info::display(), WIN->id(), XDamageReportRawRectangles); + WIN->addDamageID( (uint) dmgID); //save this for later WIN->addFrameWinID(this->winId()); connect(WIN, SIGNAL(VisualChanged()), this, SLOT(update()) ); //make sure we repaint the widget on visual change @@ -145,17 +148,21 @@ bool NativeEmbedWidget::isEmbedded(){ void NativeEmbedWidget::resyncWindow(){ QSize sz = this->size(); if(WIN==0){ return; } + //Just jitter the x origin of the window 1 pixel so the window knows to re-check it's global position + // before creating child windows (menu's in particular). + //qDebug() << "Sync Window Size:" << sz; xcb_configure_window_value_list_t valList; - valList.x = -1; + valList.x = 0; valList.y = 0; valList.width = sz.width(); - valList.height = sz.height(); + //valList.height = sz.height()-1; uint16_t mask = 0; mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; - xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); - valList.x = 0; + //xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); + valList.height = sz.height(); + //xcb_flush(QX11Info::connection()); xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); } @@ -181,15 +188,15 @@ void NativeEmbedWidget::paintEvent(QPaintEvent *ev){ //QWidget::paintEvent(ev); //ensure all the Qt-compositing is done first if(WIN==0){ QWidget::paintEvent(ev); return; } //Need to paint the image from the window onto the widget as an overlay - QImage img = windowImage(ev->rect()); + QRect geom = QRect(0,0,this->width(), this->height()); //always paint the whole window + //qDebug() << "Get Paint image"; + QImage img = windowImage(geom); if(!img.isNull()){ QPainter P(this); - P.drawImage( ev->rect() , img, ev->rect(), Qt::NoOpaqueDetection); //1-to-1 mapping - qDebug() << "Painted Rect:" << ev->rect() << this->geometry(); + P.drawImage( geom , img, geom, Qt::NoOpaqueDetection); //1-to-1 mapping + //qDebug() << "Painted Rect:" << ev->rect() << this->geometry(); //Note: Qt::NoOpaqueDetection Speeds up the paint by bypassing the checks to see if there are [semi-]transparent pixels // Since this is an embedded image - we fully expect there to be transparency most of the time. - }else{ - QWidget::paintEvent(ev); } - qDebug() << "Done Painting"; + //qDebug() << "Done Painting"; } -- cgit From f5b60b2681bc6fc8e9171566e28064fe7048aa8b Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 19 Jul 2017 13:53:34 -0400 Subject: Another checkpoint in the compositing saga. Got most of it working, but still getting random artifacting *outside* of the window that we are painting from time to time. --- src-qt5/core/libLumina/NativeEmbedWidget.cpp | 68 +++++++++++++++------------- src-qt5/core/libLumina/NativeEmbedWidget.h | 9 +++- src-qt5/core/libLumina/RootSubWindow.cpp | 7 ++- 3 files changed, 50 insertions(+), 34 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp index 333fe6e2..80c843e0 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -38,17 +38,13 @@ inline void registerClientEvents(WId id){ //Simplification functions for the XCB/XLib interactions void NativeEmbedWidget::syncWinSize(QSize sz){ if(WIN==0){ return; } + if(!sz.isValid()){ sz = this->size(); } //use the current widget size //qDebug() << "Sync Window Size:" << sz; - xcb_configure_window_value_list_t valList; - valList.x = 0; - valList.y = 0; - valList.width = sz.width(); - valList.height = sz.height(); - uint16_t mask = 0; - mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; - xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); - //xcb_flush(QX11Info::connection()); + if(sz == winSize){ return; } //no change + const uint32_t valList[2] = {(uint32_t) sz.width(), (uint32_t) sz.height()}; + const uint32_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + xcb_configure_window(QX11Info::connection(), WIN->id(), mask, valList); + winSize = sz; //save this for checking later } void NativeEmbedWidget::syncWidgetSize(QSize sz){ @@ -89,7 +85,7 @@ QImage NativeEmbedWidget::windowImage(QRect geom){ // ============ NativeEmbedWidget::NativeEmbedWidget(QWidget *parent) : QWidget(parent){ WIN = 0; //nothing embedded yet - this->setStyleSheet("background: transparent;"); //this widget should be fully-transparent to Qt itself (will paint on top of that) + this->setSizeIncrement(2,2); } bool NativeEmbedWidget::embedWindow(NativeWindow *window){ @@ -125,7 +121,7 @@ bool NativeEmbedWidget::embedWindow(NativeWindow *window){ WIN->addDamageID( (uint) dmgID); //save this for later WIN->addFrameWinID(this->winId()); - connect(WIN, SIGNAL(VisualChanged()), this, SLOT(update()) ); //make sure we repaint the widget on visual change + connect(WIN, SIGNAL(VisualChanged()), this, SLOT(repaintWindow()) ); //make sure we repaint the widget on visual change registerClientEvents(WIN->id()); registerClientEvents(this->winId()); @@ -146,32 +142,37 @@ bool NativeEmbedWidget::isEmbedded(){ // PUBLIC SLOTS // ============== void NativeEmbedWidget::resyncWindow(){ - QSize sz = this->size(); if(WIN==0){ return; } - //Just jitter the x origin of the window 1 pixel so the window knows to re-check it's global position - // before creating child windows (menu's in particular). + return; //skip the stuff below (not working) + QRect geom = WIN->geometry(); + //Send an artificial configureNotify event to the window with the global position/size included + xcb_configure_notify_event_t event; + event.x = geom.x() + this->pos().x(); + event.y = geom.y() + this->pos().y(); + event.width = this->width(); + event.height = this->height(); + event.border_width = 0; + event.above_sibling = XCB_NONE; + event.override_redirect = false; + event.window = WIN->id(); + event.event = WIN->id(); + event.response_type = XCB_CONFIGURE_NOTIFY; + xcb_send_event(QX11Info::connection(), false, WIN->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, (const char *) &event); - //qDebug() << "Sync Window Size:" << sz; - xcb_configure_window_value_list_t valList; - valList.x = 0; - valList.y = 0; - valList.width = sz.width(); - //valList.height = sz.height()-1; - uint16_t mask = 0; - mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - mask = mask | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; - //xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); - valList.height = sz.height(); - //xcb_flush(QX11Info::connection()); - xcb_configure_window_aux(QX11Info::connection(), WIN->id(), mask, &valList); + xcb_flush(QX11Info::connection()); } +void NativeEmbedWidget::repaintWindow(){ + this->update(); +} // ============== // PROTECTED // ============== void NativeEmbedWidget::resizeEvent(QResizeEvent *ev){ - if(WIN!=0){ syncWinSize(ev->size()); } //syncronize the window with the new widget size QWidget::resizeEvent(ev); + if(WIN!=0){ + syncWinSize(ev->size()); + } //syncronize the window with the new widget size } void NativeEmbedWidget::showEvent(QShowEvent *ev){ @@ -186,14 +187,19 @@ void NativeEmbedWidget::hideEvent(QHideEvent *ev){ void NativeEmbedWidget::paintEvent(QPaintEvent *ev){ //QWidget::paintEvent(ev); //ensure all the Qt-compositing is done first + if(this->size()!=winSize){ return; } //do not paint here - waiting to re-sync the sizes if(WIN==0){ QWidget::paintEvent(ev); return; } //Need to paint the image from the window onto the widget as an overlay QRect geom = QRect(0,0,this->width(), this->height()); //always paint the whole window - //qDebug() << "Get Paint image"; + //qDebug() << "Get Paint image:" << ev->rect() << geom; + //geom = ev->rect(); //atomic updates + //geom.adjust(-1,-1,1,1); //add an additional pixel in each direction to be painted + //geom = geom.intersected(QRect(0,0,this->width(), this->height())); //ensure intersection with actual window QImage img = windowImage(geom); if(!img.isNull()){ + if(img.size() != geom.size()){ return; } QPainter P(this); - P.drawImage( geom , img, geom, Qt::NoOpaqueDetection); //1-to-1 mapping + P.drawImage( geom , img, QRect(geom.topLeft(), img.size()), Qt::NoOpaqueDetection); //1-to-1 mapping //qDebug() << "Painted Rect:" << ev->rect() << this->geometry(); //Note: Qt::NoOpaqueDetection Speeds up the paint by bypassing the checks to see if there are [semi-]transparent pixels // Since this is an embedded image - we fully expect there to be transparency most of the time. diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.h b/src-qt5/core/libLumina/NativeEmbedWidget.h index 07e1c4dd..78c11dfc 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.h +++ b/src-qt5/core/libLumina/NativeEmbedWidget.h @@ -13,6 +13,7 @@ #include "NativeWindow.h" #include +#include #include #include #include @@ -22,14 +23,17 @@ class NativeEmbedWidget : public QWidget{ Q_OBJECT private: NativeWindow *WIN; + QSize winSize; +private slots: //Simplification functions - void syncWinSize(QSize); - void syncWidgetSize(QSize); + void syncWinSize(QSize sz = QSize()); + void syncWidgetSize(QSize sz); void hideWindow(); void showWindow(); QImage windowImage(QRect geom); + public: NativeEmbedWidget(QWidget *parent); @@ -39,6 +43,7 @@ public: public slots: void resyncWindow(); + void repaintWindow(); protected: void resizeEvent(QResizeEvent *ev); diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 1059871a..9ef6464e 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -181,6 +181,12 @@ void RootSubWindow::initWindowFrame(){ titleBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); mainLayout->addWidget(titleBar); mainLayout->addWidget(WinWidget); + //Setup the cursors for the buttons + closeB->setCursor(Qt::ArrowCursor); + minB->setCursor(Qt::ArrowCursor); + maxB->setCursor(Qt::ArrowCursor); + otherM->setCursor(Qt::ArrowCursor); + titleLabel->setCursor(Qt::ArrowCursor); //Now all the stylesheet options this->setObjectName("WindowFrame"); closeB->setObjectName("Button_Close"); @@ -492,7 +498,6 @@ void RootSubWindow::mouseMoveEvent(QMouseEvent *ev){ default: break; } - this->setGeometry(geom); } QFrame::mouseMoveEvent(ev); -- cgit