//=========================================== // Lumina-DE source code // Copyright (c) 2016, Ken Moore // Available under the 3-clause BSD license // See the LICENSE file for full details //=========================================== #include "ScreenSettings.h" #include #include #include //Reset current screen config to match previously-saved settings void RRSettings::ApplyPrevious(){ QSettings set("lumina-desktop","lumina-xconfig"); set.beginGroup("MonitorSettings"); //Setup a couple lists QStringList devs = set.childGroups(); //known/saved devices QList screens = RRSettings::CurrentScreens(); QStringList lastactive = set.value("lastActive",QStringList()).toStringList(); //Now go through all the saved settings and put that info into the array QString primary; QStringList avail; for(int i=0; i=0){screens[i].order = -1; } //reset all screen orders (need to re-check all) if(devs.contains(screens[i].ID) && screens[i].isavailable){ //only load settings for monitors which are currently attached set.beginGroup(screens[i].ID); screens[i].geom = set.value("geometry", QRect()).toRect(); screens[i].isprimary = set.value("isprimary", false).toBool(); if(screens[i].isprimary){ primary = screens[i].ID; } screens[i].isactive = lastactive.contains(screens[i].ID); screens[i].order = (screens[i].isactive ? -1 : -3); //check/ignore set.endGroup(); }else if(screens[i].isavailable){ screens[i].order = -2; //needs activation/placement }else{ screens[i].order = -3; //ignored } //Now clean up the list as needed if(screens[i].order < -2){ screens.removeAt(i); i--; } //just remove it (less to loop through later) else{ avail << screens[i].ID; } //needed for some checks later - make it simple } //NOTE ABOUT orders: -1: check geom, -2: auto-add to end, -3: ignored //Quick checks for simple systems - just use current X config as-is if(devs.isEmpty() && (avail.filter("LVDS").isEmpty() || screens.length()==1) ){ return; } //Typical ID's: LVDS-[], DVI-I-[], DP-[], HDMI-[], VGA-[] //"LVDS" is the built-in laptop display normally if(primary.isEmpty()){ QStringList priority; priority << "LVDS" << "DP" << "HDMI" << "DVI" << "VGA"; for(int i=0; i=0){ cx+=screens[next].geom.width(); screens[next].order = handled; handled++; }else{ //Still missing monitors (vertical alignment?) qDebug() << "Unhandled Monitors:" << screens.length()-handled; break; } } //Now reset the display with xrandr RRSettings::Apply(screens); } //Read the current screen config from xrandr QList RRSettings::CurrentScreens(){ QList SCREENS; QStringList info = LUtils::getCmdOutput("xrandr -q"); ScreenInfo cscreen; for(int i=0; ix++" cscreen.geom.setRect( devres.section("+",-2,-2).toInt(), devres.section("+",-1,-1).toInt(), devres.section("x",0,0).toInt(), devres.section("+",0,0).section("x",1,1).toInt() ); cscreen.isavailable = true; cscreen.isactive = true; }else if(info[i].contains(" connected")){ //Device that is connected, but not attached qDebug() << "Create new Screen entry:" << dev << "none"; cscreen.ID = dev; cscreen.order = -2; //flag this right now as a non-active screen cscreen.isavailable = true; cscreen.isactive = false; } }else if( !cscreen.ID.isEmpty() && info[i].section("\t",0,0,QString::SectionSkipEmpty).contains("x")){ //available resolution for a device cscreen.resList << info[i].section("\t",0,0,QString::SectionSkipEmpty); } } //end loop over primary info lines if(!cscreen.ID.isEmpty()){ SCREENS << cscreen; } //make sure to add the last screen to the array return SCREENS; } //Save the screen config for later bool RRSettings::SaveScreens(QList screens){ QSettings set("lumina-desktop","lumina-xconfig"); set.beginGroup("MonitorSettings"); //Setup a couple lists QStringList olddevs = set.childGroups(); QStringList active; //Now go through all the current screens and save that info for(int i=0; i screens){ //Read all the settings and create the xrandr options to maintain these settings QStringList opts; qDebug() << "Apply:" << screens.length(); for(int i=0; i