aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core/lumina-desktop-unified
diff options
context:
space:
mode:
authorSasongko Bawono <sasongko262@gmail.com>2017-02-26 08:33:25 +0700
committerSasongko Bawono <sasongko262@gmail.com>2017-02-26 08:33:25 +0700
commiteb7d5a1270d17ecd16912008d8587cc543cafc77 (patch)
tree64be065a2e3fe58933bb5be6f30cc76a1af33f86 /src-qt5/core/lumina-desktop-unified
parent modified DEPENDENCIES for Slackware (diff)
parentMerge remote-tracking branch 'origin/master' (diff)
downloadlumina-eb7d5a1270d17ecd16912008d8587cc543cafc77.tar.gz
lumina-eb7d5a1270d17ecd16912008d8587cc543cafc77.tar.bz2
lumina-eb7d5a1270d17ecd16912008d8587cc543cafc77.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src-qt5/core/lumina-desktop-unified')
-rw-r--r--src-qt5/core/lumina-desktop-unified/LSession.cpp11
-rw-r--r--src-qt5/core/lumina-desktop-unified/global-includes.h2
-rw-r--r--src-qt5/core/lumina-desktop-unified/lumina-desktop.pro1
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp7
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h1
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp129
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h20
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp3
8 files changed, 150 insertions, 24 deletions
diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp
index cb0144d5..1c8d3c45 100644
--- a/src-qt5/core/lumina-desktop-unified/LSession.cpp
+++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp
@@ -24,11 +24,12 @@ RootWindow* Lumina::ROOTWIN = 0;
XDGDesktopList* Lumina::APPLIST = 0;
LShortcutEvents* Lumina::SHORTCUTS = 0;
-LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lumina-desktop"){
+LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lumina-desktop-unified"){
//Initialize the global objects to null pointers
mediaObj = 0; //private object used for playing login/logout chimes
if(this->isPrimaryProcess()){
//Setup the global registrations
+ qsrand(QDateTime::currentMSecsSinceEpoch());
this->setApplicationName("Lumina Desktop Environment");
this->setApplicationVersion( LDesktopUtils::LuminaDesktopVersion() );
this->setOrganizationName("LuminaDesktopEnvironment");
@@ -41,7 +42,7 @@ LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lu
//this->setAttribute(Qt::AA_UseHighDpiPixmaps); //allow pixmaps to be scaled up as well as down
//Now initialize the global objects (but do not start them yet)
- Lumina::EFILTER = new EventFilter(); //Need the XCB Event filter
+ Lumina::EFILTER = new EventFilter(); //Need the XCB Event filter first
Lumina::SETTINGS = new DesktopSettings();
Lumina::SS = new LScreenSaver();
//Lumina::WM = new LWindowManager();
@@ -60,7 +61,7 @@ LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lu
//Setup the various connections between the global classes
// NOTE: Most of these connections will only become "active" as the global objects get started during the setupSession routine
connect(Lumina::ROOTWIN, SIGNAL(RegisterVirtualRoot(WId)), Lumina::EFILTER, SLOT(RegisterVirtualRoot(WId)) );
-
+ connect(Lumina::EFILTER, SIGNAL(WindowCreated(NativeWindow*)), Lumina::ROOTWIN, SLOT(NewWindow(NativeWindow*)) );
} //end check for primary process
}
@@ -176,7 +177,7 @@ void LSession::setupSession(){
Lumina::SHORTCUTS->start(); //Startup the shortcut handler now
//for(int i=0; i<4; i++){ LSession::processEvents(); } //Again, just a few event loops here so thing can settle before we close the splash screen
//launchStartupApps();
- //QTimer::singleShot(500, this, SLOT(launchStartupApps()) );
+ QTimer::singleShot(500, this, SLOT(launchStartupApps()) );
splash.hide();
LSession::processEvents();
splash.close();
@@ -279,7 +280,7 @@ void LSession::launchStartupApps(){
LOS::setScreenBrightness( tmp );
qDebug() << " - - Screen Brightness:" << QString::number(tmp)+"%";
}
- QProcess::startDetached("nice lumina-open -autostart-apps");
+ //ExternalProcess::launch("nice lumina-open -autostart-apps");
//Re-load the screen brightness and volume settings from the previous session
// Wait until after the XDG-autostart functions, since the audio system might be started that way
diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h
index 6a753cd1..867076db 100644
--- a/src-qt5/core/lumina-desktop-unified/global-includes.h
+++ b/src-qt5/core/lumina-desktop-unified/global-includes.h
@@ -57,6 +57,8 @@
#include <LuminaSingleApplication.h>
#include <DesktopSettings.h>
#include <RootWindow.h>
+#include <ExternalProcess.h>
+#include <NativeWindow.h>
// Standard C includes
#include <unistd.h>
diff --git a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro
index 497ce635..1de8308d 100644
--- a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro
+++ b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro
@@ -17,6 +17,7 @@ include(../libLumina/LuminaSingleApplication.pri)
include(../libLumina/LuminaThemes.pri)
include(../libLumina/DesktopSettings.pri)
include(../libLumina/RootWindow.pri)
+include(../libLumina/ExternalProcess.pri)
#include all the main individual source groups
include(src-screensaver/screensaver.pri)
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp
index fa4af5ba..e363af01 100644
--- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp
@@ -24,7 +24,7 @@ void DesktopContextMenu::UpdateMenu(){
for(int i=0; i<items.length(); i++){
if(items[i]=="terminal"){ this->addAction(LXDG::findIcon("utilities-terminal",""), tr("Terminal"))->setWhatsThis("lumina-open -terminal"); }
else if(items[i]=="lockdesktop"){ this->addAction(LXDG::findIcon("system-lock-screen",""), tr("Lock Session"), this, SIGNAL(LockSession()) ); }
- else if(items[i]=="filemanager"){ this->addAction( LXDG::findIcon("user-home",""), tr("Browse Files"))->setWhatsThis("lumina-open ~"); }
+ else if(items[i]=="filemanager"){ this->addAction( LXDG::findIcon("user-home",""), tr("Browse Files"))->setWhatsThis("lumina-open \""+QDir::homePath()+"\""); }
//else if(items[i]=="applications"){ this->addMenu( LSession::handle()->applicationMenu() ); }
else if(items[i]=="line"){ this->addSeparator(); }
//else if(items[i]=="settings"){ this->addMenu( LSession::handle()->settingsMenu() ); }
@@ -34,7 +34,7 @@ void DesktopContextMenu::UpdateMenu(){
QString file = items[i].section("::::",1,1).simplified();
XDGDesktop xdgf(file);// = LXDG::loadDesktopFile(file, ok);
if(xdgf.type!=XDGDesktop::BAD){
- this->addAction( LXDG::findIcon(xdgf.icon,""), xdgf.name)->setWhatsThis(file);
+ this->addAction( LXDG::findIcon(xdgf.icon,""), xdgf.name)->setWhatsThis("lumina-open \""+file+"\"");
}else{
qDebug() << "Could not load application file:" << file;
}
@@ -86,8 +86,9 @@ void DesktopContextMenu::start(){
// === PRIVATE SLOTS ===
void DesktopContextMenu::LaunchAction(QAction *act){
if(act->whatsThis().isEmpty() || act->parent()!=this ){ return; }
+ qDebug() << "Launch Menu Action:" << act->whatsThis();
QString cmd = act->whatsThis();
- emit LaunchApplication(cmd);
+ ExternalProcess::launch(cmd);
}
void DesktopContextMenu::showMenu(const QPoint &pt){
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h
index 1a4befc9..8b0509fb 100644
--- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h
@@ -30,7 +30,6 @@ private slots:
void showMenu(const QPoint&);
signals:
- void LaunchApplication(QString); //cmd to run
void LockSession();
void showLeaveDialog();
};
diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp
index 4a192aa4..7031f3df 100644
--- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp
+++ b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp
@@ -53,6 +53,7 @@ void EventFilter::start(){
XCB->setupEventsForRoot(WMFlag);
XCB->WM_Set_Supporting_WM(WMFlag);
+ XCB->WM_Set_Root_Supported(); //announce all the various options that the WM supports
static_cast<XCBEventFilter*>(EF)->startSystemTray();
QCoreApplication::instance()->flush();
@@ -71,11 +72,22 @@ unsigned int EventFilter::currentWorkspace(){
return XCB->CurrentWorkspace();
}
+QList<NativeWindow*> EventFilter::currentWindows(){
+ return static_cast<XCBEventFilter*>(EF)->windowList();
+}
+
// === PUBLIC SLOTS ===
void EventFilter::RegisterVirtualRoot(WId id){
XCB->WM_Set_Virtual_Roots( QList<WId>() << id );
}
+void EventFilter::TryCloseWindow(WId id){
+ XCB->WM_CloseWindow(id, false); //do not force close
+}
+
+void EventFilter::TryActivateWindow(WId id){
+ XCB->WM_Set_Active_Window(id);
+}
//=============================
// XCBEventFilter Class
//=============================
@@ -132,13 +144,13 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag
//==============================
case XCB_KEY_PRESS:
//This is a keyboard key press
- qDebug() << "Key Press Event";
+ //qDebug() << "Key Press Event";
stopevent = BlockInputEvent( ((xcb_key_press_event_t *) ev)->root ); //use the main "root" window - not the child widget
if(!stopevent){ obj->emit KeyPressed( InputWindow(((xcb_key_press_event_t *) ev)->root), ((xcb_key_press_event_t *) ev)->detail ); }
break;
case XCB_KEY_RELEASE:
//This is a keyboard key release
- qDebug() << "Key Release Event";
+ //qDebug() << "Key Release Event";
stopevent = BlockInputEvent( ((xcb_key_release_event_t *) ev)->root ); //use the main "root" window - not the child widget
if(!stopevent){ obj->emit KeyReleased( InputWindow(((xcb_key_release_event_t *) ev)->root), ((xcb_key_release_event_t *) ev)->detail ); }
break;
@@ -183,25 +195,42 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag
break;
//==============================
case XCB_MAP_NOTIFY:
+ //qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window;
+ if(Lumina::SS->isLocked()){ waitingToShow << ((xcb_map_notify_event_t *)ev)->window ; }
+ else{
+ for(int i=0; i<windows.length(); i++){
+ if(windows[i]->id() == ((xcb_map_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, true); break; }
+ }
+ }
break; //This is just a notification that a window was mapped - nothing needs to change here
case XCB_MAP_REQUEST:
- qDebug() << "Window Map Request Event";
- obj->emit ModifyWindow( ((xcb_map_request_event_t *) ev)->window, Lumina::Show);
+ //qDebug() << "Window Map Request Event";
+ SetupNewWindow( ((xcb_map_request_event_t *) ev) );
break;
//==============================
case XCB_CREATE_NOTIFY:
- qDebug() << "Window Create Event";
+ //qDebug() << "Window Create Event";
break;
//==============================
case XCB_UNMAP_NOTIFY:
- qDebug() << "Window Unmap Event";
- obj->emit ModifyWindow( ((xcb_unmap_notify_event_t *)ev)->window, Lumina::Hide);
+ //qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window;
+ if(waitingToShow.contains(((xcb_unmap_notify_event_t *)ev)->window)){ waitingToShow.removeAll(((xcb_unmap_notify_event_t *)ev)->window); }
+ for(int i=0; i<windows.length(); i++){
+ if(windows[i]->id() == ((xcb_unmap_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, false); break; }
+ }
break;
//==============================
case XCB_DESTROY_NOTIFY:
- qDebug() << "Window Closed Event";
+ //qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window;
if( !rmTrayApp( ((xcb_destroy_notify_event_t *) ev)->window ) ){
- obj->emit WindowClosed( ((xcb_destroy_notify_event_t *) ev)->window );
+ //qDebug() <<" - Non-tray window";
+ for(int i=0; i<windows.length(); i++){
+ if(windows[i]->id() == ((xcb_destroy_notify_event_t *)ev)->window){
+ windows[i]->emit WindowClosed(windows[i]->id());
+ QTimer::singleShot(500, windows.takeAt(i), SLOT(deleteLater()) ); //give a few moments first, then clean up the object
+ break;
+ }
+ }
}
break;
//==============================
@@ -215,7 +244,7 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag
//==============================
case XCB_PROPERTY_NOTIFY:
//qDebug() << "Property Notify Event:";
- //qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window;
+ ParsePropertyEvent((xcb_property_notify_event_t*)ev);
break;
//==============================
case XCB_CLIENT_MESSAGE:
@@ -305,6 +334,10 @@ bool XCBEventFilter::stopSystemTray(){
return true;
}
+QList<NativeWindow*> XCBEventFilter::windowList(){
+ return windows;
+}
+
//=========
// PRIVATE
//=========
@@ -389,3 +422,79 @@ void XCBEventFilter::checkDamageID(WId id){
//Could check for window damage ID's - but we should not need this
}
}
+
+// WINDOW HANDLING FUNCTIONS
+void XCBEventFilter::SetupNewWindow(xcb_map_request_event_t *ev){
+ WId win = ev->window;
+
+ bool ok = obj->XCB->WM_ManageWindow(win, true);
+ //Quick check if this is a transient window if we could not manage it directly
+ if(!ok){
+ WId tran = obj->XCB->WM_ICCCM_GetTransientFor(win);
+ if(tran!=win && tran!=0){
+ win = tran;
+ ok = obj->XCB->WM_ManageWindow(win);
+ }
+ }
+ qDebug() << "New Window:" << win << obj->XCB->WM_ICCCM_GetClass(win) << " Managed:" << ok;
+ obj->XCB->WM_Set_Active_Window(win);
+ //Determing the requested geometry/location/management within the event,
+ NativeWindow *nwin = new NativeWindow(win);
+ QObject::connect(nwin, SIGNAL(RequestClose(WId)), obj, SLOT(TryCloseWindow(WId)) );
+ QObject::connect(nwin, SIGNAL(RequestActivate(WId)), obj, SLOT(TryActivateWindow(WId)) );
+ windows << nwin;
+ bool show_now = !Lumina::SS->isLocked();
+ if(!show_now){ waitingToShow << win; } //add to the list to get set visible later
+ //populate the native window settings as they are right now
+ nwin->setProperty(NativeWindow::Active, true);
+ nwin->setProperty(NativeWindow::Visible, show_now);
+ nwin->setProperty(NativeWindow::Workspace, obj->XCB->CurrentWorkspace());
+ icccm_size_hints hints = obj->XCB->WM_ICCCM_GetNormalHints(win);
+ if(!hints.isValid()){ hints = obj->XCB->WM_ICCCM_GetSizeHints(win); }
+ if(hints.validMinSize()){ nwin->setProperty(NativeWindow::MinSize, QSize(hints.min_width,hints.min_height)); }
+ if(hints.validMaxSize()){ nwin->setProperty(NativeWindow::MaxSize, QSize(hints.max_width,hints.max_height)); }
+ if(hints.validBaseSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.base_width,hints.base_height)); }
+ else if(hints.validSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.width, hints.height)); }
+ nwin->setProperty(NativeWindow::Icon, obj->XCB->WM_Get_Icon(win));
+ QString title = obj->XCB->WM_Get_Name(win);
+ if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Name(win); }
+ if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetName(win); }
+ nwin->setProperty(NativeWindow::Title, title);
+ title = obj->XCB->WM_Get_Icon_Name(win);
+ if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Icon_Name(win); }
+ if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetIconName(win); }
+ nwin->setProperty(NativeWindow::ShortTitle, title);
+
+ obj->emit WindowCreated(nwin);
+}
+
+void XCBEventFilter::ParsePropertyEvent(xcb_property_notify_event_t *ev){
+ //First find the NativeWindow associated with the event
+ NativeWindow *nwin = 0;
+ for(int i=0; i<windows.length() && nwin==0; i++){
+ if(windows[i]->id() == ev->window){ nwin = windows[i]; }
+ }
+ if(nwin==0){ return; } //unmanaged window - ignore this event
+ qDebug() << "Got Property Event:" << ev->window << ev->atom;
+ //Now determine which properties are getting changed, and update the native window as appropriate
+ if(ev->atom == obj->XCB->EWMH._NET_WM_NAME){
+ qDebug() << " - Found _NET_WM_NAME atom";
+ nwin->setProperty(NativeWindow::Title, obj->XCB->WM_Get_Name(nwin->id()));
+ }else if(ev->atom == obj->XCB->EWMH._NET_WM_ICON){
+ qDebug() << " - Found _NET_WM_ICON atom";
+ nwin->setProperty(NativeWindow::Icon, obj->XCB->WM_Get_Icon(nwin->id()));
+ }else if(ev->atom == obj->XCB->EWMH._NET_WM_ICON_NAME){
+ qDebug() << " - Found _NET_WM_ICON_NAME atom";
+ nwin->setProperty(NativeWindow::ShortTitle, obj->XCB->WM_Get_Icon_Name(nwin->id()));
+ }else if(ev->atom == obj->XCB->EWMH._NET_WM_DESKTOP){
+ qDebug() << " - Found _NET_WM_DESKTOP atom";
+ nwin->setProperty(NativeWindow::Workspace, obj->XCB->WM_Get_Desktop(nwin->id()));
+ }else if(ev->atom == obj->XCB->EWMH._NET_WM_WINDOW_TYPE ){
+ qDebug() << " - Found _NET_WM_WINDOW_TYPE atom";
+
+ }else if( ev->atom == obj->XCB->EWMH._NET_WM_STATE){
+ qDebug() << " - Found _NET_WM_STATE atom";
+
+ }
+
+}
diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h
index 9e76ba53..9f2530e8 100644
--- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h
+++ b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h
@@ -60,18 +60,21 @@ public:
//Public Session Interaction Functions
unsigned int currentWorkspace();
+
+ //Public Window Management Lists
+ QList<NativeWindow*> currentWindows(); //always returned in creation-order (oldest first)
//Variables/Functions needed by the XCBEventFilter class only (not really needed by anything else)
LXCB *XCB; //used to interact with the X11 graphics subsystem
public slots:
void RegisterVirtualRoot(WId);
+ void TryCloseWindow(WId);
+ void TryActivateWindow(WId);
signals:
void NewInputEvent();
- void NewManagedWindow(WId);
- void WindowClosed(WId);
- void ModifyWindow(WId win, Lumina::WindowAction);
+ void WindowCreated(NativeWindow*);
// Session Signals
void WorkspaceChanged(unsigned int);
@@ -99,6 +102,9 @@ public:
bool startSystemTray();
bool stopSystemTray();
+ //Window List Functions
+ QList<NativeWindow*> windowList();
+
private:
EventFilter *obj;
QList<xcb_atom_t> WinNotifyAtoms, SysNotifyAtoms;
@@ -119,13 +125,19 @@ private:
bool rmTrayApp(WId); //returns "true" if the tray app was found and removed
void checkDamageID(WId);
+ //Window List Variables
+ QList<NativeWindow*> windows;
+ QList<WId> waitingToShow;
+
//Longer Event handling functions
+ void SetupNewWindow(xcb_map_request_event_t *ev);
+
//bool ParseKeyPressEvent();
//bool ParseKeyReleaseEvent();
//bool ParseButtonPressEvent();
//bool ParseButtonReleaseEvent();
//bool ParseMotionEvent();
- //bool ParsePropertyEvent();
+ void ParsePropertyEvent(xcb_property_notify_event_t *ev);
//bool ParseClientMessageEvent();
//bool ParseDestroyEvent();
//bool ParseConfigureEvent();
diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp
index 83b82ff8..9ad31f5c 100644
--- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp
+++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp
@@ -19,6 +19,7 @@ SSBaseWidget::SSBaseWidget(QWidget *parent, QSettings *set) : QWidget(parent){
this->setObjectName("LuminaBaseSSWidget");
ANIM = 0;
this->setMouseTracking(true);
+ plugType="none";
}
SSBaseWidget::~SSBaseWidget(){
@@ -51,7 +52,7 @@ void SSBaseWidget::startPainting(){
//Now list all the various plugins and start them appropriately
QString style;
if(cplug=="none"){
- style = "background: transparent;"; //show the underlying black parent widget
+ style = "background: black;"; //show the underlying black parent widget
}else{
style = "background: black;";
}
bgstack15