aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core-utils/lumina-xconfig
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/core-utils/lumina-xconfig')
-rw-r--r--src-qt5/core-utils/lumina-xconfig/MainUI.cpp461
-rw-r--r--src-qt5/core-utils/lumina-xconfig/MainUI.h24
-rw-r--r--src-qt5/core-utils/lumina-xconfig/MainUI.ui193
-rw-r--r--src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp101
-rw-r--r--src-qt5/core-utils/lumina-xconfig/ScreenSettings.h13
-rw-r--r--src-qt5/core-utils/lumina-xconfig/i18n/lumina-xconfig_en_AU.ts4
-rw-r--r--src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro1
7 files changed, 431 insertions, 366 deletions
diff --git a/src-qt5/core-utils/lumina-xconfig/MainUI.cpp b/src-qt5/core-utils/lumina-xconfig/MainUI.cpp
index 6553bb37..030b96be 100644
--- a/src-qt5/core-utils/lumina-xconfig/MainUI.cpp
+++ b/src-qt5/core-utils/lumina-xconfig/MainUI.cpp
@@ -15,19 +15,34 @@
MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
ui->setupUi(this);
loadIcons();
- //Fill the location list with the valid entries
- ui->combo_location->clear();
- ui->combo_location->addItem(tr("Right Of"), "--right-of");
- ui->combo_location->addItem(tr("Left Of"), "--left-of");
+ scaleFactor = 1/15.0; //simple default value
+ ui->combo_rotation->clear();
+ ui->combo_rotation->addItem(tr("None"), 0);
+ ui->combo_rotation->addItem(tr("Left"), -90);
+ ui->combo_rotation->addItem(tr("Right"), 90);
+ ui->combo_rotation->addItem(tr("Inverted"), 180);
+ singleTileMenu = new QMenu(this);
+ singleTileMenu->addAction(tr("Align Horizontally"))->setWhatsThis("X");
+ singleTileMenu->addAction(tr("Align Vertically"))->setWhatsThis("Y");
+ singleTileMenu->addAction(tr("Align Horizontal then Vertical"))->setWhatsThis("XY");
+ singleTileMenu->addAction(tr("Align Vertical then Horizontal"))->setWhatsThis("YX");
+ ui->mdiArea->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui->mdiArea, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMenu()) );
+
+ connect(singleTileMenu, SIGNAL(triggered(QAction*)), this, SLOT(tileSingleScreen(QAction*)) );
connect(ui->push_close, SIGNAL(clicked()), this, SLOT(close()) );
connect(ui->push_rescan, SIGNAL(clicked()), this, SLOT(UpdateScreens()) );
connect(ui->push_activate, SIGNAL(clicked()), this, SLOT(ActivateScreen()) );
connect(ui->tool_deactivate, SIGNAL(clicked()), this, SLOT(DeactivateScreen()) );
- connect(ui->tool_moveleft, SIGNAL(clicked()), this, SLOT(MoveScreenLeft()) );
- connect(ui->tool_moveright, SIGNAL(clicked()), this, SLOT(MoveScreenRight()) );
+
+ connect(ui->tool_save, SIGNAL(clicked()), this, SLOT(SaveSettings()) );
connect(ui->tool_applyconfig, SIGNAL(clicked()), this, SLOT(ApplyChanges()) );
- connect(ui->list_screens, SIGNAL(itemSelectionChanged()),this, SLOT(ScreenSelected()) );
+ connect(ui->mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),this, SLOT(ScreenSelected()) );
+ connect(ui->tool_tileX, SIGNAL(clicked()), this, SLOT(tileScreensX()) );
+ connect(ui->tool_tileY, SIGNAL(clicked()), this, SLOT(tileScreensY()) );
+ connect(ui->tool_tile, SIGNAL(clicked()), this, SLOT(tileScreens()) );
+ connect(ui->combo_availscreens, SIGNAL(currentIndexChanged(int)), this, SLOT(updateNewScreenResolutions()) );
QTimer::singleShot(0, this, SLOT(UpdateScreens()) );
}
@@ -38,8 +53,7 @@ MainUI::~MainUI(){
void MainUI::loadIcons(){
this->setWindowIcon( LXDG::findIcon("preferences-system-windows-actions","") );
ui->tool_deactivate->setIcon( LXDG::findIcon("list-remove","") );
- ui->tool_moveleft->setIcon( LXDG::findIcon("arrow-left","") );
- ui->tool_moveright->setIcon( LXDG::findIcon("arrow-right","") );
+
ui->push_activate->setIcon( LXDG::findIcon("list-add","") );
ui->push_rescan->setIcon( LXDG::findIcon("view-refresh","") );
ui->push_close->setIcon( LXDG::findIcon("window-close","") );
@@ -48,30 +62,17 @@ void MainUI::loadIcons(){
ui->tool_applyconfig->setIcon( LXDG::findIcon("dialog-ok-apply","") );
}
-QStringList MainUI::currentOpts(){
- //Read all the settings and create the xrandr options to maintain these settings
- QStringList opts;
- for(int i=0; i<SCREENS.length(); i++){
- if(SCREENS[i].order <0){ continue; } //skip this screen - non-active
- opts << "--output" << SCREENS[i].ID << "--mode" << QString::number(SCREENS[i].geom.width())+"x"+QString::number(SCREENS[i].geom.height());
- if(SCREENS[i].isprimary){ opts << "--primary"; }
- if(SCREENS[i].order > 0){
- //Get the ID of the previous screen
- QString id;
- for(int j=0; j<SCREENS.length(); j++){
- if(SCREENS[j].order == SCREENS[i].order-1){ id = SCREENS[j].ID; break;}
- }
- if(!id.isEmpty()){ opts << "--right-of" << id; }
- }
- }
- return opts;
+QString MainUI::currentSelection(){
+ QMdiSubWindow *tmp = ui->mdiArea->activeSubWindow();
+ if(tmp!=0){ return tmp->whatsThis(); }
+ else{ return ""; }
}
ScreenInfo MainUI::currentScreenInfo(){
- QListWidgetItem *item = ui->list_screens->currentItem();
+ QString item = currentSelection();
if(item!=0){
for(int i=0; i<SCREENS.length(); i++){
- if(SCREENS[i].ID==item->whatsThis()){ return SCREENS[i]; }
+ if(SCREENS[i].ID==item){ return SCREENS[i]; }
}
}
//Fallback when nothing found/selected
@@ -79,104 +80,84 @@ ScreenInfo MainUI::currentScreenInfo(){
}
void MainUI::AddScreenToWidget(ScreenInfo screen){
- QListWidgetItem *it = new QListWidgetItem();
- it->setTextAlignment(Qt::AlignCenter);
- it->setText( screen.ID+"\n\n ("+QString::number(screen.geom.x())+", "+QString::number(screen.geom.y())+")\n ("+QString::number(screen.geom.width())+"x"+QString::number(screen.geom.height())+") " );
+ qDebug() << "Add Screen To Widget:" << screen.ID << screen.geom;
+ QLabel *lab = new QLabel(this);
+ lab->setAlignment(Qt::AlignCenter);
+ QMdiSubWindow *it = ui->mdiArea->addSubWindow(lab, Qt::Tool | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
+ it->setSystemMenu(0);
+ it->setWindowTitle(screen.ID);
+ lab->setText(QString::number(screen.geom.width())+"x"+QString::number(screen.geom.height()));
+
it->setWhatsThis(screen.ID);
- ui->list_screens->addItem(it);
+ QRect scaled( screen.geom.topLeft()*scaleFactor, screen.geom.size()*scaleFactor);
+ qDebug() << " - Scaled:" << scaled;
+ it->show();
+ it->setGeometry(scaled); //scale it down for the display
+ it->setFixedSize(scaled.size());
+
+}
+
+void MainUI::SyncBackend(){
+ QString item = currentSelection();
+ if(item.isEmpty()){ return; } //nothing to do
+ QString newres = ui->combo_resolution->currentData().toString().section("(",0,0).simplified();
+ if(newres.isEmpty()){ return; } //nothing to do
+ //qDebug() << "Apply Screen Changes" << item << "->" << newres;
+ //Adjust the order of the two screens
+ bool setprimary = ui->check_primary->isChecked();
+ QList<QMdiSubWindow*> windows = ui->mdiArea->subWindowList();
+ for(int i=0; i<SCREENS.length(); i++){
+ if(SCREENS[i].ID == item){
+ SCREENS[i].geom.setWidth(newres.section("x",0,0).toInt());
+ SCREENS[i].geom.setHeight(newres.section("x",1,1).toInt());
+ //qDebug() << " - New Geom:" << SCREENS[i].geom;
+ SCREENS[i].rotation = ui->combo_rotation->currentData().toInt();
+ }
+ if(setprimary){ SCREENS[i].isprimary = (SCREENS[i].ID==item); }
+ //Find the window associated with this screen
+ for(int s=0; s<windows.length(); s++){
+ if(windows[s]->whatsThis()==SCREENS[i].ID){
+ qDebug() << "Adjust geom of window:" << SCREENS[i].geom;
+ SCREENS[i].geom.moveTopLeft( windows[s]->geometry().topLeft()/scaleFactor );
+ qDebug() << " - New Geom:" << SCREENS[i].geom;
+ if(SCREENS[i].applyChange<1){ SCREENS[i].applyChange = (windows[s]->widget()->isEnabled() ? 0 : 1); } //disabled window is one that will be removed
+ }
+ }
+ }
}
void MainUI::UpdateScreens(){
//First probe the server for current screens
SCREENS = RRSettings::CurrentScreens();
- /*QStringList info = LUtils::getCmdOutput("xrandr -q");
- ScreenInfo cscreen;
- for(int i=0; i<info.length(); i++){
- if(info[i].contains("connected") ){
- //qDebug() << "xrandr info:" << info[i];
- if(!cscreen.ID.isEmpty()){
- SCREENS << cscreen; //current screen finished - save it into the array
- cscreen = ScreenInfo(); //Now create a new structure
- }
- //qDebug() << "Line:" << info[i];
- QString dev = info[i].section(" ",0,0); //device ID
- //The device resolution can be either the 3rd or 4th output - check both
- QString devres = info[i].section(" ",2,2, QString::SectionSkipEmpty);
- if(!devres.contains("x")){ devres = info[i].section(" ",3,3,QString::SectionSkipEmpty); }
- if(!devres.contains("x")){ devres.clear(); }
- qDebug() << " - ID:" <<dev << "Current Geometry:" << devres;
- //qDebug() << " - Res:" << devres;
- if( !devres.contains("x") || !devres.contains("+") ){ devres.clear(); }
- //qDebug() << " - Res (modified):" << devres;
- if(info[i].contains(" disconnected ") && !devres.isEmpty() ){
- //Disable this device and restart (disconnected, but still attached to the X server)
- DeactivateScreen(dev);
- UpdateScreens();
- return;
- }else if( !devres.isEmpty() ){
- cscreen.isprimary = info[i].contains(" primary ");
- //Device that is connected and attached (has a resolution)
- qDebug() << "Create new Screen entry:" << dev << devres;
- cscreen.ID = dev;
- //Note: devres format: "<width>x<height>+<xoffset>+<yoffset>"
- 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() );
-
- }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
- }
- }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 info lines
- if(!cscreen.ID.isEmpty()){ SCREENS << cscreen; } //make sure to add the last screen to the array
- */
+ //Determine the scale factor for putting these into the UI
+ QRegion tot;
+ for(int i=0; i<SCREENS.length(); i++){
+ if(SCREENS[i].isactive){ tot = tot.united( SCREENS[i].geom ); }
+ }
+ int wid = tot.boundingRect().width();
+ scaleFactor = (0.9*ui->mdiArea->width())/wid;
//Now go through the screens and arrange them in order from left->right in the UI
- bool found = true;
- int xoffset = 0; //start at 0
- int cnum = 0;
- QString csel = "";
- if(ui->list_screens->currentItem()!=0){ csel = ui->list_screens->currentItem()->whatsThis(); }
- ui->list_screens->clear();
- while(found){
- found = false; //make sure to break out if a screen is not found
- for(int i=0; i<SCREENS.length(); i++){
- if(SCREENS[i].order != -1){qDebug() << "Skip Screen:" << i << SCREENS[i].order; } //already evaluated - skip it
- else if(SCREENS[i].geom.x()==xoffset){
- found = true; //make sure to look for the next one
- xoffset = xoffset+SCREENS[i].geom.width(); //next number to look for
- SCREENS[i].order = cnum; //assign the current order to it
- cnum++; //get ready for the next one
- AddScreenToWidget(SCREENS[i]);
- /*QListWidgetItem *it = new QListWidgetItem();
- it->setTextAlignment(Qt::AlignCenter);
- it->setText( SCREENS[i].ID+"\n ("+QString::number(SCREENS[i].geom.x())+", "+QString::number(SCREENS[i].geom.y())+")\n("+QString::number(SCREENS[i].geom.width())+"x"+QString::number(SCREENS[i].geom.height())+") " );
- it->setWhatsThis(SCREENS[i].ID);
- ui->list_screens->addItem(it);*/
- //if(SCREENS[i].ID==csel){ ui->list_screens->setCurrentItem(it); }
- }else if(SCREENS[i].geom.x() < xoffset || SCREENS[i].geom.x() > xoffset){
- //Screen not aligned with previous screen edge
- qDebug() << "Found mis-aligned screen:" << i << SCREENS[i].ID;
- found = true; //make sure to look for the next one
- xoffset = xoffset+SCREENS[i].geom.width(); //next number to look for
- SCREENS[i].order = cnum; //assign the current order to it
- cnum++; //get ready for the next one
- AddScreenToWidget(SCREENS[i]);
- }
- }
+ //bool found = true;
+ //int xoffset = 0; //start at 0
+ //int cnum = 0;
+ QString csel = currentSelection();
+ //Clear all the current widgets
+ while(ui->mdiArea->currentSubWindow()!=0 ){
+ QMdiSubWindow *tmp = ui->mdiArea->currentSubWindow();
+ tmp->widget()->deleteLater();
+ ui->mdiArea->removeSubWindow(tmp);
+ tmp->deleteLater();
+ }
+ //Now add all the active screens to the display
+ for(int i=0; i<SCREENS.length(); i++){
+ if(SCREENS[i].isactive){ AddScreenToWidget(SCREENS[i]); }
}
//Now update the available/current screens in the UI
ui->combo_availscreens->clear();
- ui->combo_cscreens->clear();
for(int i=0; i<SCREENS.length(); i++){
- if(SCREENS[i].order<0){
+ if(!SCREENS[i].isactive && SCREENS[i].isavailable){
ui->combo_availscreens->addItem(SCREENS[i].ID);
- }else{
- ui->combo_cscreens->addItem(SCREENS[i].ID);
}
}
if(ui->combo_availscreens->count()<1){
@@ -187,24 +168,20 @@ void MainUI::UpdateScreens(){
ui->group_avail->setVisible(true);
ui->tabWidget->setTabEnabled(1,true);
}
- if(ui->list_screens->currentItem()==0){ ui->list_screens->setCurrentRow(0); }
ScreenSelected(); //update buttons
- RRSettings::SaveScreens(SCREENS);
+ updateNewScreenResolutions();
}
void MainUI::ScreenSelected(){
- QListWidgetItem *item = ui->list_screens->currentItem();
- if(item==0){
+ QString item = currentSelection();
+ //QListWidgetItem *item = ui->list_screens->currentItem();
+ if(item.isEmpty()){
//nothing selected
ui->tool_deactivate->setEnabled(false);
- ui->tool_moveleft->setEnabled(false);
- ui->tool_moveright->setEnabled(false);
ui->tab_config->setEnabled(false);
}else{
//Item selected
- ui->tool_deactivate->setEnabled(ui->list_screens->count()>1);
- ui->tool_moveleft->setEnabled(ui->list_screens->row(item) > 0);
- ui->tool_moveright->setEnabled(ui->list_screens->row(item) < (ui->list_screens->count()-1));
+ ui->tool_deactivate->setEnabled(true);
ui->tab_config->setEnabled(true);
//Update the info available on the config tab
ScreenInfo cur = currentScreenInfo();
@@ -217,102 +194,190 @@ void MainUI::ScreenSelected(){
if(cur.resList[i].contains(cres)){ ui->combo_resolution->setCurrentIndex(i); }
}
ui->check_primary->setChecked( cur.isprimary );
+ int index = ui->combo_rotation->findData( cur.rotation );
+ if(index<0){ index = 0; }
+ ui->combo_rotation->setCurrentIndex(index);
}
}
-void MainUI::MoveScreenLeft(){
- QListWidgetItem *item = ui->list_screens->currentItem();
- if(item==0){ return; } //no selection
- //Get the current ID
- QString CID = item->whatsThis();
- //Now get the ID of the one on the left
- item = ui->list_screens->item( ui->list_screens->row(item)-1 );
- if(item == 0){ return; } //no item on the left (can't go left)
- QString LID = item->whatsThis(); //left ID
- //Adjust the order of the two screens
+void MainUI::updateNewScreenResolutions(){
+ QString id = ui->combo_availscreens->currentText();
for(int i=0; i<SCREENS.length(); i++){
- if(SCREENS[i].ID == CID){ SCREENS[i].order = SCREENS[i].order-1; }
- else if(SCREENS[i].ID==LID){ SCREENS[i].order = SCREENS[i].order+1; }
+ if(SCREENS[i].ID==id){
+ ui->combo_resolutions->clear();
+ for(int r=0; r<SCREENS[i].resList.length(); r++){
+ ui->combo_resolutions->addItem(SCREENS[i].resList[r].section(" ",0,0, QString::SectionSkipEmpty));
+ if(SCREENS[i].resList[r].contains("+")){ ui->combo_resolutions->setCurrentIndex(r); } //preferred resolution
+ }
+ break;
+ }
}
- //Now run the command
- QStringList opts = currentOpts();
- LUtils::runCmd("xrandr", opts);
- //Now run the command
- //LUtils::runCmd("xrandr", QStringList() << "--output" << CID << "--left-of" << LID);
- QTimer::singleShot(500, this, SLOT(UpdateScreens()) );
}
-void MainUI::MoveScreenRight(){
- QListWidgetItem *item = ui->list_screens->currentItem();
- if(item==0){ return; } //no selection
- //Get the current ID
- QString CID = item->whatsThis();
- //Now get the ID of the one on the left
- item = ui->list_screens->item( ui->list_screens->row(item)+1 );
- if(item == 0){ return; } //no item on the right (can't go right)
- QString RID = item->whatsThis(); //right ID
- //Adjust the order of the two screens
- for(int i=0; i<SCREENS.length(); i++){
- if(SCREENS[i].ID == RID){ SCREENS[i].order = SCREENS[i].order-1; }
- else if(SCREENS[i].ID==CID){ SCREENS[i].order = SCREENS[i].order+1; }
+void MainUI::tileScreensY(bool activeonly){
+ //qDebug() << "Tile Windows in Y Dimension";
+ QList<QMdiSubWindow*> wins = ui->mdiArea->subWindowList();
+ QMdiSubWindow *active = ui->mdiArea->currentSubWindow();
+ QRegion total;
+ int ypos = 0;
+ QMdiSubWindow *cur = 0;
+ while(!wins.isEmpty()){
+ cur=0;
+ for(int i=0; i<wins.length(); i++){
+ if(wins[i]==active && wins.length()>1){ continue; } //ensure active window is last
+ if(cur==0){ cur = wins[i]; } //first one
+ else if(wins[i]->pos().y() < cur->pos().y()){ cur = wins[i]; }
+ }
+ if(cur==0){
+ //Note: This should **never** happen
+ qDebug() << "No windows found below y=:" << ypos;
+ //need to move the reference point
+ QRect bounding = total.boundingRect();
+ ypos+= (bounding.height()/2);
+ }else{
+ if(total.isNull()){
+ //First window handled
+ if(!activeonly || cur==active){ cur->move(cur->pos().x(), ypos); }
+ }else{
+ int newy = ypos;
+ bool overlap = true;
+ while(overlap){
+ QRegion tmp(cur->pos().x(), newy, cur->width(), cur->height());
+ QRegion diff = tmp.subtracted(total);
+ overlap = (diff.boundingRect()!=tmp.boundingRect());
+ //qDebug() << "Check Y Overlap:" << newy << overlap << tmp.boundingRect() << diff.boundingRect();
+ if(overlap){
+ QRect bound = diff.boundingRect();
+ if(bound.isNull()){ newy+=cur->height(); }
+ else if(newy!=bound.top()){ newy = bound.top(); }
+ else if(newy!=bound.bottom()){ newy = bound.bottom() + 1; }
+ else{ newy++; } //make sure it always changes - no infinite loops!!
+ }
+ }
+ if(!activeonly || cur==active){ cur->move(cur->pos().x(), newy); }
+ }
+ total = total.united(cur->geometry());
+ wins.removeAll(cur);
+ }
}
- //Now run the command
- QStringList opts = currentOpts();
- LUtils::runCmd("xrandr", opts);
- QTimer::singleShot(500, this, SLOT(UpdateScreens()) );
}
-void MainUI::DeactivateScreen(QString device){
- if(device.isEmpty()){
- //Get the currently selected device
- QListWidgetItem *item = ui->list_screens->currentItem();
- if(item==0){ return; } //no selection
- //Get the current ID
- device = item->whatsThis();
+void MainUI::tileScreensX(bool activeonly){
+ //qDebug() << "Tile Windows in X Dimension";
+ QList<QMdiSubWindow*> wins = ui->mdiArea->subWindowList();
+ QMdiSubWindow *active = ui->mdiArea->currentSubWindow();
+ QRegion total;
+ int xpos = 0;
+ QMdiSubWindow *cur = 0;
+ while(!wins.isEmpty()){
+ cur=0;
+ for(int i=0; i<wins.length(); i++){
+ if(wins[i]==active && wins.length()>1){ continue; } //ensure active window is last
+ if(cur==0){ cur = wins[i]; } //first one
+ else if(wins[i]->pos().x() < cur->pos().x()){ cur = wins[i]; }
+ }
+ if(cur==0){
+ //Note: This should **never** happen
+ qDebug() << "No windows found left of x=:" << xpos;
+ //need to move the reference point
+ QRect bounding = total.boundingRect();
+ xpos+= (bounding.width()/2);
+ }else{
+ if(total.isNull()){
+ //First window handled
+ if(!activeonly || cur==active){ cur->move(xpos, cur->pos().y()); }
+ }else{
+ int newx = xpos;
+ bool overlap = true;
+ while(overlap){
+ QRegion tmp(newx, cur->pos().y(), cur->width(), cur->height());
+ QRegion diff = tmp.subtracted(total);
+ overlap = (diff.boundingRect()!=tmp.boundingRect());
+ //qDebug() << "Check X Overlap:" << newx << overlap << tmp.boundingRect() << diff.boundingRect();
+ if(overlap){
+ QRect bound = diff.boundingRect();
+ if(bound.isNull()){ newx+=cur->width(); }
+ else if(newx!=bound.left()){ newx = bound.left(); }
+ else if(newx!=bound.right()){ newx = bound.right() + 1; }
+ else{ newx++; }//make sure it always changes - no infinite loops!!
+ }else{
+ qDebug() << "Found Area:" << tmp << diff << newx;
+ }
+ }
+ if(!activeonly || cur==active){ cur->move(newx, cur->pos().y()); }
+ }
+ total = total.united(cur->geometry());
+ wins.removeAll(cur);
+ }
}
- if(device.isEmpty()){ return; } //nothing found
- //Remove the screen from the settings
- for(int i=0; i<SCREENS.length(); i++){
- if(SCREENS[i].ID==device){ SCREENS.removeAt(i); break; }
+}
+
+void MainUI::tileScreens(){
+ tileScreensY();
+ tileScreensX();
+}
+
+void MainUI::tileSingleScreen(QAction* act){
+ if(act->whatsThis()=="X"){
+ tileScreensX(true);
+ }else if(act->whatsThis()=="Y"){
+ tileScreensY(true);
+ }else if(act->whatsThis()=="XY"){
+ tileScreensX(true);
+ tileScreensY(true);
+ }else if(act->whatsThis()=="YX"){
+ tileScreensY(true);
+ tileScreensX(true);
}
- //Now run the command
- QStringList opts = currentOpts();
- opts << "--output" << device << "--off";
- LUtils::runCmd("xrandr", opts);
- QTimer::singleShot(500, this, SLOT(UpdateScreens()) );
+}
+
+void MainUI::DeactivateScreen(){
+ QMdiSubWindow *cur = ui->mdiArea->currentSubWindow();
+ if(cur==0){ return; }
+ cur->widget()->setEnabled( !cur->widget()->isEnabled() ); //toggle it between enabled/disabled
}
void MainUI::ActivateScreen(){
//Assemble the command;
QString ID = ui->combo_availscreens->currentText();
- QString DID = ui->combo_cscreens->currentText();
- QString loc = ui->combo_location->currentData().toString();
- if(ID.isEmpty() || DID.isEmpty() || loc.isEmpty()){ return; } //invalid inputs
- QStringList opts = currentOpts();
- opts << "--output" << ID << loc << DID <<"--auto";
- //qDebug() << "Activate Options:" << opts;
- LUtils::runCmd("xrandr", opts );
- QTimer::singleShot(500, this, SLOT(UpdateScreens()) );
-}
-
-void MainUI::ApplyChanges(){
- //NOTE: need to re-specifiy the
- QListWidgetItem *it = ui->list_screens->currentItem();
- if(it==0){ return; } //nothing to do
- QString newres = ui->combo_resolution->currentData().toString();
- if(newres.isEmpty()){ return; } //nothing to do
- //qDebug() << "Apply Screen Changes" << it->whatsThis() << "->" << newres;
- //Adjust the order of the two screens
- bool setprimary = ui->check_primary->isChecked();
+ QStringList res = ui->combo_resolutions->currentText().split("x");
+ //Find the screen infor associated with this ID
for(int i=0; i<SCREENS.length(); i++){
- if(SCREENS[i].ID == it->whatsThis()){
- SCREENS[i].geom.setWidth(newres.section("x",0,0).toInt());
- SCREENS[i].geom.setHeight(newres.section("x",1,1).toInt());
+ if(SCREENS[i].ID==ID){
+ SCREENS[i].isactive = true;
+ SCREENS[i].geom.setSize( QSize(res[0].toInt(), res[1].toInt()) );
+ SCREENS[i].applyChange = 2; //need to activate this monitor
+ AddScreenToWidget(SCREENS[i]);
+ break;
}
- if(setprimary){ SCREENS[i].isprimary = SCREENS[i].ID==it->whatsThis(); }
}
+ tileScreensX(true);
+ //Now remove that option from the "new" list
+ ui->combo_availscreens->removeItem(ui->combo_availscreens->currentIndex());
+ if(ui->combo_availscreens->count()<1){
+ ui->group_avail->setVisible(false);
+ ui->tabWidget->setCurrentIndex(0);
+ ui->tabWidget->setTabEnabled(1,false);
+ }else{
+ ui->group_avail->setVisible(true);
+ ui->tabWidget->setTabEnabled(1,true);
+ }
+}
+
+void MainUI::ApplyChanges(){
+ SyncBackend();
//Now run the command
- QStringList opts = currentOpts();
- LUtils::runCmd("xrandr", opts);
+ RRSettings::Apply(SCREENS);
+ //And update the UI and WM in a moment
QTimer::singleShot(500, this, SLOT(UpdateScreens()) );
+ QTimer::singleShot(1000, this, SLOT(RestartFluxbox()) );
+}
+
+void MainUI::SaveSettings(){
+ SyncBackend();
+ RRSettings::SaveScreens(SCREENS);
+}
+
+void MainUI::RestartFluxbox(){
+ QProcess::startDetached("killall fluxbox");
}
diff --git a/src-qt5/core-utils/lumina-xconfig/MainUI.h b/src-qt5/core-utils/lumina-xconfig/MainUI.h
index 5a1a62cc..d1abc153 100644
--- a/src-qt5/core-utils/lumina-xconfig/MainUI.h
+++ b/src-qt5/core-utils/lumina-xconfig/MainUI.h
@@ -11,6 +11,10 @@
#include <QRect>
#include <QString>
#include <QList>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QMenu>
+#include <QAction>
#include "ScreenSettings.h"
@@ -34,20 +38,32 @@ public slots:
private:
Ui::MainUI *ui;
QList<ScreenInfo> SCREENS;
+ double scaleFactor;
+ QMenu *singleTileMenu;
+
ScreenInfo currentScreenInfo();
- QStringList currentOpts();
+ //QStringList currentOpts();
+ QString currentSelection();
void AddScreenToWidget(ScreenInfo);
+ void SyncBackend(); //sync backend structures to current settings
private slots:
void UpdateScreens();
void ScreenSelected();
- void MoveScreenLeft();
- void MoveScreenRight();
- void DeactivateScreen(QString device = "");
+ void updateNewScreenResolutions();
+ void tileScreensY(bool activeonly = false);
+ void tileScreensX(bool activeonly = false);
+ void tileScreens();
+ void tileSingleScreen(QAction*);
+ void showMenu(){ singleTileMenu->popup(QCursor::pos()); }
+
+ void DeactivateScreen();
void ActivateScreen();
void ApplyChanges(); //config changes
+ void SaveSettings();
+ void RestartFluxbox();
};
#endif
diff --git a/src-qt5/core-utils/lumina-xconfig/MainUI.ui b/src-qt5/core-utils/lumina-xconfig/MainUI.ui
index de1cc18d..872df95b 100644
--- a/src-qt5/core-utils/lumina-xconfig/MainUI.ui
+++ b/src-qt5/core-utils/lumina-xconfig/MainUI.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>408</width>
- <height>321</height>
+ <width>560</width>
+ <height>548</height>
</rect>
</property>
<property name="windowTitle">
@@ -18,52 +18,41 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
- <widget class="QListWidget" name="list_screens">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <widget class="QMdiArea" name="mdiArea">
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAsNeeded</enum>
</property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>100</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>100</height>
- </size>
- </property>
- <property name="flow">
- <enum>QListView::LeftToRight</enum>
- </property>
- <property name="viewMode">
- <enum>QListView::ListMode</enum>
- </property>
- <property name="uniformItemSizes">
- <bool>true</bool>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- <property name="selectionRectVisible">
- <bool>true</bool>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAsNeeded</enum>
</property>
</widget>
</item>
<item>
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QToolButton" name="tool_deactivate">
+ <property name="toolTip">
+ <string>Disable Current Screen</string>
+ </property>
<property name="text">
- <string>...</string>
+ <string notr="true">...</string>
</property>
</widget>
</item>
<item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -71,22 +60,42 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
- <height>0</height>
+ <height>40</height>
</size>
</property>
</spacer>
</item>
<item>
- <widget class="QToolButton" name="tool_moveleft">
+ <widget class="QToolButton" name="tool_tileX">
<property name="text">
- <string>...</string>
+ <string notr="true">...</string>
+ </property>
+ <property name="icon">
+ <iconset theme="format-view-column"/>
</property>
</widget>
</item>
<item>
- <widget class="QToolButton" name="tool_moveright">
+ <widget class="QToolButton" name="tool_tileY">
<property name="text">
- <string>...</string>
+ <string notr="true">...</string>
+ </property>
+ <property name="icon">
+ <iconset theme="format-view-agenda"/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tool_tile">
+ <property name="toolTip">
+ <string>Tile Screens</string>
+ </property>
+ <property name="text">
+ <string notr="true">...</string>
+ </property>
+ <property name="icon">
+ <iconset theme="format-view-grid-small">
+ <normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
@@ -97,7 +106,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
- <number>0</number>
+ <number>1</number>
</property>
<widget class="QWidget" name="tab_config">
<attribute name="title">
@@ -142,47 +151,23 @@
</item>
</layout>
</item>
- <item row="2" column="1">
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
+ <property name="text">
+ <string>Rotation:</string>
</property>
- </spacer>
- </item>
- <item row="3" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QToolButton" name="tool_applyconfig">
- <property name="text">
- <string>Apply Settings</string>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
- </property>
- </widget>
- </item>
- </layout>
+ </widget>
</item>
<item row="1" column="1">
+ <widget class="QComboBox" name="combo_rotation"/>
+ </item>
+ <item row="2" column="1">
<widget class="QCheckBox" name="check_primary">
<property name="text">
<string>Primary Screen</string>
@@ -208,6 +193,13 @@
<string>Available Screens</string>
</property>
<layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="2">
+ <widget class="QPushButton" name="push_activate">
+ <property name="text">
+ <string>Enable Screen</string>
+ </property>
+ </widget>
+ </item>
<item row="0" column="0">
<widget class="QComboBox" name="combo_availscreens">
<property name="toolTip">
@@ -216,26 +208,12 @@
</widget>
</item>
<item row="0" column="1">
- <widget class="QComboBox" name="combo_location">
+ <widget class="QComboBox" name="combo_resolutions">
<property name="toolTip">
<string>Location to insert the screen</string>
</property>
</widget>
</item>
- <item row="0" column="2">
- <widget class="QComboBox" name="combo_cscreens">
- <property name="toolTip">
- <string>Current screens</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="push_activate">
- <property name="text">
- <string>Enable Screen</string>
- </property>
- </widget>
- </item>
</layout>
</widget>
</item>
@@ -279,6 +257,33 @@
</spacer>
</item>
<item>
+ <widget class="QToolButton" name="tool_applyconfig">
+ <property name="text">
+ <string>Apply</string>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tool_save">
+ <property name="toolTip">
+ <string>Save current settings as user defaults</string>
+ </property>
+ <property name="text">
+ <string>Save</string>
+ </property>
+ <property name="icon">
+ <iconset theme="document-save">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QPushButton" name="push_close">
<property name="text">
<string>Close</string>
diff --git a/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp b/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp
index 91e1f498..99cfc918 100644
--- a/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp
+++ b/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp
@@ -21,33 +21,26 @@ void RRSettings::ApplyPrevious(){
QString primary;
QStringList avail;
for(int i=0; i<screens.length(); i++){
- //if(screens[i].order>=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
+ screens[i].applyChange = (screens[i].isactive && !lastactive.contains(screens[i].ID) ? 1 : 0); //disable/ignore
+ screens[i].rotation = set.value("rotation",0).toInt();
set.endGroup();
- }else if(screens[i].isavailable){
- screens[i].order = -2; //needs activation/placement
- }else{
- screens[i].order = -3; //ignored
+ }else if(screens[i].isactive){
+ screens[i].applyChange = 1; //disable monitor - not enabled in the default settings
}
- //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; }
+ 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
+ //"LVDS" or "eDP" is the built-in laptop display normally
if(primary.isEmpty()){
- QStringList priority; priority << "LVDS" << "DP" << "HDMI" << "DVI" << "VGA";
+ QStringList priority; priority << "LVDS" << "eDP" << "DP" << "HDMI" << "DVI" << "VGA";
for(int i=0; i<priority.length() && primary.isEmpty(); i++){
QStringList filter = avail.filter(priority[i]);
if(!filter.isEmpty()){ filter.sort(); primary = filter.first(); }
@@ -55,44 +48,8 @@ void RRSettings::ApplyPrevious(){
if(primary.isEmpty()){ primary = avail.first(); }
}
//Ensure only one monitor is primary, and reset a few flags
- for(int i=0; i<screens.length(); i++){
- if(screens[i].ID!=primary){ screens[i].isprimary = false; }
- screens[i].isactive = true; //we want all these monitors to be active eventually
- }
- // Handle all the available monitors
- int handled = 0;
- int cx = 0; //current x point
- while(handled<screens.length()){
- //Go through horizontally and place monitors (TO-DO: Vertical placement not handled yet)
- int next = -1;
- int diff = -1;
- for(int i=0; i<screens.length(); i++){
- if(screens[i].order==-1){
- if(diff<0 || ((screens[i].geom.x()-cx) < diff)){
- diff = screens[i].geom.x()-cx;
- next = i;
- }
- }
- }//end loop over screens
- if(next<0){
- //Go through and start adding the non-assigned screens to the end
- for(int i=0; i<screens.length(); i++){
- if(screens[i].order==-2){
- if(diff<0 || ((screens[i].geom.x()-cx) < diff)){
- diff = screens[i].geom.x()-cx;
- next = i;
- }
- }
- } //end loop over screens
- }
- if(next>=0){
- cx+=screens[next].geom.width();
- screens[next].order = handled; handled++;
- }else{
- //Still missing monitors (vertical alignment?)
- qDebug() << "Unhandled Monitors:" << screens.length()-handled;
- break;
- }
+ for(int i=0; i<screens.length(); i++){
+ if(screens[i].ID!=primary){ screens[i].isprimary = false; }
}
//Now reset the display with xrandr
RRSettings::Apply(screens);
@@ -106,17 +63,19 @@ QList<ScreenInfo> RRSettings::CurrentScreens(){
for(int i=0; i<info.length(); i++){
if(info[i].contains("connected") ){
//qDebug() << "xrandr info:" << info[i];
- if(!cscreen.ID.isEmpty()){
+ if(!cscreen.ID.isEmpty()){
SCREENS << cscreen; //current screen finished - save it into the array
- cscreen = ScreenInfo(); //Now create a new structure
- }
+ cscreen = ScreenInfo(); //Now create a new structure
+ }
//qDebug() << "Line:" << info[i];
QString dev = info[i].section(" ",0,0); //device ID
//The device resolution can be either the 3rd or 4th output - check both
QString devres = info[i].section(" ",2,2, QString::SectionSkipEmpty);
if(!devres.contains("x")){ devres = info[i].section(" ",3,3,QString::SectionSkipEmpty); }
if(!devres.contains("x")){ devres.clear(); }
- qDebug() << " - ID:" <<dev << "Current Geometry:" << devres;
+ //Pull the monitor rotation mode out as well (last word before the parenthesis)
+ QString devrotate = info[i].section("(",0,0).split(" ",QString::SkipEmptyParts).last();
+ //qDebug() << " - ID:" <<dev << "Current Geometry:" << devres;
//qDebug() << " - Res:" << devres;
if( !devres.contains("x") || !devres.contains("+") ){ devres.clear(); }
//qDebug() << " - Res (modified):" << devres;
@@ -127,17 +86,21 @@ QList<ScreenInfo> RRSettings::CurrentScreens(){
}else if( !devres.isEmpty() ){
cscreen.isprimary = info[i].contains(" primary ");
//Device that is connected and attached (has a resolution)
- qDebug() << "Create new Screen entry:" << dev << devres;
+ //qDebug() << "Create new Screen entry:" << dev << devres << devrotate << info[i].section("(",0,0);
cscreen.ID = dev;
//Note: devres format: "<width>x<height>+<xoffset>+<yoffset>"
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;
+ if(devrotate=="left"){ cscreen.rotation = -90; }
+ else if(devrotate=="right"){ cscreen.rotation = 90; }
+ else if(devrotate=="inverted"){ cscreen.rotation = 180; }
+ else{ cscreen.rotation = 0; }
}else if(info[i].contains(" connected")){
//Device that is connected, but not attached
- qDebug() << "Create new Screen entry:" << dev << "none";
+ //qDebug() << "Create new Screen entry:" << dev << "none";
cscreen.ID = dev;
- cscreen.order = -2; //flag this right now as a non-active screen
+ //cscreen.order = -2; //flag this right now as a non-active screen
cscreen.isavailable = true;
cscreen.isactive = false;
}
@@ -164,6 +127,7 @@ bool RRSettings::SaveScreens(QList<ScreenInfo> screens){
set.beginGroup(screens[i].ID);
set.setValue("geometry", screens[i].geom);
set.setValue("isprimary", screens[i].isprimary);
+ set.setValue("rotation", screens[i].rotation);
set.endGroup();
}
set.setValue("lastActive",active);
@@ -173,17 +137,24 @@ bool RRSettings::SaveScreens(QList<ScreenInfo> screens){
}
return true;
}
-
+
//Apply screen configuration
void RRSettings::Apply(QList<ScreenInfo> screens){
//Read all the settings and create the xrandr options to maintain these settings
QStringList opts;
- qDebug() << "Apply:" << screens.length();
+ //qDebug() << "Apply:" << screens.length();
for(int i=0; i<screens.length(); i++){
- qDebug() << " -- Screen:" << i << screens[i].ID << screens[i].isactive << screens[i].order;
- if(screens[i].order <0 || !screens[i].isactive){ continue; } //skip this screen - non-active
- opts << "--output" << screens[i].ID << "--mode" << QString::number(screens[i].geom.width())+"x"+QString::number(screens[i].geom.height());
+ qDebug() << " -- Screen:" << i << screens[i].ID << screens[i].isactive;
+ if( !screens[i].isactive){ continue; } //skip this screen - non-active
+ else if(screens[i].applyChange==1){ opts << "--output" << screens[i].ID << "--off"; continue; } //deactivate a screen
+ opts << "--output" << screens[i].ID;
+ if(screens[i].applyChange==2){ opts << "--auto"; }
+ else{ opts << "--mode" << QString::number(screens[i].geom.width())+"x"+QString::number(screens[i].geom.height()); }
opts << "--pos" << QString::number(screens[i].geom.x())+"x"+QString::number(screens[i].geom.y());
+ if(screens[i].rotation==-90){ opts << "--rotate" << "left"; }
+ else if(screens[i].rotation==90){ opts << "--rotate" << "right"; }
+ else if(screens[i].rotation==180){ opts << "--rotate" << "inverted"; }
+ else{ opts << "--rotate" << "normal"; }
if(screens[i].isprimary){ opts << "--primary"; }
}
qDebug() << "Run command: xrandr" << opts;
diff --git a/src-qt5/core-utils/lumina-xconfig/ScreenSettings.h b/src-qt5/core-utils/lumina-xconfig/ScreenSettings.h
index 5826f804..b1b9cad9 100644
--- a/src-qt5/core-utils/lumina-xconfig/ScreenSettings.h
+++ b/src-qt5/core-utils/lumina-xconfig/ScreenSettings.h
@@ -13,21 +13,24 @@
#include <QStringList>
class ScreenInfo{
- public:
+ public:
QString ID;
QRect geom; //screen geometry
bool isprimary;
bool isactive;
bool isavailable;
- int order; //left to right
+ int applyChange; //[<=0: do nothing, 1: deactivate, 2: activate]
QStringList resList;
+ int rotation; //possible values: [-90, 0, 90, 180]
+
//Initial Defaults
ScreenInfo(){
- order = -1; //initial value is invalid
+ applyChange = -1; //initial value is invalid
isprimary = false;
isactive = false;
isavailable = false;
+ rotation = 0; //no rotation by default
}
~ScreenInfo(){}
};
@@ -42,9 +45,9 @@ public:
//Save the screen config for later
static bool SaveScreens(QList<ScreenInfo> screens);
-
+
//Apply screen configuration
static void Apply(QList<ScreenInfo> screens);
-};
+};
#endif
diff --git a/src-qt5/core-utils/lumina-xconfig/i18n/lumina-xconfig_en_AU.ts b/src-qt5/core-utils/lumina-xconfig/i18n/lumina-xconfig_en_AU.ts
new file mode 100644
index 00000000..6401616d
--- /dev/null
+++ b/src-qt5/core-utils/lumina-xconfig/i18n/lumina-xconfig_en_AU.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+</TS>
diff --git a/src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro b/src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro
index 2fb792d6..2cfb64ec 100644
--- a/src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro
+++ b/src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro
@@ -38,6 +38,7 @@ TRANSLATIONS = i18n/lumina-xconfig_af.ts \
i18n/lumina-xconfig_el.ts \
i18n/lumina-xconfig_en_GB.ts \
i18n/lumina-xconfig_en_ZA.ts \
+ i18n/lumina-xconfig_en_AU.ts \
i18n/lumina-xconfig_es.ts \
i18n/lumina-xconfig_et.ts \
i18n/lumina-xconfig_eu.ts \
bgstack15