aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp
blob: d6e0abb66dda8857658ac5373eeb91303a924a55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//===========================================
//  Lumina-desktop source code
//  Copyright (c) 2017, Ken Moore
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
#include "ScreenObject.h"
#include <QQmlEngine>
#include <QDebug>

ScreenObject::ScreenObject(QScreen *scrn, QObject *parent) : QObject(parent){
  bg_screen = scrn;
  connect(this, SIGNAL(changePanels(QStringList)), this, SLOT(setPanels(QStringList)) );
  connect(RootWindowObject::instance(), SIGNAL(sessionGeomAvailableChanged()), this, SLOT(updateAvailableGeometry()) );
}

void ScreenObject::RegisterType(){
  static bool done = false;
  if(done){ return; }
  done=true;
  qmlRegisterType<ScreenObject>("Lumina.Backend.ScreenObject",2,0, "ScreenObject");
  //Also register any types that are needed by this class
  PanelObject::RegisterType();
}

QString ScreenObject::name(){ return bg_screen->name(); }
QString ScreenObject::background(){ return bg; }
int ScreenObject::x(){ return bg_screen->geometry().x(); }
int ScreenObject::y(){ return bg_screen->geometry().y(); }
int ScreenObject::width(){ return bg_screen->geometry().width(); }
int ScreenObject::height(){ return bg_screen->geometry().height(); }

void ScreenObject::setBackground(QString fileOrColor){
  if(bg!=fileOrColor){
    bg = fileOrColor;
    emit backgroundChanged();
  }
}

void ScreenObject::setPanels(QList<PanelObject*> list){
  panel_objects = list;
  emit panelsChanged();
}

void ScreenObject::setPanels(QStringList ids){
  //Make this thread-safe for object creation
  if(this->thread() != QThread::currentThread()){
    //use internal signal/slot combo to change threads
    this->emit changePanels(ids);
    return;
  }

  QRegion *sess = RootDesktopObject::instance()->availableGeometry();
  QRect avail = sess->intersected(bg_screen->geometry()).boundingRect();
  if(session_available_geometry.isNull()){ avail = bg_screen->geometry(); }
  //First update/remove any current panel objects
  bool change = false;
  for(int i=0; i<panel_objects.length(); i++){
    if(ids.contains(panel_objects[i]->name()) ){
      ids.removeAll(panel_objects[i]->name()); //already handled
      panel_objects[i]->syncWithSettings(avail);
    }else{
      panel_objects.takeAt(i)->deleteLater();
      i--;
      change = true; //list changed
    }
  }
  //Now create any new panel objects as needed
  for(int i=0; i<ids.length(); i++){
    PanelObject *tmp = new PanelObject(ids[i], this);
    tmp->syncWithSettings(bg_screen->geometry());
    panel_objects << tmp;
    change = true; //list changed
  }
  if(change){ emit panelsChanged(); }
}


//QML Read Functions
QStringList ScreenObject::panels(){
  //qDebug() << "Request Panels:" << panel_objects.length();
  QStringList names;
  for(int i=0; i<panel_objects.length(); i++){ names << panel_objects[i]->name(); }
  return names;
}

PanelObject* ScreenObject::panel(QString id){
  //qDebug() << "Got Panel Request:" << id;
  for(int i=0; i<panel_objects.length(); i++){
    if(panel_objects[i]->name()==id){ return panel_objects[i]; }
  }
  return 0;
}

QRect ScreenObject::availableGeometry(){
  return avail_geom;
}

void ScreenObject::updateAvailableGeometry(){
  QRegion *sess = RootDesktopObject::instance()->availableGeometry();
  QRegion availRegion = sess->intersected(bg_screen->geometry());
  QRect avail = availRegion.boundingRect();
  for(int i=0; i<panel_objects.length(); i++){
    panel_objects[i]->syncWithSettings(avail);
    //Note: Use the "full side" geometry to ensure that we are cleanly cutting off the entire side of the region
    availRegion = availRegion.subtracted( panel_objects[i]->fullSideGeometry() );
  }
  avail = availRegion.boundingRect();
  if(avail != avail_geom){
    avail_geom = avail;
    emit availableGeomChanged();
  }
}
bgstack15