diff options
author | Ken Moore <ken@pcbsd.org> | 2014-12-18 07:47:48 -0500 |
---|---|---|
committer | Ken Moore <ken@pcbsd.org> | 2014-12-18 07:47:48 -0500 |
commit | 71c2fda95224f0a04316c5f1059628d33564ca43 (patch) | |
tree | ca74dbe49dd2f555e73893e7f5f06154d6dab763 | |
parent | Oops, forgot to add knowledge of the new "Wine" app category to the userbutton. (diff) | |
download | lumina-71c2fda95224f0a04316c5f1059628d33564ca43.tar.gz lumina-71c2fda95224f0a04316c5f1059628d33564ca43.tar.bz2 lumina-71c2fda95224f0a04316c5f1059628d33564ca43.zip |
Commit a checkpoint on the conversion of Lumina to Qt5.
It is functional at the moment, but still has a few rough edges with regards to the X11 background interface (due to the move from XLib to XCB in Qt5). This reulst in some of the window manager interactions not behaving properly (such as sticky status on panels).
48 files changed, 783 insertions, 242 deletions
diff --git a/DEPENDENCIES b/DEPENDENCIES index dafae1e0..8e9e8c5f 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -20,6 +20,7 @@ xbrightness (x11/xbrightness) (Screen Brightness Control) Build time dependencies: +== (Version 0.7.2) == Qt 4.8+ qt4-core (devel/qt4-corelib)) qt4-gui (x11-toolkits/qt4-gui) @@ -31,11 +32,30 @@ Qt 4.8+ qt4-moc (devel/qt4-moc) qt4-rcc (devel/qt4-rcc) devel/qt4-qtsolutions-singleapplication - + X.org and XLib with extensions: Xrender (x11/libXrender) Xcomposite (x11/libXcomposite) Xdamage (x11/libXdamage) + +== (Version 0.8.0+) == +Qt 5.2+ + qt5-core + qt5-buildtools + qt5-gui + qt5-widgets + qt5-multimedia + qt5-network + qt5-qmake + qt5-svg + qt5-x11extras + +X.org and XCB extensions (possibly the XLib libraries above during the transition phase): + libxcb + xcb-util-wm (window manager framework) + xcb-damage (included in base XCB lib?) + xcb-composite (included in base XCB lib?) + xcb-render (included in base XCB lib?) 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 diff --git a/lumina-config/lumina-config.pro b/lumina-config/lumina-config.pro index ff8211b3..ec6d09e3 100644 --- a/lumina-config/lumina-config.pro +++ b/lumina-config/lumina-config.pro @@ -1,5 +1,6 @@ QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras network TARGET = lumina-config isEmpty(PREFIX) { @@ -34,17 +35,17 @@ FORMS += mainUI.ui \ INCLUDEPATH += ../libLumina $$PREFIX/include LIBS += -L../libLumina -lLuminaUtils -freebsd-* { - LIBS += -lQtSolutions_SingleApplication-head -} -openbsd-g++4 { - LIBS += -lQtSolutions_SingleApplication-head -} +#freebsd-* { +# LIBS += -lQtSolutions_SingleApplication-head +#} +#openbsd-g++4 { +# LIBS += -lQtSolutions_SingleApplication-head +#} openbsd-g++4 { LRELEASE = lrelease4 } else { - LRELEASE = lrelease-qt4 + LRELEASE = $$PREFIX/lib/qt5/bin/lrelease } QMAKE_LIBDIR = ../libLumina diff --git a/lumina-config/main.cpp b/lumina-config/main.cpp index 27af600d..af5c0ab9 100644 --- a/lumina-config/main.cpp +++ b/lumina-config/main.cpp @@ -1,25 +1,19 @@ #include <QTranslator> -#ifdef __FreeBSD__ - #include <qtsingleapplication.h> -#endif -#include <QtGui/QApplication> +#include <QApplication> #include <QDebug> #include <QFile> #include "mainUI.h" #include <LuminaOS.h> #include <LuminaThemes.h> +#include <LuminaSingleApplication.h> int main(int argc, char ** argv) { - #ifndef __FreeBSD__ - QApplication a(argc, argv); - #else - QtSingleApplication a(argc, argv); - if( a.isRunning() ) - return !(a.sendMessage("show")); - #endif + LSingleApplication a(argc, argv); + if(!a.isPrimaryProcess()){ return 0; } + LuminaThemeEngine theme(&a); QTranslator translator; QLocale mylocale; @@ -32,7 +26,7 @@ int main(int argc, char ** argv) MainUI w; - QObject::connect(&a, SIGNAL(messageReceived(const QString&)), &w, SLOT(slotSingleInstance()) ); + QObject::connect(&a, SIGNAL(InputsAvailable(QStringList)), &w, SLOT(slotSingleInstance()) ); QObject::connect(&theme, SIGNAL(updateIcons()), &w, SLOT(setupIcons()) ); w.show(); diff --git a/lumina-desktop/LDesktop.cpp b/lumina-desktop/LDesktop.cpp index 9db4eac7..07225fad 100644 --- a/lumina-desktop/LDesktop.cpp +++ b/lumina-desktop/LDesktop.cpp @@ -11,6 +11,8 @@ #include <LuminaX11.h> #include "LWinInfo.h" +#define DEBUG 1 + LDesktop::LDesktop(int deskNum) : QObject(){ DPREFIX = "desktop-"+QString::number(deskNum)+"/"; @@ -103,9 +105,9 @@ void LDesktop::CreateDesktopPluginContainer(LDPlugin *plug){ // ===================== void LDesktop::InitDesktop(){ //This is called *once* during the main initialization routines - qDebug() << "Init Desktop:" << desktopnumber; + if(DEBUG){ qDebug() << "Init Desktop:" << desktopnumber; } connect(desktop, SIGNAL(resized(int)), this, SLOT(UpdateGeometry(int))); - qDebug() << "Desktop #"<<desktopnumber<<" -> "<< desktop->screenGeometry(desktopnumber).x() << desktop->screenGeometry(desktopnumber).y() << desktop->screenGeometry(desktopnumber).width() << desktop->screenGeometry(desktopnumber).height(); + if(DEBUG){ qDebug() << "Desktop #"<<desktopnumber<<" -> "<< desktop->screenGeometry(desktopnumber).x() << desktop->screenGeometry(desktopnumber).y() << desktop->screenGeometry(desktopnumber).width() << desktop->screenGeometry(desktopnumber).height(); } deskMenu = new QMenu(0); connect(deskMenu, SIGNAL(triggered(QAction*)), this, SLOT(SystemApplication(QAction*)) ); winMenu = new QMenu(0); @@ -124,17 +126,20 @@ void LDesktop::InitDesktop(){ watcher->addPath(settings->fileName()); connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(SettingsChanged()) ); + if(DEBUG){ qDebug() << "Create bgWindow"; } bgWindow = new QWidget(); bgWindow->setObjectName("bgWindow"); bgWindow->setContextMenuPolicy(Qt::CustomContextMenu); + bgWindow->setWindowFlags(Qt::FramelessWindowHint); LX11::SetAsDesktop(bgWindow->winId()); bgWindow->setGeometry(desktop->screenGeometry(desktopnumber)); connect(bgWindow, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ShowMenu()) ); + if(DEBUG){ qDebug() << "Create bgDesktop"; } bgDesktop = new QMdiArea(bgWindow); //Make sure the desktop area is transparent to show the background bgDesktop->setBackground( QBrush(Qt::NoBrush) ); bgDesktop->setStyleSheet( "QMdiArea{ border: none; background: transparent;}" ); - qDebug() << " - Desktop Init Done:" << desktopnumber; + if(DEBUG){ qDebug() << " - Desktop Init Done:" << desktopnumber; } //Start the update processes QTimer::singleShot(10,this, SLOT(UpdateMenu()) ); QTimer::singleShot(0,this, SLOT(UpdateBackground()) ); @@ -155,10 +160,10 @@ void LDesktop::SettingsChanged(){ } void LDesktop::UpdateMenu(bool fast){ - //qDebug() << " - Update Menu:" << desktopnumber; + if(DEBUG){ qDebug() << " - Update Menu:" << desktopnumber; } //Put a label at the top int num = LX11::GetCurrentDesktop(); - //qDebug() << "Found desktop number:" << num; + if(DEBUG){ qDebug() << "Found workspace number:" << num; } if(num < 0){ workspacelabel->setText( "<b>"+tr("Lumina Desktop")+"</b>"); } else{ workspacelabel->setText( "<b>"+QString(tr("Workspace %1")).arg(QString::number(num+1))+"</b>"); } if(fast && usewinmenu){ UpdateWinMenu(); } @@ -216,7 +221,7 @@ void LDesktop::winClicked(QAction* act){ } void LDesktop::UpdateDesktop(){ - qDebug() << " - Update Desktop Plugins for screen:" << desktopnumber; + if(DEBUG){ qDebug() << " - Update Desktop Plugins for screen:" << desktopnumber; } if(deskupdating){ return; } //make sure to only run this once deskupdating = true; QStringList plugins = settings->value(DPREFIX+"pluginlist", QStringList()).toStringList(); @@ -372,7 +377,7 @@ void LDesktop::DesktopPluginRemoved(QString ID){ } void LDesktop::UpdatePanels(){ - qDebug() << " - Update Panels For Screen:" << desktopnumber; + if(DEBUG){ qDebug() << " - Update Panels For Screen:" << desktopnumber; } int panels = settings->value(DPREFIX+"panels", -1).toInt(); if(panels==-1 && defaultdesktop){ panels=1; } //need at least 1 panel on the primary desktop //Remove all extra panels @@ -394,7 +399,7 @@ void LDesktop::UpdatePanels(){ } } if(!found){ - qDebug() << " -- Create panel "<< i; + if(DEBUG){ qDebug() << " -- Create panel "<< i; } //New panel LPanel *pan = new LPanel(settings, desktopnumber, i, bgWindow); PANELS << pan; @@ -412,6 +417,7 @@ void LDesktop::UpdateDesktopPluginArea(){ } //Now make sure the desktop plugin area is only the visible area QRect rec = visReg.boundingRect(); + //LSession::handle()->XCB->SetScreenWorkArea((unsigned int) desktopnumber, rec); //Now remove the X offset to place it on the current screen (needs widget-coords, not global) rec.moveTopLeft( QPoint( rec.x()-desktop->screenGeometry(desktopnumber).x() , rec.y() ) ); //qDebug() << "DPlug Area:" << rec.x() << rec.y() << rec.width() << rec.height(); @@ -426,7 +432,7 @@ void LDesktop::UpdateBackground(){ //Get the current Background if(bgupdating || bgWindow==0){ return; } //prevent multiple calls to this at the same time bgupdating = true; - qDebug() << " - Update Desktop Background for screen:" << desktopnumber; + if(DEBUG){ qDebug() << " - Update Desktop Background for screen:" << desktopnumber; } //Get the list of background(s) to show QStringList bgL = settings->value(DPREFIX+"background/filelist", QStringList()).toStringList(); //qDebug() << " - List:" << bgL << CBG; diff --git a/lumina-desktop/LPanel.cpp b/lumina-desktop/LPanel.cpp index 138a8d77..afef1e13 100644 --- a/lumina-desktop/LPanel.cpp +++ b/lumina-desktop/LPanel.cpp @@ -34,12 +34,13 @@ LPanel::LPanel(QSettings *file, int scr, int num, QWidget *parent) : QWidget(){ this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint ); this->setFocusPolicy(Qt::NoFocus); this->setWindowTitle(""); - this->setAttribute(Qt::WA_X11NetWmWindowTypeDock); //Reserve as panel/dock + //this->setAttribute(Qt::WA_X11NetWmWindowTypeDock); //Reserve as panel/dock this->setAttribute(Qt::WA_AlwaysShowToolTips); this->setObjectName("LuminaPanelWidget"); panelArea->setObjectName("LuminaPanelPluginWidget"); - //LX11::SetAsPanel(this->winId()); //set proper type of window for a panel since Qt can't do it - LX11::SetAsSticky(this->winId()); + LX11::SetAsPanel(this->winId()); //set proper type of window for a panel since Qt can't do it + LSession::handle()->XCB->SetAsSticky(this->winId()); + //LX11::SetAsSticky(this->winId()); layout = new QBoxLayout(QBoxLayout::LeftToRight); layout->setContentsMargins(0,0,0,0); layout->setSpacing(1); @@ -86,7 +87,7 @@ void LPanel::UpdatePanel(){ this->setGeometry(xloc,0,xwid, ht ); if(!hidden){ LX11::ReservePanelLocation(this->winId(), xloc, 0, this->width(), ht, "top"); } else{ - LX11::ReservePanelLocation(this->winId(), xloc, 0, this->width(), 2, "top"); + LX11::ReservePanelLocation(this->winId(), xloc, 0, this->width(), 2, "top"); hidepoint = QPoint(xloc, 2-ht); showpoint = QPoint(xloc, 0); this->move(hidepoint); //Could bleed over onto the screen above @@ -128,6 +129,9 @@ void LPanel::UpdatePanel(){ this->move(hidepoint); //Could bleed over onto the screen right } } + //With QT5, we need to make sure to reset window properties on occasion + LSession::handle()->XCB->SetAsSticky(this->winId()); + LX11::SetAsPanel(this->winId()); //Now update the appearance of the toolbar QString color = settings->value(PPREFIX+"color", "rgba(255,255,255,160)").toString(); QString style = "QWidget#LuminaPanelPluginWidget{ background: %1; border-radius: 3px; border: 1px solid %1; }"; @@ -233,7 +237,7 @@ void LPanel::paintEvent(QPaintEvent *event){ //qDebug() << "Global Rec:" << rec.x() << rec.y() << screennum; rec.moveTo( rec.x()-screen->screenGeometry(screennum).x(), rec.y() ); //qDebug() << "Adjusted Global Rec:" << rec.x() << rec.y(); - painter->drawPixmap(event->rect(), QPixmap::grabWidget(bgWindow, rec) ); + painter->drawPixmap(event->rect(), bgWindow->grab(rec) ); QWidget::paintEvent(event); //now pass the event along to the normal painting event } diff --git a/lumina-desktop/LSession.cpp b/lumina-desktop/LSession.cpp index de3d9307..c8b98b22 100644 --- a/lumina-desktop/LSession.cpp +++ b/lumina-desktop/LSession.cpp @@ -8,6 +8,10 @@ #include <LuminaOS.h> #include <QTime> +#include "LXcbEventFilter.h" + +//LibLumina X11 class +#include <LuminaX11.h> //X includes (these need to be last due to Qt compile issues) #include <X11/Xlib.h> @@ -17,9 +21,11 @@ #include <X11/extensions/Xdamage.h> #ifndef DEBUG -#define DEBUG 0 +#define DEBUG 1 #endif +XCBEventFilter *evFilter = 0; + LSession::LSession(int &argc, char ** argv) : QApplication(argc, argv){ this->setApplicationName("Lumina Desktop Environment"); this->setApplicationVersion("0.7.2"); @@ -33,14 +39,18 @@ LSession::LSession(int &argc, char ** argv) : QApplication(argc, argv){ SystemTrayID = 0; VisualTrayID = 0; TrayDmgEvent = 0; TrayDmgError = 0; + XCB = 0; //initialize the empty internal pointers to 0 appmenu = 0; settingsmenu = 0; currTranslator=0; mediaObj=0; - audioOut=0; + //audioOut=0; audioThread=0; sessionsettings=0; + //Setup the event filter for Qt5 + evFilter = new XCBEventFilter(this); + this->installNativeEventFilter( evFilter ); } LSession::~LSession(){ @@ -53,13 +63,15 @@ LSession::~LSession(){ delete appmenu; delete currTranslator; if(mediaObj!=0){delete mediaObj;} - if(audioOut!=0){delete audioOut; } + //if(audioOut!=0){delete audioOut; } } void LSession::setupSession(){ qDebug() << "Initializing Session"; QTime* timer = 0; if(DEBUG){ timer = new QTime(); timer->start(); qDebug() << " - Init srand:" << timer->elapsed();} + //Initialize the XCB interface backend + XCB = new LXCB(); //Seed random number generator (if needed) qsrand( QTime::currentTime().msec() ); //Setup the QSettings default paths @@ -260,7 +272,7 @@ void LSession::SessionEnding(){ stopSystemTray(); } -bool LSession::x11EventFilter(XEvent *event){ +/*bool LSession::x11EventFilter(XEvent *event){ //Detect X Event types and send the appropriate signal(s) switch(event->type){ // ------------------------- @@ -335,7 +347,7 @@ bool LSession::x11EventFilter(XEvent *event){ // ----------------------- //Now continue on with the event handling (don't change it) return false; -} +}*/ //=============== // SYSTEM ACCESS @@ -368,23 +380,73 @@ void LSession::playAudioFile(QString filepath){ //Setup the audio output systems for the desktop //return; //Disable this for now: too many issues with Phonon at the moment (hangs the session) bool init = false; + if(DEBUG){ qDebug() << "Play Audio File"; } if(audioThread==0){ qDebug() << " - Initialize audio systems"; audioThread = new QThread(); init = true; } - if(mediaObj==0){ qDebug() << " - Initialize Phonon media Object"; mediaObj = new Phonon::MediaObject(); init = true;} - if(audioOut==0){ qDebug() << " - Initialize Phonon audio output"; audioOut = new Phonon::AudioOutput(); init=true;} - if(mediaObj && audioOut && init){ //in case Phonon errors for some reason - qDebug() << " -- Create path between audio objects"; - Phonon::createPath(mediaObj, audioOut); + //if(mediaObj==0){ qDebug() << " - Initialize Phonon media Object"; mediaObj = new Phonon::MediaObject(); init = true;} + if(mediaObj==0){ qDebug() << " - Initialize media player"; mediaObj = new QMediaPlayer(); init = true;} + //if(audioOut==0){ qDebug() << " - Initialize Phonon audio output"; audioOut = new Phonon::AudioOutput(); init=true;} + if(mediaObj && init){ //in case it errors for some reason + //qDebug() << " -- Create path between audio objects"; + //Phonon::createPath(mediaObj, audioOut); qDebug() << " -- Move audio objects to separate thread"; mediaObj->moveToThread(audioThread); - audioOut->moveToThread(audioThread); + //audioOut->moveToThread(audioThread); + audioThread->start(); } - if(mediaObj !=0 && audioOut!=0){ - mediaObj->setCurrentSource(QUrl(filepath)); + if(mediaObj !=0 ){//&& audioOut!=0){ + //mediaObj->setCurrentSource(QUrl(filepath)); + mediaObj->setMedia(QUrl::fromLocalFile(filepath)); + mediaObj->setVolume(100); mediaObj->play(); - audioThread->start(); + //audioThread->start(); } + if(DEBUG){ qDebug() << " - Done with Audio File"; } +} +// ======================= +// XCB EVENT FILTER FUNCTIONS +// ======================= +void LSession::WindowPropertyEvent(){ + if(DEBUG){ qDebug() << "Window Property Event"; } + LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?) + emit WindowListEvent(); } +void LSession::SysTrayDockRequest(WId win){ + attachTrayWindow(win); //Check to see if the window is already registered +} + +void LSession::WindowClosedEvent(WId win){ + removeTrayWindow(win); //Check to see if the window is a tray app +} + +void LSession::WindowConfigureEvent(WId win){ + for(int i=0; i<RunningTrayApps.length(); i++){ + if(win==RunningTrayApps[i]){ + if(DEBUG){ qDebug() << "SysTray: Configure Event"; } + emit TrayIconChanged(RunningTrayApps[i]); //trigger a repaint event + break; + } + } +} + +void LSession::WindowDamageEvent(WId win){ + for(int i=0; i<RunningTrayApps.length(); i++){ + if(win==RunningTrayApps[i]){ + if(DEBUG){ qDebug() << "SysTray: Damage Event"; } + emit TrayIconChanged(RunningTrayApps[i]); //trigger a repaint event + break; + } + } +} + +void LSession::WindowSelectionClearEvent(WId win){ + if(win==SystemTrayID){ + qDebug() << "Stopping system tray"; + stopSystemTray(true); //make sure to detach all windows + } +} + + //====================== // SYSTEM TRAY FUNCTIONS //====================== @@ -422,7 +484,9 @@ void LSession::startSystemTray(){ if(SystemTrayID!=0){ XSelectInput(QX11Info::display(), SystemTrayID, InputOutput); //make sure TrayID events get forwarded here XDamageQueryExtension( QX11Info::display(), &TrayDmgEvent, &TrayDmgError); + evFilter->setTrayDamageFlag(TrayDmgEvent); qDebug() << "System Tray Started Successfully"; + if(DEBUG){ qDebug() << " - System Tray Flags:" << TrayDmgEvent << TrayDmgError; } } } @@ -445,6 +509,7 @@ void LSession::attachTrayWindow(WId win){ if(TrayStopping){ return; } if(RunningTrayApps.contains(win)){ return; } //already managed RunningTrayApps << win; + if(DEBUG){ qDebug() << "Tray List Changed"; } emit TrayListChanged(); /*//Now try to embed the window into the tray //(NOT USED - Breaks visuals due to X11 graphics constraints - need to do embed in a single visual tray instead) @@ -476,4 +541,4 @@ void LSession::removeTrayWindow(WId win){ break; } } -}
\ No newline at end of file +} diff --git a/lumina-desktop/LSession.h b/lumina-desktop/LSession.h index 1e773f74..68916a77 100644 --- a/lumina-desktop/LSession.h +++ b/lumina-desktop/LSession.h @@ -18,8 +18,7 @@ #include <QDesktopWidget> #include <QList> #include <QThread> -#include <Phonon/MediaObject> -#include <Phonon/AudioOutput> +#include <QMediaPlayer> #include <QThread> #include <QUrl> @@ -29,8 +28,8 @@ #include "SystemWindow.h" #include "LDesktop.h" #include "WMProcess.h" +//#include "LXcbEventFilter.h" -//LibLumina X11 class #include <LuminaX11.h> //SYSTEM TRAY STANDARD DEFINITIONS @@ -54,7 +53,7 @@ public: //Functions to be called during startup void setupSession(); - virtual bool x11EventFilter(XEvent *event); + //virtual bool x11EventFilter(XEvent *event); bool LoadLocale(QString); @@ -63,6 +62,15 @@ public: bool registerVisualTray(WId); void unregisterVisualTray(WId); + //Special functions for XCB event filter parsing only + // (DO NOT USE MANUALLY) + void WindowPropertyEvent(); + void SysTrayDockRequest(WId); + void WindowClosedEvent(WId); + void WindowConfigureEvent(WId); + void WindowDamageEvent(WId); + void WindowSelectionClearEvent(WId); + //System Access //Return a pointer to the current session static LSession* handle(){ @@ -74,7 +82,8 @@ public: AppMenu* applicationMenu(); void systemWindow(); SettingsMenu* settingsMenu(); - + LXCB *XCB; //class for XCB usage + QSettings* sessionSettings(); //Play System Audio @@ -84,13 +93,12 @@ private: WMProcess *WM; QList<LDesktop*> DESKTOPS; QFileSystemWatcher *watcher; - + //XCBEventFilter *evFilter; //Internal variable for global usage AppMenu *appmenu; SettingsMenu *settingsmenu; QTranslator *currTranslator; - Phonon::MediaObject *mediaObj; - Phonon::AudioOutput *audioOut; + QMediaPlayer *mediaObj; QThread *audioThread; QSettings *sessionsettings; diff --git a/lumina-desktop/LWinInfo.h b/lumina-desktop/LWinInfo.h index 750ab508..ae67499b 100644 --- a/lumina-desktop/LWinInfo.h +++ b/lumina-desktop/LWinInfo.h @@ -19,6 +19,7 @@ // Local includes #include "Globals.h" //For the STATES enumeration definition +//#include "LSession.h" class LWinInfo{ diff --git a/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp b/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp index ae52378f..d3e1e10d 100644 --- a/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp +++ b/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp @@ -11,7 +11,7 @@ NotePadPlugin::NotePadPlugin(QWidget* parent, QString ID) : LDPlugin(parent, ID) vlay->setContentsMargins(3,3,3,3); frame = new QFrame(this); frame->setObjectName("notepadbase"); - frame->setStyleSheet("QFrame#notepadbase{border-size: 1px; background: rgba(255,255,255,50); color: black;} QFrame{ border: none; border-radius: 3px; background: rgba(255,255,255,100); color: black;}"); + frame->setStyleSheet("QFrame#notepadbase{border-width: 1px; background: rgba(255,255,255,50); color: black;} QFrame{ border: none; border-radius: 3px; background: rgba(255,255,255,100); color: black;}"); this->layout()->addWidget(frame); frame->setLayout(vlay); diff --git a/lumina-desktop/lumina-desktop.pro b/lumina-desktop/lumina-desktop.pro index 8772b661..02581bdc 100644 --- a/lumina-desktop/lumina-desktop.pro +++ b/lumina-desktop/lumina-desktop.pro @@ -1,5 +1,6 @@ -QT += core gui network phonon +QT += core gui network +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras multimedia TARGET = Lumina-DE isEmpty(PREFIX) { @@ -7,7 +8,7 @@ isEmpty(PREFIX) { } target.path = $$PREFIX/bin -LIBS += -L../libLumina -lLuminaUtils -lXdamage -lX11 +LIBS += -L../libLumina -lLuminaUtils -lXdamage -lX11 -lxcb -lxcb-damage QMAKE_LIBDIR = ../libLumina DEPENDPATH += ../libLumina @@ -16,7 +17,7 @@ TEMPLATE = app openbsd-g++4 { LRELEASE = lrelease4 } else { - LRELEASE = lrelease-qt4 + LRELEASE = /usr/local/lib/qt5/bin/lrelease } SOURCES += main.cpp \ @@ -47,6 +48,7 @@ SOURCES += main.cpp \ HEADERS += Globals.h \ WMProcess.h \ + LXcbEventFilter.h \ LSession.h \ LDesktop.h \ LPanel.h \ diff --git a/lumina-desktop/main.cpp b/lumina-desktop/main.cpp index 884e9441..8305be60 100644 --- a/lumina-desktop/main.cpp +++ b/lumina-desktop/main.cpp @@ -23,10 +23,10 @@ #include <LuminaThemes.h> #include <LuminaOS.h> -#define DEBUG 0 +#define DEBUG 1 QFile logfile(QDir::homePath()+"/.lumina/logs/runtime.log"); -void MessageOutput(QtMsgType type, const char *msg){ +void MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg){ QString txt; switch(type){ case QtDebugMsg: @@ -76,7 +76,7 @@ int main(int argc, char ** argv) if(DEBUG){ qDebug() << "Theme Init:" << timer->elapsed(); } LuminaThemeEngine theme(&a); //Setup Log File - qInstallMsgHandler(MessageOutput); + qInstallMessageHandler(MessageOutput); if(DEBUG){ qDebug() << "Session Setup:" << timer->elapsed(); } a.setupSession(); if(DEBUG){ qDebug() << "Load Locale:" << timer->elapsed(); } diff --git a/lumina-desktop/panel-plugins/LPPlugin.h b/lumina-desktop/panel-plugins/LPPlugin.h index ae4e7fbc..c8347a8e 100644 --- a/lumina-desktop/panel-plugins/LPPlugin.h +++ b/lumina-desktop/panel-plugins/LPPlugin.h @@ -28,6 +28,7 @@ public: plugintype=ptype; this->setContentsMargins(0,0,0,0); this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + this->setFocusPolicy(Qt::NoFocus); //no keyboard focus on the panel/plugins if(horizontal){LY = new QBoxLayout(QBoxLayout::LeftToRight, this); } else{ LY = new QBoxLayout(QBoxLayout::TopToBottom, this); } LY->setContentsMargins(0,0,0,0); diff --git a/lumina-desktop/panel-plugins/LTBWidget.h b/lumina-desktop/panel-plugins/LTBWidget.h index 5252c619..7ca46d0d 100644 --- a/lumina-desktop/panel-plugins/LTBWidget.h +++ b/lumina-desktop/panel-plugins/LTBWidget.h @@ -12,20 +12,21 @@ #include <QWheelEvent> #include "Globals.h" +#include <LuminaX11.h> class LTBWidget : public QToolButton{ Q_OBJECT private: - Lumina::STATES cstate; + LXCB::WINDOWSTATE cstate; QString rawstyle; void updateBackground(){ QString background = "background: transparent; "; //default value QString border = "border: 1px solid transparent;"; - if(cstate == Lumina::NONE){ } //just use the defaults - else if(cstate == Lumina::VISIBLE){ background = "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(255, 255, 255, 240), stop:0.505682 rgba(240, 240, 240, 150), stop:1 rgba(210, 210, 210, 55));"; border="border: 1px solid transparent;"; } - else if(cstate == Lumina::INVISIBLE){background = "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(215, 215, 215, 240), stop:0.505682 rgba(184, 185, 186, 150), stop:1 rgba(221, 246, 255, 55));"; border="border: 1px solid transparent;"; } - else if(cstate == Lumina::ACTIVE){ background= "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(241, 233, 156, 240), stop:0.355682 rgba(255, 243, 127, 150), stop:1 rgba(221, 246, 255, 55));"; border ="border: 1px solid transparent;"; } - else if(cstate == Lumina::NOTIFICATION){ background= "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(252, 187, 127, 240), stop:0.505682 rgba(255, 222, 197, 150), stop:1 rgba(221, 246, 255, 55));"; border="border: 1px solid transparent;"; } + if(cstate == LXCB::IGNORE){ } //just use the defaults + else if(cstate == LXCB::VISIBLE){ background = "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(255, 255, 255, 240), stop:0.505682 rgba(240, 240, 240, 150), stop:1 rgba(210, 210, 210, 55));"; border="border: 1px solid transparent;"; } + else if(cstate == LXCB::INVISIBLE){background = "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(215, 215, 215, 240), stop:0.505682 rgba(184, 185, 186, 150), stop:1 rgba(221, 246, 255, 55));"; border="border: 1px solid transparent;"; } + else if(cstate == LXCB::ACTIVE){ background= "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(241, 233, 156, 240), stop:0.355682 rgba(255, 243, 127, 150), stop:1 rgba(221, 246, 255, 55));"; border ="border: 1px solid transparent;"; } + else if(cstate == LXCB::ATTENTION){ background= "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(252, 187, 127, 240), stop:0.505682 rgba(255, 222, 197, 150), stop:1 rgba(221, 246, 255, 55));"; border="border: 1px solid transparent;"; } QString raw = rawstyle; this->setStyleSheet( raw.replace("%1",background).replace("%2", border) ); } @@ -37,7 +38,7 @@ signals: public: LTBWidget(QWidget* parent) : QToolButton(parent){ //this->setStyleSheet( this->styleSheet()+" LTBWidget::menu-indicator{image: none;}"); - cstate = Lumina::NONE; + cstate = LXCB::IGNORE; this->setPopupMode(QToolButton::InstantPopup); this->setAutoRaise(true); @@ -48,7 +49,7 @@ public: ~LTBWidget(){ } - void setState(Lumina::STATES newstate){ + void setState(LXCB::WINDOWSTATE newstate){ cstate = newstate; updateBackground(); } diff --git a/lumina-desktop/panel-plugins/systemtray/LSysTray.cpp b/lumina-desktop/panel-plugins/systemtray/LSysTray.cpp index dacb7b55..1eafffee 100644 --- a/lumina-desktop/panel-plugins/systemtray/LSysTray.cpp +++ b/lumina-desktop/panel-plugins/systemtray/LSysTray.cpp @@ -53,7 +53,7 @@ void LSysTray::start(){ isRunning = LSession::handle()->registerVisualTray(this->winId()); qDebug() << "Visual Tray Started:" << this->type() << isRunning; if(isRunning){ - upTimer->start(); + //upTimer->start(); QTimer::singleShot(0,this, SLOT(checkAll()) ); } //Make sure we catch all events right away @@ -169,6 +169,7 @@ void LSysTray::checkAll(){ if(!isRunning || stopping || checking){ return; } //Don't check if not running at the moment checking = true; //qDebug() << "System Tray: Check tray apps"; + bool listChanged = false; QList<WId> wins = LSession::handle()->currentTrayApps(this->winId()); for(int i=0; i<trayIcons.length(); i++){ int index = wins.indexOf(trayIcons[i]->appID()); @@ -179,6 +180,7 @@ void LSysTray::checkAll(){ LI->removeWidget(cont); delete cont; i--; //List size changed + listChanged = true; //Re-adjust the maximum widget size to account for what is left if(this->layout()->direction()==QBoxLayout::LeftToRight){ this->setMaximumSize( trayIcons.length()*this->height(), 10000); @@ -217,9 +219,17 @@ void LSysTray::checkAll(){ LI->removeWidget(cont); delete cont; continue; - } + }else{ + listChanged = true; + } LI->update(); //make sure there is no blank space in the layout } + /*if(listChanged){ + //Icons got moved around: be sure to re-draw all of them to fix visuals + for(int i=0; i<trayIcons.length(); i++){ + trayIcons[i]->update(); + } + }*/ //qDebug() << " - System Tray: check done"; checking = false; } diff --git a/lumina-desktop/panel-plugins/systemtray/LSysTray.h b/lumina-desktop/panel-plugins/systemtray/LSysTray.h index f45a52ad..1b482ef7 100644 --- a/lumina-desktop/panel-plugins/systemtray/LSysTray.h +++ b/lumina-desktop/panel-plugins/systemtray/LSysTray.h @@ -12,7 +12,7 @@ #include <QHBoxLayout> #include <QDebug> #include <QX11Info> -#include <QX11EmbedContainer> +//#include <QX11EmbedContainer> #include <QCoreApplication> //Local includes diff --git a/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp index 64c7c77d..716a49ed 100644 --- a/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp +++ b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp @@ -6,11 +6,13 @@ //=========================================== #include "TrayIcon.h" -#include <X11/Xlib.h> -#include <X11/Xutil.h> +//#include <X11/Xlib.h> +//#include <X11/Xutil.h> #include <X11/extensions/Xdamage.h> -static Damage dmgID = 0; +//#include <xcb/damage.h> +//static xcb_damage_damage_t dmgID; +static int dmgID = 0; TrayIcon::TrayIcon(QWidget *parent) : QWidget(parent){ AID = 0; //nothing yet @@ -36,10 +38,10 @@ void TrayIcon::attachApp(WId id){ if( LX11::EmbedWindow(AID, IID) ){ LX11::RestoreWindow(AID); //make it visible //XSelectInput(QX11Info::display(), AID, StructureNotifyMask); + //xcb_damage_create(QX11Info::connection(), dmgID, AID, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES); dmgID = XDamageCreate( QX11Info::display(), AID, XDamageReportRawRectangles ); - updateIcon(); qDebug() << "New System Tray App:" << AID; - QTimer::singleShot(500, this, SLOT(updateIcon()) ); + QTimer::singleShot(1000, this, SLOT(updateIcon()) ); }else{ qWarning() << "Could not Embed Tray Application:" << AID; //LX11::DestroyWindow(IID); @@ -64,9 +66,9 @@ void TrayIcon::detachApp(){ //Now detach the application window and clean up qDebug() << " - Unembed"; LX11::UnembedWindow(tmp); - if(dmgID!=0){ - XDamageDestroy(QX11Info::display(), dmgID); - } + //if(dmgID!=0){ + //XDamageDestroy(QX11Info::display(), dmgID); + //} qDebug() << " - finished app:" << tmp; //if(IID!=this->winId()){ LX11::DestroyWindow(IID); } IID = 0; @@ -98,6 +100,7 @@ void TrayIcon::updateIcon(){ //Make sure the icon is square QSize icosize = this->size(); LX11::ResizeWindow(AID, icosize.width(), icosize.height()); + QTimer::singleShot(500, this, SLOT(update()) ); //make sure to re-draw the window in a moment } // ============= @@ -115,7 +118,7 @@ void TrayIcon::paintEvent(QPaintEvent *event){ QPixmap pix = LX11::WindowImage(AID, false); if(pix.isNull()){ //Try to grab the window directly with Qt - //qDebug() << " - - Grab window directly"; + qDebug() << " - - Grab window directly"; pix = QPixmap::grabWindow(AID); } //qDebug() << " - Pix size:" << pix.size().width() << pix.size().height(); @@ -138,6 +141,7 @@ void TrayIcon::resizeEvent(QResizeEvent *event){ //qDebug() << "Resize Event:" << event->size().width() << event->size().height(); if(AID!=0){ LX11::ResizeWindow(AID, event->size().width(), event->size().height()); + QTimer::singleShot(500, this, SLOT(update()) ); //make sure to re-draw the window in a moment } } diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp index 6ea7854e..9dfc0979 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp @@ -5,6 +5,7 @@ // See the LICENSE file for full details //=========================================== #include "LTaskButton.h" +#include "LSession.h" LTaskButton::LTaskButton(QWidget *parent) : LTBWidget(parent){ actMenu = new QMenu(this); @@ -71,7 +72,7 @@ void LTaskButton::UpdateButton(){ LWINLIST = WINLIST; winMenu->clear(); - Lumina::STATES showstate = Lumina::NOSHOW; + LXCB::WINDOWSTATE showstate = LXCB::IGNORE; for(int i=0; i<WINLIST.length(); i++){ if(WINLIST[i].windowID() == 0){ WINLIST.removeAt(i); @@ -88,31 +89,19 @@ void LTaskButton::UpdateButton(){ if(cname.contains(" - ")){ cname = cname.section(" - ",-1); } } this->setToolTip(cname); - /* - if(this->icon().isNull()){ - this->setIcon( LXDG::findIcon(cname.toLower(),"") ); - if(this->icon().isNull()){ - this->setIcon( LXDG::findIcon("preferences-system-windows","") ); - noicon=true; - }else{ - noicon = false; - } - }else{ - noicon = false; - }*/ } bool junk; QAction *tmp = winMenu->addAction( WINLIST[i].icon(junk), WINLIST[i].text() ); tmp->setData(i); //save which number in the WINLIST this entry is for - Lumina::STATES stat = WINLIST[i].status(); - if(stat==Lumina::NOTIFICATION){ showstate = stat; } //highest priority - else if( stat==Lumina::ACTIVE && showstate != Lumina::NOTIFICATION){ showstate = stat; } //next priority - else if( stat==Lumina::Lumina::VISIBLE && showstate != Lumina::NOTIFICATION && showstate != Lumina::ACTIVE){ showstate = stat; } - else if(showstate == Lumina::INVISIBLE || showstate == Lumina::NOSHOW){ showstate = stat; } //anything is the same/better + LXCB::WINDOWSTATE stat = LSession::handle()->XCB->WindowState(WINLIST[i].windowID()); + if(stat==LXCB::ATTENTION){ showstate = stat; } //highest priority + else if( stat==LXCB::ACTIVE && showstate != LXCB::ATTENTION){ showstate = stat; } //next priority + else if( stat==LXCB::VISIBLE && showstate != LXCB::ATTENTION && showstate != LXCB::ACTIVE){ showstate = stat; } + else if(showstate == LXCB::INVISIBLE || showstate == LXCB::IGNORE){ showstate = stat; } //anything is the same/better } //Now setup the button appropriately // - visibility - if(showstate == Lumina::NOSHOW || WINLIST.length() < 1){ this->setVisible(false); } + if(showstate == LXCB::IGNORE || WINLIST.length() < 1){ this->setVisible(false); } else{ this->setVisible(true); } // - functionality if(WINLIST.length() == 1){ diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp index 674c9088..8f131c9e 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp @@ -31,7 +31,7 @@ void LTaskManagerPlugin::UpdateButtons(){ //Make sure this only runs one at a time updating=true; //Get the current window list - QList<WId> winlist = LX11::WindowList(); + QList<WId> winlist = LSession::handle()->XCB->WindowList(); //qDebug() << "Update Buttons:" << winlist; //Now go through all the current buttons first for(int i=0; i<BUTTONS.length(); i++){ diff --git a/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp b/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp index 7a1983d2..9bfbbb8d 100644 --- a/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp +++ b/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp @@ -13,24 +13,24 @@ UserItemWidget::UserItemWidget(QWidget *parent, QString itemPath, bool isDir, bo bool ok = false; XDGDesktop item = LXDG::loadDesktopFile(itemPath, ok); if(ok){ - icon->setPixmap( LXDG::findIcon(item.icon, "preferences-system-windows-actions").pixmap(30,30) ); + icon->setPixmap( LXDG::findIcon(item.icon, "preferences-system-windows-actions").pixmap(32,32) ); name->setText( this->fontMetrics().elidedText(item.name, Qt::ElideRight, 180) ); }else{ - icon->setPixmap( LXDG::findIcon("unknown","").pixmap(30,30) ); + icon->setPixmap( LXDG::findIcon("unknown","").pixmap(32,32) ); name->setText( this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, 180) ); } }else if(isDir){ if(itemPath.endsWith("/")){ itemPath.chop(1); } if(goback){ - icon->setPixmap( LXDG::findIcon("go-previous","").pixmap(30,30) ); + icon->setPixmap( LXDG::findIcon("go-previous","").pixmap(32,32) ); name->setText( tr("Go Back") ); }else{ - icon->setPixmap( LXDG::findIcon("folder","").pixmap(30,30) ); + icon->setPixmap( LXDG::findIcon("folder","").pixmap(32,32) ); name->setText( this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, 180) ); } }else{ if(itemPath.endsWith("/")){ itemPath.chop(1); } - icon->setPixmap( LXDG::findMimeIcon(itemPath.section("/",-1).section(".",-1)).pixmap(30,30) ); + icon->setPixmap( LXDG::findMimeIcon(itemPath.section("/",-1).section(".",-1)).pixmap(32,32) ); name->setText( this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, 180) ); } linkPath = QFile::symLinkTarget(itemPath); @@ -48,7 +48,7 @@ UserItemWidget::UserItemWidget(QWidget *parent, XDGDesktop item) : QFrame(parent linkPath = QFile::symLinkTarget(item.filePath); isShortcut = item.filePath.contains("/home/") && (item.filePath.contains("/Desktop/") || item.filePath.contains("/.lumina/favorites/") ); //Now fill it appropriately - icon->setPixmap( LXDG::findIcon(item.icon,"preferences-system-windows-actions").pixmap(30,30) ); + icon->setPixmap( LXDG::findIcon(item.icon,"preferences-system-windows-actions").pixmap(32,32) ); name->setText( this->fontMetrics().elidedText(item.name, Qt::ElideRight, 180) ); icon->setWhatsThis(item.filePath); //Now setup the button appropriately @@ -70,7 +70,7 @@ void UserItemWidget::createWidget(){ button->setIconSize( QSize(14,14) ); button->setAutoRaise(true); icon = new QLabel(this); - icon->setFixedSize( QSize(30,30) ); + icon->setFixedSize( QSize(34,34) ); name = new QLabel(this); //Add them to the layout this->setLayout(new QHBoxLayout()); diff --git a/lumina-fm/BackgroundWorker.cpp b/lumina-fm/BackgroundWorker.cpp index 1e6ef28d..9b3804d5 100644 --- a/lumina-fm/BackgroundWorker.cpp +++ b/lumina-fm/BackgroundWorker.cpp @@ -1,7 +1,7 @@ #include "BackgroundWorker.h" #include <LuminaXDG.h> -#include <Phonon/BackendCapabilities> +#include <QMediaServiceSupportedFormatsInterface> #include <QImageReader> BackgroundWorker::BackgroundWorker() : QObject(){ @@ -26,12 +26,9 @@ void BackgroundWorker::startDirChecks(QString path){ //Now check for multimedia files if(multiFilter.isEmpty()){ - //Initial Run - load supported multimedia extensions - QStringList mimes = Phonon::BackendCapabilities::availableMimeTypes(); - mimes = mimes.filter("audio/") + mimes.filter("video/"); - for(int i=0; i<mimes.length(); i++){ - multiFilter << LXDG::findFilesForMime(mimes[i]); - } + //Initial Run - load supported multimedia extensions + // (Auto-detection of supported types broken in Qt5 - just use everythings for now) + multiFilter = LXDG::findAVFileExtensions(); multiFilter.removeDuplicates(); qDebug() << "Supported Multimedia Formats:" << multiFilter; } diff --git a/lumina-fm/MainUI.cpp b/lumina-fm/MainUI.cpp index 6b369e9b..03e7a533 100644 --- a/lumina-fm/MainUI.cpp +++ b/lumina-fm/MainUI.cpp @@ -65,20 +65,20 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ ui->menuView->addAction(listWA); ui->menuView->addAction(icoWA); //Setup the special Phonon widgets - mediaObj = new Phonon::MediaObject(this); - mediaObj->setTickInterval(200); //1/5 second ticks for updates - videoDisplay = new Phonon::VideoWidget(this); + mediaObj = new QMediaPlayer(this); + mediaObj->setVolume(100); + mediaObj->setNotifyInterval(500); //only every 1/2 second update + videoDisplay = new QVideoWidget(this); videoDisplay->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); ui->videoLayout->addWidget(videoDisplay); - Phonon::createPath(mediaObj, videoDisplay); + mediaObj->setVideoOutput(videoDisplay); videoDisplay->setVisible(false); - audioOut = new Phonon::AudioOutput(Phonon::VideoCategory, this); - Phonon::createPath(mediaObj, audioOut); - playerSlider = new Phonon::SeekSlider(this); - playerSlider->setMediaObject(mediaObj); + playerSlider = new QSlider(this); + playerSlider->setOrientation(Qt::Horizontal); ui->videoControlLayout->insertWidget(4, playerSlider); ui->tool_player_stop->setEnabled(false); //nothing to stop yet ui->tool_player_pause->setVisible(false); //nothing to pause yet + playerSlider->setEnabled(false); //nothing to seek yet //Setup any specialty keyboard shortcuts nextTabLShort = new QShortcut( QKeySequence(tr("Shift+Left")), this); nextTabRShort = new QShortcut( QKeySequence(tr("Shift+Right")), this); @@ -232,10 +232,16 @@ void MainUI::setupConnections(){ connect(ui->tool_player_play, SIGNAL(clicked()), this, SLOT(playerStart())); connect(ui->tool_player_stop, SIGNAL(clicked()), this, SLOT(playerStop())); connect(ui->combo_player_list, SIGNAL(currentIndexChanged(int)), this, SLOT(playerFileChanged()) ); - connect(mediaObj, SIGNAL(finished()), this, SLOT(playerFinished()) ); - connect(mediaObj, SIGNAL(tick(qint64)), this, SLOT(playerTimeChanged(qint64)) ); - connect(mediaObj, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(playerStateChanged(Phonon::State, Phonon::State)) ); - connect(mediaObj, SIGNAL(hasVideoChanged(bool)), this, SLOT(playerVideoAvailable(bool)) ); + connect(playerSlider, SIGNAL(sliderPressed()), this, SLOT(playerSliderHeld()) ); + connect(playerSlider, SIGNAL(sliderReleased()), this, SLOT(playerSliderChanged()) ); + connect(playerSlider, SIGNAL(valueChanged(int)), this, SLOT(playerSliderMoved(int)) ); + connect(mediaObj, SIGNAL(durationChanged(qint64)), this, SLOT(playerDurationChanged(qint64)) ); + connect(mediaObj, SIGNAL(seekableChanged(bool)), playerSlider, SLOT(setEnabled(bool)) ); + connect(mediaObj, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(playerStatusChanged(QMediaPlayer::MediaStatus)) ); + connect(mediaObj, SIGNAL(positionChanged(qint64)), this, SLOT(playerTimeChanged(qint64)) ); + connect(mediaObj, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(playerStateChanged(QMediaPlayer::State)) ); + connect(mediaObj, SIGNAL(videoAvailableChanged(bool)), this, SLOT(playerVideoAvailable(bool)) ); + connect(mediaObj, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(playerError()) ); //Special Keyboard Shortcuts connect(nextTabLShort, SIGNAL(activated()), this, SLOT( prevTab() ) ); connect(nextTabRShort, SIGNAL(activated()), this, SLOT( nextTab() ) ); @@ -391,7 +397,7 @@ void MainUI::setCurrentDir(QString dir){ ui->tool_goToPlayer->setVisible(false); ui->tool_goToRestore->setVisible(false); ui->tool_goToImages->setVisible(false); - if(olddir==rawdir){ + if(olddir!=rawdir){ emit DirChanged(rawdir); //This will be automatically run when a new dir is loaded } if(isUserWritable){ ui->label_dir_stats->setText(""); } @@ -937,24 +943,29 @@ void MainUI::restoreItems(){ void MainUI::playerStart(){ if(ui->stackedWidget->currentWidget()!=ui->page_audioPlayer){ return; } //don't play if not in the player - if(mediaObj->state()==Phonon::PausedState){ + if(mediaObj->state()==QMediaPlayer::PausedState \ + && mediaObj->currentMedia().canonicalUrl().fileName()==ui->combo_player_list->currentText() ){ mediaObj->play(); - }else{ // if(mediaObj->state()==Phonon::StoppedState || mediaObj->state()==Phonon::ErrorState || (playerFile->fileName().section("/",-1) != ui->combo_player_list->currentText()) || playerFile->isOpen() ){ + }else{ mediaObj->stop(); //Get the selected file path QString filePath = getCurrentDir(); if(!filePath.endsWith("/")){ filePath.append("/"); } filePath.append( ui->combo_player_list->currentText() ); - //if(playerFile->isOpen()){ playerFile->close(); } - //playerFile->setFileName(filePath); - //if(playerFile->open(QIODevice::ReadOnly)){ - mediaObj->setCurrentSource( QUrl(filePath) ); - playerSlider->setMediaObject(mediaObj); + mediaObj->setMedia( QUrl::fromLocalFile(filePath) ); + playerTTime.clear(); + playerSlider->setEnabled(mediaObj->isSeekable()); mediaObj->play(); - //} } } +void MainUI::playerError(){ + QString msg = QString(tr("Error Playing File: %1")); + msg = msg.arg( mediaObj->currentMedia().canonicalUrl().fileName() ); + msg.append("\n"+mediaObj->errorString()); + ui->label_player_novideo->setText(msg); +} + void MainUI::playerStop(){ mediaObj->stop(); } @@ -965,51 +976,48 @@ void MainUI::playerPause(){ void MainUI::playerNext(){ ui->combo_player_list->setCurrentIndex( ui->combo_player_list->currentIndex()+1); + if(mediaObj->state()!=QMediaPlayer::StoppedState){ playerStart(); } } void MainUI::playerPrevious(){ ui->combo_player_list->setCurrentIndex( ui->combo_player_list->currentIndex()-1); + if(mediaObj->state()!=QMediaPlayer::StoppedState){ playerStart(); } } void MainUI::playerFinished(){ - //playerFile->close(); if(ui->combo_player_list->currentIndex()<(ui->combo_player_list->count()-1) && ui->check_player_gotonext->isChecked()){ ui->combo_player_list->setCurrentIndex( ui->combo_player_list->currentIndex()+1 ); + QTimer::singleShot(0,this,SLOT(playerStart())); }else{ ui->label_player_novideo->setText(tr("Finished")); } } -void MainUI::playerStateChanged(Phonon::State newstate, Phonon::State oldstate){ +void MainUI::playerStatusChanged(QMediaPlayer::MediaStatus stat){ + //Only use this for end-of-file detection - use the state detection otherwise + if(stat == QMediaPlayer::EndOfMedia){ + if(!mediaObj->isMuted()){ playerFinished(); } //make sure it is not being seeked right now + } +} + +void MainUI::playerStateChanged(QMediaPlayer::State newstate){ //This function keeps track of updating the visuals of the player bool running = false; bool showVideo = false; QString msg; switch(newstate){ - case Phonon::LoadingState: + case QMediaPlayer::PlayingState: running=true; - ui->label_player_novideo->setText(tr("Loading File...")); - break; - case Phonon::PlayingState: - running=true; - showVideo = mediaObj->hasVideo(); - msg = mediaObj->metaData(Phonon::TitleMetaData).join(" "); + showVideo = mediaObj->isVideoAvailable(); + msg = "";//mediaObj->metaData(Phonon::TitleMetaData).join(" "); if(msg.simplified().isEmpty()){ msg = ui->combo_player_list->currentText(); } ui->label_player_novideo->setText(tr("Playing:")+"\n"+msg); break; - case Phonon::BufferingState: - running=true; - showVideo=true; //don't blank the screen - break; - case Phonon::PausedState: + case QMediaPlayer::PausedState: showVideo=videoDisplay->isVisible(); //don't change the screen break; - case Phonon::StoppedState: - if(oldstate==Phonon::LoadingState){ mediaObj->play(); } - else{ ui->label_player_novideo->setText(tr("Stopped")); } - break; - case Phonon::ErrorState: - ui->label_player_novideo->setText(tr("Error Playing File")+"\n("+mediaObj->errorString()+")"); + case QMediaPlayer::StoppedState: + ui->label_player_novideo->setText(tr("Stopped")); break; } ui->tool_player_play->setVisible(!running); @@ -1024,20 +1032,34 @@ void MainUI::playerVideoAvailable(bool showVideo){ videoDisplay->setVisible(showVideo); } +void MainUI::playerDurationChanged(qint64 dur){ + if(dur < 0){ return; } //not ready yet + playerSlider->setMaximum(mediaObj->duration()); + playerTTime = msToText(dur); +} + void MainUI::playerTimeChanged(qint64 ctime){ - if(playerTTime=="0:00" || playerTTime.isEmpty()){ playerTTime = msToText(mediaObj->totalTime()); } //only calculate as necessary - //qDebug() << "Time:" << msToText(ctime) << playerTTime << mediaObj->isSeekable() << mediaObj->hasVideo(); - ui->label_player_runstats->setText( msToText(ctime)+"/"+playerTTime ); + if(mediaObj->isMuted() || playerTTime.isEmpty() ){ return; } //currently being moved + playerSlider->setSliderPosition(ctime); +} + +void MainUI::playerSliderMoved(int val){ + ui->label_player_runstats->setText( msToText(val)+"/"+playerTTime ); + if(mediaObj->isMuted()){ mediaObj->setPosition(playerSlider->value()); } //currently seeking +} + +void MainUI::playerSliderHeld(){ + mediaObj->setMuted(true); + mediaObj->pause(); +} +void MainUI::playerSliderChanged(){ + if(mediaObj->state()==QMediaPlayer::PausedState){ mediaObj->play(); } + mediaObj->setMuted(false); } void MainUI::playerFileChanged(){ ui->tool_player_next->setEnabled( ui->combo_player_list->count() > (ui->combo_player_list->currentIndex()+1) ); ui->tool_player_prev->setEnabled( (ui->combo_player_list->currentIndex()-1) >= 0 ); - if(ui->stackedWidget->currentWidget()!=ui->page_audioPlayer){ return; } //don't play if not in the player - //If one is playing, so ahead and start playing the new selection - if(ui->check_player_gotonext->isChecked() ){ - QTimer::singleShot(0,this,SLOT(playerStart())); - } } //---------------------------------- diff --git a/lumina-fm/MainUI.h b/lumina-fm/MainUI.h index 87a52668..1cc26830 100644 --- a/lumina-fm/MainUI.h +++ b/lumina-fm/MainUI.h @@ -40,13 +40,9 @@ #include <QUrl> #include <QThread> -//Phonon widgets -//#include <Phonon/BackendCapabilities> -#include <Phonon/MediaObject> -#include <Phonon/VideoWidget> -#include <Phonon/AudioOutput> -#include <Phonon/SeekSlider> -#include <Phonon/MediaSource> +//Multimedia Widgets +#include <QVideoWidget> +#include <QMediaPlayer> // libLumina includes #include <LuminaXDG.h> @@ -89,10 +85,10 @@ private: QString favdir; //Phonon Widgets for the multimedia player - Phonon::MediaObject *mediaObj; - Phonon::VideoWidget *videoDisplay; - Phonon::AudioOutput *audioOut; - Phonon::SeekSlider *playerSlider; + QMediaPlayer *mediaObj; + QVideoWidget *videoDisplay; + //Phonon::AudioOutput *audioOut; + QSlider *playerSlider; QString playerTTime; //total time - to prevent recalculation every tick //Internal variables @@ -184,14 +180,20 @@ private slots: //Multimedia Player Functions void playerStart(); + void playerError(); void playerStop(); void playerPause(); void playerNext(); void playerPrevious(); void playerFinished(); //automatically called by the media object - void playerStateChanged(Phonon::State newstate, Phonon::State oldstate); //automatically called by the media object + void playerStatusChanged(QMediaPlayer::MediaStatus stat); //automatically called + void playerStateChanged(QMediaPlayer::State newstate); //automatically called by the media object void playerVideoAvailable(bool showVideo); //automatically called by the media object + void playerDurationChanged(qint64); void playerTimeChanged(qint64 ctime); //automatically called by the media object + void playerSliderMoved(int); + void playerSliderHeld(); + void playerSliderChanged(); void playerFileChanged(); //Context Menu Actions diff --git a/lumina-fm/lumina-fm.pro b/lumina-fm/lumina-fm.pro index cc9ad275..d0fb713b 100644 --- a/lumina-fm/lumina-fm.pro +++ b/lumina-fm/lumina-fm.pro @@ -1,5 +1,6 @@ -QT += core gui phonon +QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets multimedia multimediawidgets TARGET = lumina-fm isEmpty(PREFIX) { @@ -30,14 +31,14 @@ FORMS += MainUI.ui \ INCLUDEPATH += ../libLumina $$PREFIX/include LIBS += -L../libLumina -lLuminaUtils -freebsd-* { +/*freebsd-* { LIBS += -lQtSolutions_SingleApplication-head -} +}*/ openbsd-g++4 { LRELEASE = lrelease4 } else { - LRELEASE = lrelease-qt4 + LRELEASE = $$PREFIX/lib/qt5/bin/lrelease } QMAKE_LIBDIR = ../libLumina diff --git a/lumina-fm/main.cpp b/lumina-fm/main.cpp index e2f70bc1..760ca7ad 100644 --- a/lumina-fm/main.cpp +++ b/lumina-fm/main.cpp @@ -1,11 +1,12 @@ #include <QTranslator> -#ifdef __FreeBSD__ +/*#ifdef __FreeBSD__ #include <qtsingleapplication.h> -#endif -#include <QtGui/QApplication> +#endif*/ +#include <QApplication> #include <QDebug> #include <QFile> -#include <QTextCodec> +#include <QStringList> +//#include <QTextCodec> #include "MainUI.h" #include <LuminaOS.h> @@ -25,32 +26,32 @@ int main(int argc, char ** argv) } } if(in.isEmpty()){ in << QDir::homePath(); } - #ifdef __FreeBSD__ + /*#ifdef __FreeBSD__ QtSingleApplication a(argc, argv); if( a.isRunning() ){ return !(a.sendMessage(in.join("\n"))); } - #else + #else*/ QApplication a(argc, argv); - #endif + qDebug() << "Loaded QApplication"; + //#endif a.setApplicationName("Insight File Manager"); LuminaThemeEngine themes(&a); //Load current Locale QTranslator translator; QLocale mylocale; QString langCode = mylocale.name(); - if ( ! QFile::exists(LOS::LuminaShare()+"i18n/lumina-fm_" + langCode + ".qm" ) ) langCode.truncate(langCode.indexOf("_")); translator.load( QString("lumina-fm_") + langCode, LOS::LuminaShare()+"i18n/" ); a.installTranslator( &translator ); qDebug() << "Locale:" << langCode; //Load current encoding for this locale - QTextCodec::setCodecForTr( QTextCodec::codecForLocale() ); //make sure to use the same codec - qDebug() << "Locale Encoding:" << QTextCodec::codecForLocale()->name(); + //QTextCodec::setCodecForTr( QTextCodec::codecForLocale() ); //make sure to use the same codec + //qDebug() << "Locale Encoding:" << QTextCodec::codecForLocale()->name(); MainUI w; - QObject::connect(&a, SIGNAL(messageReceived(const QString&)), &w, SLOT(slotSingleInstance(const QString&)) ); + //QObject::connect(&a, SIGNAL(messageReceived(const QString&)), &w, SLOT(slotSingleInstance(const QString&)) ); QObject::connect(&themes, SIGNAL(updateIcons()), &w, SLOT(setupIcons()) ); w.OpenDirs(in); w.show(); diff --git a/lumina-open/LFileDialog.h b/lumina-open/LFileDialog.h index 27f038d6..eaed3625 100644 --- a/lumina-open/LFileDialog.h +++ b/lumina-open/LFileDialog.h @@ -19,6 +19,7 @@ #include <QSettings> #include <QTextStream> #include <QTreeWidgetItem> +#include <QAction> #include <LuminaXDG.h> //From libLuminaUtils #include <LuminaUtils.h> diff --git a/lumina-open/lumina-open.pro b/lumina-open/lumina-open.pro index b70d6b27..ce0e231d 100644 --- a/lumina-open/lumina-open.pro +++ b/lumina-open/lumina-open.pro @@ -1,5 +1,6 @@ QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras TARGET = lumina-open isEmpty(PREFIX) { diff --git a/lumina-open/main.cpp b/lumina-open/main.cpp index 4fcf70b7..a92a585f 100644 --- a/lumina-open/main.cpp +++ b/lumina-open/main.cpp @@ -125,8 +125,8 @@ QString cmdFromUser(int argc, char **argv, QString inFile, QString extension, QS qDebug() << "Locale:" << langCode; //Load current encoding for this locale - QTextCodec::setCodecForTr( QTextCodec::codecForLocale() ); //make sure to use the same codec - qDebug() << "Locale Encoding:" << QTextCodec::codecForLocale()->name(); + //QTextCodec::setCodecForTr( QTextCodec::codecForLocale() ); //make sure to use the same codec + //qDebug() << "Locale Encoding:" << QTextCodec::codecForLocale()->name(); LFileDialog w; if(inFile.startsWith(extension)){ diff --git a/lumina-screenshot/MainUI.cpp b/lumina-screenshot/MainUI.cpp index 5ff698bd..9abe93a2 100644 --- a/lumina-screenshot/MainUI.cpp +++ b/lumina-screenshot/MainUI.cpp @@ -11,7 +11,7 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ ui->setupUi(this); //load the designer file - cpic = QPixmap::grabWindow(QApplication::desktop()->winId()); //initial screenshot + cpic = QApplication::screens().at(0)->grabWindow(QApplication::desktop()->winId()); //initial screenshot ppath = QDir::homePath(); QWidget *spacer = new QWidget(); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -90,12 +90,13 @@ bool MainUI::getWindow(){ } void MainUI::getPixmap(){ + QScreen *scrn = QApplication::screens().at(0); if(cwin==0){ //Grab the whole screen - cpic = QPixmap::grabWindow(QApplication::desktop()->winId()); + cpic = scrn->grabWindow(QApplication::desktop()->winId()); }else{ //Grab just the designated window - cpic = QPixmap::grabWindow(cwin); + cpic = scrn->grabWindow(cwin); } this->show(); //Now display the pixmap on the label as well diff --git a/lumina-screenshot/MainUI.h b/lumina-screenshot/MainUI.h index c350f366..8c408131 100644 --- a/lumina-screenshot/MainUI.h +++ b/lumina-screenshot/MainUI.h @@ -16,6 +16,8 @@ #include <QDir> #include <QInputDialog> #include <QSettings> +#include <QAction> +#include <QScreen> #include <LuminaXDG.h> #include <LuminaUtils.h> diff --git a/lumina-screenshot/MainUI.ui b/lumina-screenshot/MainUI.ui index 2d35b68c..a9ee7aaa 100644 --- a/lumina-screenshot/MainUI.ui +++ b/lumina-screenshot/MainUI.ui @@ -118,7 +118,7 @@ <enum>TopToolBarArea</enum> </attribute> <attribute name="toolBarBreak"> - <bool>true</bool> + <bool>false</bool> </attribute> <addaction name="actionQuit"/> <addaction name="actionSave"/> diff --git a/lumina-screenshot/lumina-screenshot.pro b/lumina-screenshot/lumina-screenshot.pro index 1681a12b..b43d582c 100644 --- a/lumina-screenshot/lumina-screenshot.pro +++ b/lumina-screenshot/lumina-screenshot.pro @@ -1,5 +1,6 @@ QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras TARGET = lumina-screenshot isEmpty(PREFIX) { @@ -18,16 +19,10 @@ FORMS += MainUI.ui INCLUDEPATH += ../libLumina $$PREFIX/include - LIBS += -L../libLumina -lLuminaUtils -freebsd-* { - LIBS += -lQtSolutions_SingleApplication-head -} +LIBS += -L../libLumina -lLuminaUtils + +LRELEASE = $$PREFIX/lib/qt5/bin/lrelease -openbsd-g++4 { - LRELEASE = lrelease4 -} else { - LRELEASE = lrelease-qt4 -} QMAKE_LIBDIR = ../libLumina DEPENDPATH += ../libLumina diff --git a/lumina-screenshot/main.cpp b/lumina-screenshot/main.cpp index b7112a4d..9561430d 100644 --- a/lumina-screenshot/main.cpp +++ b/lumina-screenshot/main.cpp @@ -1,5 +1,5 @@ #include <QTranslator> -#include <QtGui/QApplication> +#include <QApplication> #include <QDebug> #include <QFile> diff --git a/lumina-search/lumina-search.pro b/lumina-search/lumina-search.pro index 3f428c6a..fcc6ae0f 100644 --- a/lumina-search/lumina-search.pro +++ b/lumina-search/lumina-search.pro @@ -1,5 +1,6 @@ QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = lumina-search isEmpty(PREFIX) { @@ -20,16 +21,10 @@ FORMS += MainUI.ui INCLUDEPATH += ../libLumina $$PREFIX/include - LIBS += -L../libLumina -lLuminaUtils -freebsd-* { - LIBS += -lQtSolutions_SingleApplication-head -} +LIBS += -L../libLumina -lLuminaUtils + +LRELEASE = $$PREFIX/lib/qt5/bin/lrelease -openbsd-g++4 { - LRELEASE = lrelease4 -} else { - LRELEASE = lrelease-qt4 -} QMAKE_LIBDIR = ../libLumina DEPENDPATH += ../libLumina diff --git a/lumina-search/main.cpp b/lumina-search/main.cpp index 886884d5..a4d04d4b 100644 --- a/lumina-search/main.cpp +++ b/lumina-search/main.cpp @@ -1,5 +1,5 @@ #include <QTranslator> -#include <QtGui/QApplication> +#include <QApplication> #include <QDebug> #include <QFile> @@ -9,8 +9,11 @@ int main(int argc, char ** argv) { + //qDebug() << "Init App..."; QApplication a(argc, argv); + //qDebug() << "Init Theme Engine..."; LuminaThemeEngine theme(&a); + //qDebug() << "Load Translations..."; a.setApplicationName("Search for..."); QTranslator translator; QLocale mylocale; diff --git a/port-files/Makefile b/port-files/Makefile index e625c4b4..483c49e3 100644 --- a/port-files/Makefile +++ b/port-files/Makefile @@ -3,7 +3,7 @@ PORTNAME= lumina GITVERSION= CHGVERSION -PORTVERSION= 0.7.2.${GITVERSION} +PORTVERSION= 0.8.0.${GITVERSION} PORTEPOCH= 1 CATEGORIES= x11 DISTNAME= ${PORTNAME}-${GITVERSION} @@ -23,16 +23,14 @@ RUN_DEPENDS= xorg>=0:${PORTSDIR}/x11/xorg \ xscreensaver-demo:${PORTSDIR}/x11/xscreensaver \ xbrightness:${PORTSDIR}/x11/xbrightness \ numlockx:${PORTSDIR}/x11/numlockx \ - phonon-gstreamer>=0:${PORTSDIR}/multimedia/phonon-gstreamer \ - gstreamer-plugins-ogg>=0:${PORTSDIR}/audio/gstreamer-plugins-ogg -LIB_DEPENDS= libQtSolutions_SingleApplication-head.so:${PORTSDIR}/devel/qt4-qtsolutions-singleapplication \ - libjpeg.so:${PORTSDIR}/graphics/jpeg +#LIB_DEPENDS= MAKE_JOBS_UNSAFE=yes USE_XORG= x11 xcomposite xdamage xrender +USE_XCB= x11extras wm USE_LDCONFIG= yes -USE_QT4= corelib gui network svg linguist phonon imageformats \ - moc_build rcc_build uic_build +USE_QT5= corelib gui network svg linguist multimedia imageformats \ + buildtools x11extras USES= qmake tar:bzip2 WRKSRC= ${WRKDIR}/lumina diff --git a/port-files/pkg-plist b/port-files/pkg-plist index b07c02aa..a0c7dd82 100644 --- a/port-files/pkg-plist +++ b/port-files/pkg-plist @@ -13,6 +13,7 @@ include/LuminaUtils.h include/LuminaX11.h include/LuminaThemes.h include/LuminaOS.h +include/LuminaSingleApplication.h share/applications/lumina-fm.desktop share/applications/lumina-screenshot.desktop share/applications/lumina-search.desktop |