diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/FocusControl.cc | 69 | ||||
-rw-r--r-- | src/FocusControl.hh | 16 | ||||
-rw-r--r-- | src/Window.cc | 30 | ||||
-rw-r--r-- | src/WorkspaceCmd.cc | 34 | ||||
-rw-r--r-- | src/fluxbox.cc | 35 |
5 files changed, 73 insertions, 111 deletions
diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 5cbf645..f4c8cdf 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc | |||
@@ -54,7 +54,7 @@ FocusControl::FocusControl(BScreen &screen): | |||
54 | m_focus_new(screen.resourceManager(), true, | 54 | m_focus_new(screen.resourceManager(), true, |
55 | screen.name()+".focusNewWindows", | 55 | screen.name()+".focusNewWindows", |
56 | screen.altName()+".FocusNewWindows"), | 56 | screen.altName()+".FocusNewWindows"), |
57 | m_cycling_focus(false), | 57 | m_cycling_list(0), |
58 | m_was_iconic(false), | 58 | m_was_iconic(false), |
59 | m_cycling_last(0) { | 59 | m_cycling_last(0) { |
60 | 60 | ||
@@ -79,26 +79,25 @@ bool doSkipWindow(const WinClient &winclient, int opts) { | |||
79 | ); | 79 | ); |
80 | } | 80 | } |
81 | 81 | ||
82 | void FocusControl::cycleFocus(int opts, bool cycle_reverse) { | 82 | void FocusControl::cycleFocus(FocusedWindows *window_list, int opts, bool cycle_reverse) { |
83 | 83 | ||
84 | FocusedWindows *window_list = (opts & CYCLELINEAR) ? &m_creation_order_list : &m_focused_list; | 84 | if (!m_cycling_list) { |
85 | if (!m_cycling_focus) { | ||
86 | if (&m_screen == Fluxbox::instance()->watchingScreen()) | 85 | if (&m_screen == Fluxbox::instance()->watchingScreen()) |
87 | m_cycling_focus = true; | 86 | // only set this when we're waiting for modifiers |
88 | m_cycling_window = find(window_list->begin(),window_list->end(),s_focused_window); | 87 | m_cycling_list = window_list; |
89 | m_cycling_creation_order = (opts & CYCLELINEAR); | 88 | m_was_iconic = 0; |
90 | m_was_iconic = false; | ||
91 | m_cycling_last = 0; | 89 | m_cycling_last = 0; |
92 | } else if (m_cycling_creation_order ^ (bool)(opts & CYCLELINEAR)) { | 90 | } else if (m_cycling_list != window_list) |
93 | m_cycling_creation_order ^= true; | 91 | m_cycling_list = window_list; |
94 | m_cycling_window = find(window_list->begin(),window_list->end(),*m_cycling_window); | 92 | |
95 | } | 93 | // too many things can go wrong with remembering this |
96 | // if it is stacked, we want the highest window in the focused list | 94 | m_cycling_window = find(window_list->begin(),window_list->end(),s_focused_window); |
97 | // that is on the same workspace | 95 | |
98 | FocusedWindows::iterator it = m_cycling_window; | 96 | FocusedWindows::iterator it = m_cycling_window; |
99 | FocusedWindows::iterator it_begin = window_list->begin(); | 97 | FocusedWindows::iterator it_begin = window_list->begin(); |
100 | FocusedWindows::iterator it_end = window_list->end(); | 98 | FocusedWindows::iterator it_end = window_list->end(); |
101 | 99 | ||
100 | // find the next window in the list that works | ||
102 | while (true) { | 101 | while (true) { |
103 | if (cycle_reverse && it == it_begin) | 102 | if (cycle_reverse && it == it_begin) |
104 | it = it_end; | 103 | it = it_end; |
@@ -130,12 +129,18 @@ void FocusControl::cycleFocus(int opts, bool cycle_reverse) { | |||
130 | 129 | ||
131 | // set back to orig current Client in that fbwin | 130 | // set back to orig current Client in that fbwin |
132 | m_cycling_last->fbwindow()->setCurrentClient(*m_cycling_last, false); | 131 | m_cycling_last->fbwindow()->setCurrentClient(*m_cycling_last, false); |
132 | if (m_was_iconic == m_cycling_last) { | ||
133 | s_reverting = true; // little hack | ||
134 | m_cycling_last->fbwindow()->iconify(); | ||
135 | s_reverting = false; | ||
136 | } | ||
133 | } | 137 | } |
134 | m_cycling_last = &last_client; | 138 | m_cycling_last = &last_client; |
135 | if (m_was_iconic) | 139 | if (fbwin->isIconic()) |
136 | (*m_cycling_window)->fbwindow()->iconify(); | 140 | m_was_iconic = m_cycling_last; |
137 | m_was_iconic = fbwin->isIconic(); | 141 | if (m_cycling_list) |
138 | fbwin->tempRaise(); | 142 | // else window will raise itself (if desired) on FocusIn |
143 | fbwin->tempRaise(); | ||
139 | } | 144 | } |
140 | break; | 145 | break; |
141 | } | 146 | } |
@@ -158,7 +163,7 @@ void FocusControl::addFocusFront(WinClient &client) { | |||
158 | void FocusControl::setFocusBack(FluxboxWindow *fbwin) { | 163 | void FocusControl::setFocusBack(FluxboxWindow *fbwin) { |
159 | // do nothing if there are no windows open | 164 | // do nothing if there are no windows open |
160 | // don't change focus order while cycling | 165 | // don't change focus order while cycling |
161 | if (m_focused_list.empty() || isCycling()) | 166 | if (m_focused_list.empty() || s_reverting) |
162 | return; | 167 | return; |
163 | 168 | ||
164 | FocusedWindows::iterator it = m_focused_list.begin(); | 169 | FocusedWindows::iterator it = m_focused_list.begin(); |
@@ -181,28 +186,24 @@ void FocusControl::setFocusBack(FluxboxWindow *fbwin) { | |||
181 | 186 | ||
182 | void FocusControl::stopCyclingFocus() { | 187 | void FocusControl::stopCyclingFocus() { |
183 | // nothing to do | 188 | // nothing to do |
184 | if (!m_cycling_focus) | 189 | if (m_cycling_list == 0) |
185 | return; | 190 | return; |
186 | 191 | ||
187 | m_cycling_focus = false; | 192 | FocusedWindows::iterator it_end = m_cycling_list->end(); |
188 | m_cycling_last = 0; | 193 | m_cycling_last = 0; |
194 | m_cycling_list = 0; | ||
195 | |||
189 | // put currently focused window to top | 196 | // put currently focused window to top |
190 | // the iterator may be invalid if the window died | 197 | // the iterator may be invalid if the window died |
191 | // in which case we'll do a proper revert focus | 198 | // in which case we'll do a proper revert focus |
192 | if (m_cycling_creation_order && m_cycling_window != m_creation_order_list.end()) | 199 | if (m_cycling_window != it_end && (*m_cycling_window)->fbwindow() && |
193 | m_cycling_window = find(m_focused_list.begin(),m_focused_list.end(),*m_cycling_window); | ||
194 | if (m_cycling_window != m_focused_list.end() && | ||
195 | m_cycling_window != m_creation_order_list.end() && | ||
196 | (*m_cycling_window)->fbwindow() && | ||
197 | (*m_cycling_window)->fbwindow()->isVisible()) { | 200 | (*m_cycling_window)->fbwindow()->isVisible()) { |
198 | WinClient *client = *m_cycling_window; | 201 | WinClient *client = *m_cycling_window; |
199 | m_focused_list.erase(m_cycling_window); | 202 | m_focused_list.remove(client); |
200 | m_focused_list.push_front(client); | 203 | m_focused_list.push_front(client); |
201 | client->fbwindow()->raise(); | 204 | client->fbwindow()->raise(); |
202 | } else { | 205 | } else |
203 | revertFocus(m_screen); | 206 | revertFocus(m_screen); |
204 | } | ||
205 | |||
206 | } | 207 | } |
207 | 208 | ||
208 | /** | 209 | /** |
@@ -254,7 +255,6 @@ void FocusControl::setScreenFocusedWindow(WinClient &win_client) { | |||
254 | !Fluxbox::instance()->isStartup()) { | 255 | !Fluxbox::instance()->isStartup()) { |
255 | m_focused_list.remove(&win_client); | 256 | m_focused_list.remove(&win_client); |
256 | m_focused_list.push_front(&win_client); | 257 | m_focused_list.push_front(&win_client); |
257 | m_cycling_window = m_focused_list.begin(); | ||
258 | } | 258 | } |
259 | } | 259 | } |
260 | 260 | ||
@@ -370,14 +370,14 @@ void FocusControl::removeClient(WinClient &client) { | |||
370 | return; | 370 | return; |
371 | 371 | ||
372 | WinClient *cyc = 0; | 372 | WinClient *cyc = 0; |
373 | if (m_cycling_window != m_focused_list.end() && m_cycling_window != m_creation_order_list.end()) | 373 | if (m_cycling_list && m_cycling_window != m_cycling_list->end()) |
374 | cyc = *m_cycling_window; | 374 | cyc = *m_cycling_window; |
375 | 375 | ||
376 | m_focused_list.remove(&client); | 376 | m_focused_list.remove(&client); |
377 | m_creation_order_list.remove(&client); | 377 | m_creation_order_list.remove(&client); |
378 | 378 | ||
379 | if (cyc == &client) { | 379 | if (cyc == &client) { |
380 | m_cycling_window = m_creation_order_list.end(); | 380 | m_cycling_window = m_cycling_list->end(); |
381 | stopCyclingFocus(); | 381 | stopCyclingFocus(); |
382 | } | 382 | } |
383 | } | 383 | } |
@@ -402,8 +402,7 @@ void FocusControl::shutdown() { | |||
402 | * it gets a focusIn | 402 | * it gets a focusIn |
403 | */ | 403 | */ |
404 | void FocusControl::revertFocus(BScreen &screen) { | 404 | void FocusControl::revertFocus(BScreen &screen) { |
405 | 405 | if (s_reverting) | |
406 | if (screen.focusControl().isCycling()) | ||
407 | return; | 406 | return; |
408 | 407 | ||
409 | FocusControl::s_reverting = true; | 408 | FocusControl::s_reverting = true; |
diff --git a/src/FocusControl.hh b/src/FocusControl.hh index ee5fe95..ee66b9e 100644 --- a/src/FocusControl.hh +++ b/src/FocusControl.hh | |||
@@ -68,11 +68,9 @@ public: | |||
68 | 68 | ||
69 | explicit FocusControl(BScreen &screen); | 69 | explicit FocusControl(BScreen &screen); |
70 | 70 | ||
71 | void prevFocus() { cycleFocus(0, true); } | 71 | void prevFocus() { cycleFocus(&m_focused_list, 0, true); } |
72 | void nextFocus() { cycleFocus(0, false); } | 72 | void nextFocus() { cycleFocus(&m_focused_list, 0, false); } |
73 | void prevFocus(int options) { cycleFocus(options, true); } | 73 | void cycleFocus(FocusedWindows *winlist, int options, bool reverse = false); |
74 | void nextFocus(int options) { cycleFocus(options, false); } | ||
75 | void cycleFocus(int options, bool cycle_reverse); | ||
76 | 74 | ||
77 | void setScreenFocusedWindow(WinClient &win_client); | 75 | void setScreenFocusedWindow(WinClient &win_client); |
78 | void setFocusModel(FocusModel model); | 76 | void setFocusModel(FocusModel model); |
@@ -83,7 +81,7 @@ public: | |||
83 | void dirFocus(FluxboxWindow &win, FocusDir dir); | 81 | void dirFocus(FluxboxWindow &win, FocusDir dir); |
84 | bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; } | 82 | bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; } |
85 | bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; } | 83 | bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; } |
86 | bool isCycling() const { return m_cycling_focus; } | 84 | bool isCycling() const { return m_cycling_list != 0; } |
87 | void addFocusBack(WinClient &client); | 85 | void addFocusBack(WinClient &client); |
88 | void addFocusFront(WinClient &client); | 86 | void addFocusFront(WinClient &client); |
89 | void setFocusBack(FluxboxWindow *fbwin); | 87 | void setFocusBack(FluxboxWindow *fbwin); |
@@ -120,10 +118,10 @@ private: | |||
120 | // Screen global so it works for sticky windows too. | 118 | // Screen global so it works for sticky windows too. |
121 | FocusedWindows m_focused_list; | 119 | FocusedWindows m_focused_list; |
122 | FocusedWindows m_creation_order_list; | 120 | FocusedWindows m_creation_order_list; |
121 | |||
123 | FocusedWindows::iterator m_cycling_window; | 122 | FocusedWindows::iterator m_cycling_window; |
124 | bool m_cycling_focus; | 123 | FocusedWindows *m_cycling_list; |
125 | bool m_cycling_creation_order; | 124 | WinClient *m_was_iconic; |
126 | bool m_was_iconic; | ||
127 | WinClient *m_cycling_last; | 125 | WinClient *m_cycling_last; |
128 | 126 | ||
129 | static WinClient *s_focused_window; | 127 | static WinClient *s_focused_window; |
diff --git a/src/Window.cc b/src/Window.cc index 27992f0..4e02bfe 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -777,36 +777,14 @@ void FluxboxWindow::nextClient() { | |||
777 | if (numClients() <= 1) | 777 | if (numClients() <= 1) |
778 | return; | 778 | return; |
779 | 779 | ||
780 | ClientList::iterator it = find(m_clientlist.begin(), m_clientlist.end(), m_client); | 780 | screen().focusControl().cycleFocus(&m_clientlist, 0); |
781 | WinClient *client = 0; | ||
782 | if (it == m_clientlist.end()) { | ||
783 | client = m_clientlist.front(); | ||
784 | } else { | ||
785 | it++; | ||
786 | if (it == m_clientlist.end()) | ||
787 | client = m_clientlist.front(); | ||
788 | else | ||
789 | client = *it; | ||
790 | } | ||
791 | setCurrentClient(*client, true); | ||
792 | } | 781 | } |
793 | 782 | ||
794 | void FluxboxWindow::prevClient() { | 783 | void FluxboxWindow::prevClient() { |
795 | if (numClients() <= 1) | 784 | if (numClients() <= 1) |
796 | return; | 785 | return; |
797 | 786 | ||
798 | ClientList::iterator it = find(m_clientlist.begin(), m_clientlist.end(), m_client); | 787 | screen().focusControl().cycleFocus(&m_clientlist, 0, true); |
799 | WinClient *client = 0; | ||
800 | if (it == m_clientlist.end()) { | ||
801 | client = m_clientlist.front(); | ||
802 | } else { | ||
803 | if (it == m_clientlist.begin()) | ||
804 | client = m_clientlist.back(); | ||
805 | else | ||
806 | client = *(--it); | ||
807 | } | ||
808 | |||
809 | setCurrentClient(*client, true); | ||
810 | } | 788 | } |
811 | 789 | ||
812 | 790 | ||
@@ -3909,8 +3887,6 @@ void FluxboxWindow::setupWindow() { | |||
3909 | // sets up our window | 3887 | // sets up our window |
3910 | // we allow both to be done at once to share the commands | 3888 | // we allow both to be done at once to share the commands |
3911 | 3889 | ||
3912 | WinButtonTheme &winbutton_theme = screen().winButtonTheme(); | ||
3913 | |||
3914 | using namespace FbTk; | 3890 | using namespace FbTk; |
3915 | typedef RefCount<Command> CommandRef; | 3891 | typedef RefCount<Command> CommandRef; |
3916 | typedef SimpleCommand<FluxboxWindow> WindowCmd; | 3892 | typedef SimpleCommand<FluxboxWindow> WindowCmd; |
@@ -4024,7 +4000,7 @@ void FluxboxWindow::updateButtons() { | |||
4024 | if (new_size != m_titlebar_buttons[i].size() || need_update) | 4000 | if (new_size != m_titlebar_buttons[i].size() || need_update) |
4025 | need_update = true; | 4001 | need_update = true; |
4026 | else { | 4002 | else { |
4027 | for (int j=0; j < new_size && !need_update; j++) { | 4003 | for (size_t j=0; j < new_size && !need_update; j++) { |
4028 | if ((*(*titlebar_side[i]))[j] != m_titlebar_buttons[i][j]) | 4004 | if ((*(*titlebar_side[i]))[j] != m_titlebar_buttons[i][j]) |
4029 | need_update = true; | 4005 | need_update = true; |
4030 | } | 4006 | } |
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc index 414f942..7d384aa 100644 --- a/src/WorkspaceCmd.cc +++ b/src/WorkspaceCmd.cc | |||
@@ -53,14 +53,19 @@ void NextWindowCmd::execute() { | |||
53 | } else if (ev.type == ButtonPress) { | 53 | } else if (ev.type == ButtonPress) { |
54 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); | 54 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); |
55 | } | 55 | } |
56 | int options = m_option; | ||
56 | if (mods == 0) // can't stacked cycle unless there is a mod to grab | 57 | if (mods == 0) // can't stacked cycle unless there is a mod to grab |
57 | screen->focusControl().nextFocus(m_option | FocusControl::CYCLELINEAR); | 58 | options |= FocusControl::CYCLELINEAR; |
58 | else { | 59 | else |
59 | // if stacked cycling, then set a watch for | 60 | // set a watch for the release of exactly these modifiers |
60 | // the release of exactly these modifiers | ||
61 | fb->watchKeyRelease(*screen, mods); | 61 | fb->watchKeyRelease(*screen, mods); |
62 | screen->focusControl().nextFocus(m_option); | 62 | |
63 | } | 63 | FocusControl::FocusedWindows *win_list = |
64 | (options & FocusControl::CYCLELINEAR) ? | ||
65 | &screen->focusControl().creationOrderList() : | ||
66 | &screen->focusControl().focusedOrderList(); | ||
67 | |||
68 | screen->focusControl().cycleFocus(win_list, m_option); | ||
64 | } | 69 | } |
65 | } | 70 | } |
66 | 71 | ||
@@ -76,14 +81,19 @@ void PrevWindowCmd::execute() { | |||
76 | } else if (ev.type == ButtonPress) { | 81 | } else if (ev.type == ButtonPress) { |
77 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); | 82 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); |
78 | } | 83 | } |
84 | int options = m_option; | ||
79 | if (mods == 0) // can't stacked cycle unless there is a mod to grab | 85 | if (mods == 0) // can't stacked cycle unless there is a mod to grab |
80 | screen->focusControl().prevFocus(m_option | FocusControl::CYCLELINEAR); | 86 | options |= FocusControl::CYCLELINEAR; |
81 | else { | 87 | else |
82 | // if stacked cycling, then set a watch for | 88 | // set a watch for the release of exactly these modifiers |
83 | // the release of exactly these modifiers | ||
84 | fb->watchKeyRelease(*screen, mods); | 89 | fb->watchKeyRelease(*screen, mods); |
85 | screen->focusControl().prevFocus(m_option); | 90 | |
86 | } | 91 | FocusControl::FocusedWindows *win_list = |
92 | (options & FocusControl::CYCLELINEAR) ? | ||
93 | &screen->focusControl().creationOrderList() : | ||
94 | &screen->focusControl().focusedOrderList(); | ||
95 | |||
96 | screen->focusControl().cycleFocus(win_list, m_option, true); | ||
87 | } | 97 | } |
88 | } | 98 | } |
89 | 99 | ||
diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 468e723..89bd0d5 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc | |||
@@ -970,19 +970,7 @@ void Fluxbox::handleButtonEvent(XButtonEvent &be) { | |||
970 | if (be.button == 1 && !screen->isRootColormapInstalled()) | 970 | if (be.button == 1 && !screen->isRootColormapInstalled()) |
971 | screen->imageControl().installRootColormap(); | 971 | screen->imageControl().installRootColormap(); |
972 | 972 | ||
973 | // see if we need to keep watching for key releases | 973 | m_key->doAction(be.type, be.state, be.button); |
974 | BScreen *old_watching_screen = m_watching_screen; | ||
975 | m_watching_screen = 0; | ||
976 | if (!m_key->doAction(be.type, be.state, be.button)) | ||
977 | // no command run, so could still be cycling | ||
978 | m_watching_screen = old_watching_screen; | ||
979 | else if (old_watching_screen && | ||
980 | m_watching_screen != old_watching_screen) { | ||
981 | // no longer need to watch old screen, so stop cycling | ||
982 | old_watching_screen->notifyReleasedKeys(); | ||
983 | if (!m_watching_screen) | ||
984 | XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); | ||
985 | } | ||
986 | } | 974 | } |
987 | 975 | ||
988 | void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) { | 976 | void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) { |
@@ -1113,21 +1101,9 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { | |||
1113 | if (keyScreen() == 0 || mouseScreen() == 0) | 1101 | if (keyScreen() == 0 || mouseScreen() == 0) |
1114 | return; | 1102 | return; |
1115 | 1103 | ||
1116 | BScreen *old_watching_screen = m_watching_screen; | ||
1117 | |||
1118 | switch (ke.type) { | 1104 | switch (ke.type) { |
1119 | case KeyPress: | 1105 | case KeyPress: |
1120 | // see if we need to keep watching for key releases | 1106 | m_key->doAction(ke.type, ke.state, ke.keycode); |
1121 | m_watching_screen = 0; | ||
1122 | if (!m_key->doAction(ke.type, ke.state, ke.keycode)) | ||
1123 | // no command run, so could still be cycling | ||
1124 | m_watching_screen = old_watching_screen; | ||
1125 | else if (old_watching_screen && | ||
1126 | m_watching_screen != old_watching_screen) { | ||
1127 | old_watching_screen->notifyReleasedKeys(); | ||
1128 | if (!m_watching_screen) | ||
1129 | XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); | ||
1130 | } | ||
1131 | break; | 1107 | break; |
1132 | case KeyRelease: { | 1108 | case KeyRelease: { |
1133 | // we ignore most key releases unless we need to use | 1109 | // we ignore most key releases unless we need to use |
@@ -1841,12 +1817,15 @@ void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) { | |||
1841 | cerr<<"WARNING: attempt to grab without modifiers!"<<endl; | 1817 | cerr<<"WARNING: attempt to grab without modifiers!"<<endl; |
1842 | return; | 1818 | return; |
1843 | } | 1819 | } |
1820 | // just make sure we are saving the mods with any other flags (xkb) | ||
1821 | m_watch_keyrelease = FbTk::KeyUtil::instance().isolateModifierMask(mods); | ||
1822 | |||
1823 | if (m_watching_screen == &screen) | ||
1824 | return; | ||
1844 | if (m_watching_screen) | 1825 | if (m_watching_screen) |
1845 | m_watching_screen->focusControl().stopCyclingFocus(); | 1826 | m_watching_screen->focusControl().stopCyclingFocus(); |
1846 | m_watching_screen = &screen; | 1827 | m_watching_screen = &screen; |
1847 | 1828 | ||
1848 | // just make sure we are saving the mods with any other flags (xkb) | ||
1849 | m_watch_keyrelease = FbTk::KeyUtil::instance().isolateModifierMask(mods); | ||
1850 | // TODO: it's possible (and happens to me sometimes) for the mods to be | 1829 | // TODO: it's possible (and happens to me sometimes) for the mods to be |
1851 | // released before we grab the keyboard -- not sure of a good way to fix it | 1830 | // released before we grab the keyboard -- not sure of a good way to fix it |
1852 | XGrabKeyboard(FbTk::App::instance()->display(), | 1831 | XGrabKeyboard(FbTk::App::instance()->display(), |