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