diff options
Diffstat (limited to 'libLumina')
-rw-r--r-- | libLumina/LuminaOS.h | 1 | ||||
-rw-r--r-- | libLumina/LuminaSingleApplication.cpp | 107 | ||||
-rw-r--r-- | libLumina/LuminaSingleApplication.h | 54 | ||||
-rw-r--r-- | libLumina/LuminaThemes.cpp | 2 | ||||
-rw-r--r-- | libLumina/LuminaUtils.cpp | 4 | ||||
-rw-r--r-- | libLumina/LuminaUtils.h | 1 | ||||
-rw-r--r-- | libLumina/LuminaX11.cpp | 208 | ||||
-rw-r--r-- | libLumina/LuminaX11.h | 35 | ||||
-rw-r--r-- | libLumina/LuminaXDG.cpp | 19 | ||||
-rw-r--r-- | libLumina/LuminaXDG.h | 2 | ||||
-rw-r--r-- | libLumina/libLumina.pro | 12 | ||||
-rwxr-xr-x[-rw-r--r--] | libLumina/make-linux-distro.sh | 0 |
12 files changed, 430 insertions, 15 deletions
diff --git a/libLumina/LuminaOS.h b/libLumina/LuminaOS.h index 90f68691..7bf0e923 100644 --- a/libLumina/LuminaOS.h +++ b/libLumina/LuminaOS.h @@ -16,6 +16,7 @@ #include <QStringList> #include <QProcess> #include <QDir> +#include <QObject> #include "LuminaUtils.h" diff --git a/libLumina/LuminaSingleApplication.cpp b/libLumina/LuminaSingleApplication.cpp new file mode 100644 index 00000000..ce983035 --- /dev/null +++ b/libLumina/LuminaSingleApplication.cpp @@ -0,0 +1,107 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2014, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "LuminaSingleApplication.h" +#include <QDir> +#include <QFile> +#include <QLocalSocket> +#include <QDebug> + +#include <unistd.h> //for getlogin() + +LSingleApplication::LSingleApplication(int &argc, char **argv) : QApplication(argc, argv){ + //Initialize a couple convenience internal variables + cfile = QDir::tempPath()+"/.LSingleApp-%1-%2"; + QString username = QString(getlogin()); + QString appname = this->applicationName(); + //Obscure the user/app in the filename (TO DO) + //qDebug() << username << appname; + //bool junk; + //qDebug() << QString::number( username.toInt(&junk,16) ); + cfile = cfile.arg( username, appname ); + lockfile = new QLockFile(cfile+"-lock"); + lockfile->setStaleLockTime(0); //long-lived processes + for(int i=1; i<argc; i++){ inputlist << QString(argv[i]); } + isActive = false; + lserver = 0; + PerformLockChecks(); +} + +LSingleApplication::~LSingleApplication(){ + if(lserver != 0 && lockfile->isLocked() ){ + //currently locked instance: remove the lock now + lserver->close(); + QLocalServer::removeServer(cfile); + lockfile->unlock(); + } +} + +bool LSingleApplication::isPrimaryProcess(){ + return isActive; +} + +void LSingleApplication::PerformLockChecks(){ + bool primary = lockfile->tryLock(); + //qDebug() << "Try Lock: " << primary; + if(!primary){ + //Pre-existing lock - check it for validity + QString appname, hostname; + qint64 pid; + lockfile->getLockInfo(&pid, &hostname, &appname); //PID already exists if it gets this far, ignore hostname + //qDebug() << " - Lock Info:" << pid << hostname << appname; + if( appname!=this->applicationName() || !QFile::exists(cfile) ){ + //Some other process has the same PID or the server does not exist - stale lock + //qDebug() << " - Stale Lock"; + lockfile->removeStaleLockFile(); + //Now re-try to create the lock + primary = lockfile->tryLock(); + //qDebug() << " - Try Lock Again:" << primary; + } + } + if(primary){ + //Create the server socket + //qDebug() << "Create Local Server"; + if(QFile::exists(cfile)){ QLocalServer::removeServer(cfile); } //stale socket/server file + lserver = new QLocalServer(this); + connect(lserver, SIGNAL(newConnection()), this, SLOT(newInputsAvailable()) ); + if( lserver->listen(cfile) ){ + lserver->setSocketOptions(QLocalServer::UserAccessOption); + //qDebug() << " - Success"; + isActive = true; + }else{ + //qDebug() << " - Failure:" << lserver->errorString(); + lockfile->unlock(); + } + + }else{ + //forward the current inputs to the locked process for processing and exit + //qDebug() << "Forward inputs to locking process:" << inputlist; + QLocalSocket socket(this); + socket.connectToServer(cfile); + socket.waitForConnected(); + if(!socket.isValid()){ exit(1); } //error - could not forward info + socket.write( inputlist.join("::::").toLocal8Bit() ); + socket.waitForDisconnected(500); //max out at 1/2 second (only hits this if no inputs) + } + +} + +//New messages detected +void LSingleApplication::newInputsAvailable(){ + while(lserver->hasPendingConnections()){ + QLocalSocket *sock = lserver->nextPendingConnection(); + QByteArray bytes; + sock->waitForReadyRead(); + while(sock->bytesAvailable() > 0){ //if(sock->waitForReadyRead()){ + //qDebug() << "Info Available"; + bytes.append( sock->readAll() ); + } + sock->disconnectFromServer(); + QStringList inputs = QString::fromLocal8Bit(bytes).split("::::"); + //qDebug() << " - New Inputs Detected:" << inputs; + emit InputsAvailable(inputs); + } +}
\ No newline at end of file diff --git a/libLumina/LuminaSingleApplication.h b/libLumina/LuminaSingleApplication.h new file mode 100644 index 00000000..f61a90c0 --- /dev/null +++ b/libLumina/LuminaSingleApplication.h @@ -0,0 +1,54 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2014, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the general class for a single-instance application +//=========================================== +//EXAMPLE USAGE in main.cpp: +// +// LSingleApplication app(argc, argv); +// if( !app.isPrimaryProcess() ){ +// return 0; +// } +// QMainWindow w; //or whatever the main window class is +// connect(app, SIGNAL(InputsAvailable(QStringList)), w, SLOT(<some slot>)); //for interactive apps - optional +// app.exec(); +//=========================================== +#ifndef _LUMINA_LIBRARY_SINGLE_APPLICATION_H +#define _LUMINA_LIBRARY_SINGLE_APPLICATION_H + +#include <QApplication> +#include <QString> +#include <QStringList> +#include <QLocalServer> +#include <QLockFile> + + +class LSingleApplication : public QApplication{ + Q_OBJECT +public: + LSingleApplication(int &argc, char **argv); + ~LSingleApplication(); + + bool isPrimaryProcess(); + +private: + bool isActive; + QLockFile *lockfile; + QLocalServer *lserver; + QString cfile; + QStringList inputlist; + + void PerformLockChecks(); + +private slots: + void newInputsAvailable(); //internally used to detect a message from an alternate instance + +signals: + void InputsAvailable(QStringList); + +}; + +#endif diff --git a/libLumina/LuminaThemes.cpp b/libLumina/LuminaThemes.cpp index feacc81d..fd740e20 100644 --- a/libLumina/LuminaThemes.cpp +++ b/libLumina/LuminaThemes.cpp @@ -11,7 +11,7 @@ #include <QIcon> #include <QFont> #include <QDebug> - +#include <QObject> QStringList LTHEME::availableSystemThemes(){ //returns: [name::::path] for each item diff --git a/libLumina/LuminaUtils.cpp b/libLumina/LuminaUtils.cpp index 830cfc97..ed08857f 100644 --- a/libLumina/LuminaUtils.cpp +++ b/libLumina/LuminaUtils.cpp @@ -5,6 +5,10 @@ // See the LICENSE file for full details //=========================================== #include "LuminaUtils.h" +#include <QString> +#include <QFile> +#include <QStringList> +#include <QObject> int LUtils::runCmd(QString cmd, QStringList args){ QProcess *proc = new QProcess; diff --git a/libLumina/LuminaUtils.h b/libLumina/LuminaUtils.h index 44bec991..3a75fc3b 100644 --- a/libLumina/LuminaUtils.h +++ b/libLumina/LuminaUtils.h @@ -16,6 +16,7 @@ #include <QStringList> #include <QFile> #include <QFileInfo> +#include <QObject> class LUtils{ public: diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp index 68d54c6d..699d7b99 100644 --- a/libLumina/LuminaX11.cpp +++ b/libLumina/LuminaX11.cpp @@ -6,6 +6,12 @@ //=========================================== #include "LuminaX11.h" +#include <QString> +#include <QByteArray> +#include <QFile> +#include <QObject> +#include <QImage> + //X includes (these need to be last due to Qt compile issues) #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -13,6 +19,27 @@ #include <X11/extensions/Xrender.h> #include <X11/extensions/Xcomposite.h> +//XCB Library includes +#include <xcb/xcb.h> +#include <xcb/xcb_atom.h> +#include <xcb/xproto.h> +#include <xcb/xcb_ewmh.h> +#include <xcb/xcb_icccm.h> + +//xcb_ewmh_connection_t ewmh_handle; + +//===== Get EWMH connection handle ===== +/*xcb_ewmh_connection_t* LX11::EWMH_C(){ + static bool firstrun = true; + if(firstrun){ + qDebug() << "Init EWMH structure"; + xcb_ewmh_init_atoms(QX11Info::connection(), &ewmh_handle); + firstrun = false; + } + qDebug() << "Return EWMH structure pointer:" << &ewmh_handle; + return &ewmh_handle; +}*/ + //===== WindowList() ======== QList<WId> LX11::WindowList(){ QList<WId> output; @@ -26,7 +53,7 @@ QList<WId> LX11::WindowList(){ QString name = LX11::WindowClass(output[i]); if(output[i] == 0){ remove=true; } else if( desk >= 0 && LX11::WindowDesktop(output[i]) != desk){ remove = true; } - else if( name=="Lumina-DE" ){ remove = true; } + else if( name=="Lumina Desktop Environment" ){ remove = true; } else if(name.startsWith("Lumina-")){ //qDebug() << "Lumina Window:" << name << LX11::WindowName(output[i]); if(LX11::WindowName(output[i]).toLower()==name.toLower() ){ remove=true; } @@ -52,6 +79,17 @@ QList<WId> LX11::WindowList(){ // ===== GetClientList() ===== QList<WId> LX11::GetClientList(){ QList<WId> output; + //XCB Library + /*qDebug() << "Get Client list cookie"; + xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list_unchecked( LX11::EWMH_C(), 0); + xcb_ewmh_get_windows_reply_t winlist; + qDebug() << "Get client list"; + if( xcb_ewmh_get_client_list_reply( LX11::EWMH_C(), cookie, &winlist, NULL) ){ + qDebug() << " - Loop over items"; + for(unsigned int i=0; i<winlist.windows_len; i++){ output << winlist.windows[i]; } + }*/ + + //XLib Atom a = XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST", true); Atom realType; int format; @@ -90,7 +128,7 @@ QList<WId> LX11::GetClientStackingList(){ } // ===== findChildren() ===== -QList<WId> LX11::findChildren(Window parent, int levels){ +QList<WId> LX11::findChildren(WId parent, int levels){ Window rootR, parentR; Window *childrenR; unsigned int num; @@ -129,6 +167,9 @@ WId LX11::ActiveWindow(){ // ===== SetNumberOfDesktops() ===== void LX11::SetNumberOfDesktops(int number){ + //XCB Library + + //XLib Display *display = QX11Info::display(); Window rootWindow = QX11Info::appRootWindow(); @@ -253,8 +294,13 @@ void LX11::IconifyWindow(WId win){ // ===== RestoreWindow() ===== void LX11::RestoreWindow(WId win){ - Display *disp = QX11Info::display(); - XMapRaised(disp, win); //make it visible again and raise it to the top + //XCB Library + uint32_t val = XCB_STACK_MODE_ABOVE; + xcb_configure_window(QX11Info::connection(), win, XCB_CONFIG_WINDOW_STACK_MODE, &val); //raise it + xcb_map_window(QX11Info::connection(), win); //map it + //XLib + //Display *disp = QX11Info::display(); + //XMapRaised(disp, win); //make it visible again and raise it to the top } // ===== ActivateWindow() ===== @@ -315,12 +361,16 @@ void LX11::ReservePanelLocation(WId win, int xstart, int ystart, int width, int // ===== SetAsSticky() ===== void LX11::SetAsSticky(WId win){ //make this window "stick" to all virtual desktops + + //XCB Library + // xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_APPEND, win, _NET_WM_STATE, XCB_ATOM, 32, 1, _NET_WM_STATE_STICKY); + + //XLib Display *disp = QX11Info::display(); Atom stick = XInternAtom(disp, "_NET_WM_STATE_STICKY",false); Atom state = XInternAtom(disp, "_NET_WM_STATE", false); - XChangeProperty(disp, win, state, XA_ATOM, 32, PropModeAppend, (unsigned char*) &stick, 1); - + XChangeProperty(disp, win, state, XA_ATOM, 32, PropModeAppend, (unsigned char*) &stick, 1L); } // ===== SetAsPanel() ===== @@ -549,7 +599,12 @@ int LX11::WindowDesktop(WId win){ // ===== GetWindowState() ===== LX11::WINDOWSTATE LX11::GetWindowState(WId win){ + LX11::WINDOWSTATE state = LX11::VISIBLE; + + //XCB Library (TO DO) + + //XLib Display *disp = QX11Info::display(); Atom SA = XInternAtom(disp, "_NET_WM_STATE", true); Atom ATTENTION = XInternAtom(disp, "_NET_WM_STATE_DEMANDS_ATTENTION", false); @@ -564,8 +619,7 @@ LX11::WINDOWSTATE LX11::GetWindowState(WId win){ int status = XGetWindowProperty( disp, win, SA, 0, ~(0L), false, AnyPropertyType, &type, &format, &num, &bytes, (unsigned char**) &data); - - LX11::WINDOWSTATE state = LX11::VISIBLE; + if(status >= Success && data){ for(unsigned int i=0; i<num; i++){ if(data[i] == SKIPP || data[i]==SKIPT){ @@ -671,7 +725,7 @@ WId LX11::startSystemTray(int screen){ //Get the appropriate atom for this screen QString str = QString("_NET_SYSTEM_TRAY_S%1").arg(QString::number(screen)); qDebug() << "Default Screen Atom Name:" << str; - Atom _NET_SYSTEM_TRAY_S = XInternAtom(disp,str.toAscii(),false); + Atom _NET_SYSTEM_TRAY_S = XInternAtom(disp,str.toLatin1(),false); //Make sure that there is no other system tray running if(XGetSelectionOwner(disp, _NET_SYSTEM_TRAY_S) != None){ qWarning() << "An alternate system tray is currently in use"; @@ -783,3 +837,139 @@ QString LX11::getNetWMProp(WId win, QString prop){ } return property; } + +//=============================== +//=============================== +// XCB LIBRARY FUNCTIONS +//=============================== +//=============================== +LXCB::LXCB(){ + 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"; + }else{ + qDebug() << "Number of XCB screens:" << EWMH.nb_screens; + } +} +LXCB::~LXCB(){ + xcb_ewmh_connection_wipe(&EWMH); +} + +// === WindowList() === +QList<WId> LXCB::WindowList(bool rawlist){ + QList<WId> output; + qDebug() << "Get Client list cookie"; + xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list_unchecked( &EWMH, 0); + xcb_ewmh_get_windows_reply_t winlist; + qDebug() << "Get client list"; + 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<winlist.windows_len; i++){ + //Filter out the Lumina Desktop windows + if(WindowClass(winlist.windows[i]) == "Lumina Desktop Environment"){ continue; } + //Also filter out windows not on the active workspace + else if( (WindowWorkspace(winlist.windows[i])!=wkspace) && !rawlist ){ continue; } + else{ + output << winlist.windows[i]; + } + } + } + return output; +} + +// === CurrentWorkspace() === +unsigned int LXCB::CurrentWorkspace(){ + qDebug() << "Get Current Workspace"; + xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop_unchecked(&EWMH, 0); + uint32_t wkspace = 0; + xcb_ewmh_get_current_desktop_reply(&EWMH, cookie, &wkspace, NULL); + qDebug() << " - done:" << wkspace; + return wkspace; +} + +// === WindowClass() === +QString LXCB::WindowClass(WId win){ + QString out; + xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class_unchecked(QX11Info::connection(), win); + xcb_icccm_get_wm_class_reply_t value; + if( 1== xcb_icccm_get_wm_class_reply( QX11Info::connection(), cookie, &value, NULL) ){ + out = QString(value.class_name); + } + xcb_icccm_get_wm_class_reply_wipe(&value); + return out; +} + +// === WindowWorkspace() === +unsigned int LXCB::WindowWorkspace(WId win){ + qDebug() << "Get Window Workspace"; + uint32_t wkspace = 0; + xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_desktop_unchecked(&EWMH, win); + xcb_ewmh_get_wm_desktop_reply(&EWMH, cookie, &wkspace, NULL); + qDebug() << " - done: " << wkspace; + return wkspace; +} + +// === WindowState() === +LXCB::WINDOWSTATE LXCB::WindowState(WId win){ + xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_state_unchecked(&EWMH, win); + xcb_ewmh_get_atoms_reply_t states; + WINDOWSTATE cstate = IGNORE; + //First Check for special states (ATTENTION in particular); + if( 1 == xcb_ewmh_get_wm_state_reply(&EWMH, cookie, &states, NULL) ){ + for(unsigned int i=0; i<states.atoms_len; i++){ + if(states.atoms[i] == EWMH._NET_WM_STATE_DEMANDS_ATTENTION){ cstate = ATTENTION; break; } //nothing more urgent - stop here + else if(states.atoms[i] == EWMH._NET_WM_STATE_HIDDEN){ cstate = INVISIBLE; } + } + } + //Now check for ICCCM Urgency hint (not sure if this is still valid with EWMH instead) + /*if(cstate == IGNORE){ + xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints_unchecked(QX11Info::connection(), win); + xcb_icccm_wm_hints_t hints; + if( 1== xcb_icccm_get_wm_hints_reply(QX11Info::connection(), cookie, &hints, NULL) ){ + if(xcb_icccm_wm_hints_get_urgency(hints) ){ cstate = ATTENTION; }; + } + }*/ + //Now check for standard visible/invisible attribute (current mapping state) + if(cstate == IGNORE){ + xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(QX11Info::connection(), win); + xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(QX11Info::connection(), cookie, NULL); + if(attr!=0){ + if(attr->map_state==XCB_MAP_STATE_VIEWABLE){ cstate = VISIBLE; } + else{ cstate = INVISIBLE; } + free(attr); + } + } + return cstate; +} + +// === SetAsSticky() === +void LXCB::SetAsSticky(WId win){ + xcb_change_property( QX11Info::connection(), XCB_PROP_MODE_APPEND, win, EWMH._NET_WM_STATE, XCB_ATOM_ATOM, 32, 1, &(EWMH._NET_WM_STATE_STICKY) ); + xcb_flush(QX11Info::connection()); //apply it right away +} + +// === SetScreenWorkArea() === +/*void LXCB::SetScreenWorkArea(unsigned int screen, QRect rect){ + //This is only useful because Fluxbox does not set the _NET_WORKAREA root atom + // This needs to be better incorporated into the new window manager later + + //First get the current workarea array (for all monitors/screens) + xcb_get_property_cookie_t cookie = xcb_ewmh_get_workarea_unchecked(&EWMH, 0); + xcb_ewmh_get_workarea_reply_t work; + if(0==xcb_ewmh_get_workarea_reply(&EWMH, cookie, &work, NULL)){ return; } //Error: Could not retrieve current work areas + //Save what we need only from the reply + unsigned int desks = work.workarea_len; + if(desks <= screen){ return; } //invalid screen to modify + qDebug() << "Number of desktops/screens:" << desks; + xcb_ewmh_geometry_t *dareas = work.workarea; + //Adjust the work area for the input monitor/screen + dareas[screen].x = rect.x(); + dareas[screen].y = rect.y(); + dareas[screen].width = rect.width(); + dareas[screen].height = rect.height(); + //Now save the array again + xcb_ewmh_set_workarea(&EWMH, 0, desks, dareas); //_NET_WORKAREA + //Make sure to clear that reply + xcb_ewmh_get_workarea_reply_wipe(&work); +}*/
\ No newline at end of file diff --git a/libLumina/LuminaX11.h b/libLumina/LuminaX11.h index e7cded49..ac232de1 100644 --- a/libLumina/LuminaX11.h +++ b/libLumina/LuminaX11.h @@ -20,6 +20,7 @@ #include <QX11Info> #include <QDebug> #include <QPainter> +#include <QObject> // Addition includes for compilations (cause issues with X11 libs later) #include <QDir> #include <QEvent> @@ -33,6 +34,8 @@ //#include <X11/Xatom.h> //#include <X11/extensions/Xrender.h> +#include <xcb/xcb_ewmh.h> + //SYSTEM TRAY STANDARD DEFINITIONS #define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 #define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1 @@ -46,6 +49,9 @@ class LX11{ public: enum WINDOWSTATE {VISIBLE, INVISIBLE, ACTIVE, ATTENTION, IGNORE}; + //Internal Use Functions + //static xcb_ewmh_connection_t* EWMH_C(); //Get the XCB_ewmh handle; + //General Info Functions static QList<WId> WindowList(); //List all current windows static QList<WId> GetClientList(); // _NET_WM_CLIENT list @@ -102,4 +108,33 @@ public: static QString getNetWMProp(WId win, QString prop); //Returns a _NET_WM_* string value }; +//XCB Library replacement for LX11 (Qt5 uses XCB instead of XLib) +class LXCB{ + +private: + xcb_ewmh_connection_t EWMH; + +public: + enum WINDOWSTATE {VISIBLE, INVISIBLE, ACTIVE, ATTENTION, IGNORE}; + + LXCB(); + ~LXCB(); + + //== Main Interface functions == + // General Information + QList<WId> WindowList(bool rawlist = false); //list all non-Lumina windows (rawlist -> all workspaces) + unsigned int CurrentWorkspace(); + + //Session Modification + + + //Window Information + QString WindowClass(WId); + unsigned int WindowWorkspace(WId); + WINDOWSTATE WindowState(WId win); //Visible state of window + + //Window Modification + void SetAsSticky(WId); +}; + #endif
\ No newline at end of file diff --git a/libLumina/LuminaXDG.cpp b/libLumina/LuminaXDG.cpp index 057954dd..84a6f665 100644 --- a/libLumina/LuminaXDG.cpp +++ b/libLumina/LuminaXDG.cpp @@ -6,6 +6,8 @@ //=========================================== #include "LuminaXDG.h" #include "LuminaOS.h" +#include <QObject> +#include <QMediaPlayer> static QStringList mimeglobs; static qint64 mimechecktime; @@ -44,7 +46,7 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){ QString var = line.section("=",0,0).simplified(); QString loc = var.section("[",1,1).section("]",0,0).simplified(); // localization var = var.section("[",0,0).simplified(); //remove the localization - QString val = line.section("=",1,1).simplified(); + QString val = line.section("=",1,50).simplified(); //------------------- if(var=="Name"){ if(DF.name.isEmpty() && loc.isEmpty()){ DF.name = val; } @@ -558,6 +560,21 @@ void LXDG::setDefaultAppForMime(QString mime, QString app){ return; } +QStringList LXDG::findAVFileExtensions(){ + //output format: QDir name filter for valid A/V file extensions + QStringList globs = LXDG::loadMimeFileGlobs2(); + QStringList av = globs.filter(":audio/"); + av << globs.filter(":video/"); + for(int i=0; i<av.length(); i++){ + //Just use all audio/video mimetypes (for now) + av[i] = av[i].section(":",2,2); + //Qt5 Auto detection (broken - QMediaPlayer seg faults with Qt 5.3 - 11/24/14) + /*if( QMultimedia::NotSupported != QMediaPlayer::hasSupport(av[i].section(":",1,1)) ){ av[i] = av[i].section(":",2,2); } + else{ av.removeAt(i); i--; }*/ + } + return av; +} + QStringList LXDG::loadMimeFileGlobs2(){ //output format: <weight>:<mime type>:<file extension (*.something)> if(mimeglobs.isEmpty() || (mimechecktime < (QDateTime::currentMSecsSinceEpoch()-30000)) ){ diff --git a/libLumina/LuminaXDG.h b/libLumina/LuminaXDG.h index ec994820..ad09d490 100644 --- a/libLumina/LuminaXDG.h +++ b/libLumina/LuminaXDG.h @@ -93,6 +93,8 @@ public: static QString findDefaultAppForMime(QString mime); //Set the default application for a mime-type static void setDefaultAppForMime(QString mime, QString app); + //List all the registered audio/video file extensions + static QStringList findAVFileExtensions(); //Load all the "globs2" mime database files static QStringList loadMimeFileGlobs2(); }; diff --git a/libLumina/libLumina.pro b/libLumina/libLumina.pro index d37c2c0d..5b9cfe6c 100644 --- a/libLumina/libLumina.pro +++ b/libLumina/libLumina.pro @@ -1,5 +1,6 @@ -QT += core +QT += core network +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras multimedia TARGET=LuminaUtils @@ -24,12 +25,14 @@ HEADERS += LuminaXDG.h \ LuminaUtils.h \ LuminaX11.h \ LuminaThemes.h \ - LuminaOS.h + LuminaOS.h \ + LuminaSingleApplication.h SOURCES += LuminaXDG.cpp \ LuminaUtils.cpp \ LuminaX11.cpp \ LuminaThemes.cpp \ + LuminaSingleApplication.cpp \ LuminaOS-FreeBSD.cpp \ LuminaOS-DragonFly.cpp \ LuminaOS-OpenBSD.cpp \ @@ -39,14 +42,15 @@ SOURCES += LuminaXDG.cpp \ INCLUDEPATH += $$PREFIX/include -LIBS += -lX11 -lXrender -lXcomposite +LIBS += -lX11 -lXrender -lXcomposite -lxcb -lxcb-ewmh -lxcb-icccm include.path=$$PREFIX/include/ include.files=LuminaXDG.h \ LuminaUtils.h \ LuminaX11.h \ LuminaThemes.h \ - LuminaOS.h + LuminaOS.h \ + LuminaSingleApplication.h colors.path=$$PREFIX/share/Lumina-DE/colors/ colors.files=colors/Lumina-Red.qss.colors \ diff --git a/libLumina/make-linux-distro.sh b/libLumina/make-linux-distro.sh index 552894d5..552894d5 100644..100755 --- a/libLumina/make-linux-distro.sh +++ b/libLumina/make-linux-distro.sh |