1 #include "root.h"
2 
3 #include <memory>
4 
5 #include "client.h"
6 #include "clientmanager.h"
7 #include "ewmh.h"
8 #include "hlwmcommon.h"
9 #include "keymanager.h"
10 #include "layout.h"
11 #include "metacommands.h"
12 #include "monitormanager.h"
13 #include "mousemanager.h"
14 #include "panelmanager.h"
15 #include "rulemanager.h"
16 #include "settings.h"
17 #include "tag.h"
18 #include "tagmanager.h"
19 #include "theme.h"
20 #include "tmp.h"
21 #include "utils.h"
22 #include "watchers.h"
23 
24 using std::shared_ptr;
25 
26 shared_ptr<Root> Root::root_;
27 
Root(Globals g,XConnection & xconnection,IpcServer & ipcServer)28 Root::Root(Globals g, XConnection& xconnection, IpcServer& ipcServer)
29     : clients(*this, "clients")
30     , keys(*this, "keys")
31     , monitors(*this, "monitors")
32     , mouse(*this, "mouse")
33     , rules(*this, "rules")
34     , settings(*this, "settings")
35     , tags(*this, "tags")
36     , theme(*this, "theme")
37     , tmp(*this, TMP_OBJECT_PATH)
38     , watchers(*this, "watchers")
39     , globals(g)
40     , meta_commands(make_unique<MetaCommands>(*this))
41     , X(xconnection)
42     , ipcServer_(ipcServer)
43     , panels(make_unique<PanelManager>(xconnection))
44     , ewmh(make_unique<Ewmh>(xconnection))
45 {
46     // initialize root children (alphabetically)
47     clients.init();
48     keys.init();
49     monitors.init();
50     mouse.init();
51     rules.init();
52     settings.init();
53     tags.init();
54     theme.init();
55     tmp.init();
56     watchers.init();
57 
58     // inject dependencies where needed
59     ewmh->injectDependencies(this);
60     settings->injectDependencies(this);
61     tags->injectDependencies(monitors(), settings());
62     clients->injectDependencies(settings(), theme(), ewmh.get());
63     monitors->injectDependencies(settings(), tags(), panels.get());
64     mouse->injectDependencies(clients(), monitors());
65     panels->injectDependencies(settings());
66     watchers->injectDependencies(this);
67 
68     // set temporary globals
69     ::global_tags = tags();
70     ::g_monitors = monitors();
71 
72     // connect slots
73     clients->needsRelayout.connect(monitors(), &MonitorManager::relayoutTag);
74     tags->needsRelayout_.connect(monitors(), &MonitorManager::relayoutTag);
75     clients->clientStateChanged.connect([](Client* c) {
76         c->tag()->applyClientState(c);
77     });
78     theme->theme_changed_.connect(monitors(), &MonitorManager::relayoutAll);
79     panels->panels_changed_.connect(monitors(), &MonitorManager::autoUpdatePads);
80 }
81 
~Root()82 Root::~Root()
83 {
84     // Note: delete in reverse order of initialization!
85     mouse.reset();
86     // ClientManager and MonitorManager have circular dependencies, but only
87     // MonitorManager needs the other for shutting down, so we do that first:
88     monitors.reset();
89 
90     // Shut down children with dependencies first:
91     clients.reset();
92     tags.reset();
93 
94     // For the rest, order does not matter (do it alphabetically):
95     keys.reset();
96     rules.reset();
97     settings.reset();
98     theme.reset();
99     tmp.reset();
100 
101     children_.clear(); // avoid possible circular shared_ptr dependency
102 }
103 
focusFrame(shared_ptr<FrameLeaf> frameToFocus)104 void Root::focusFrame(shared_ptr<FrameLeaf> frameToFocus)
105 {
106     Monitor* monitor = monitors->byFrame(frameToFocus);
107     if (!monitor) {
108         return;
109     }
110     monitors->lock();
111     monitor->tag->focusFrame(frameToFocus);
112     monitor_focus_by_index(static_cast<unsigned int>(monitor->index()));
113     monitors->unlock();
114 }
115 
common()116 HlwmCommon Root::common() {
117     return HlwmCommon(Root::get().get());
118 }
119 
120