1
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
5
* Copyright (c) 2010-11 Canonical Ltd.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* Your own copyright notice would go above. You are free to choose whatever
18
* licence you want, just take note that some compiz code is GPL and you will
19
* not be able to re-use it if you want to use a different licence.
22
#include <NuxCore/Logger.h>
24
#include <Nux/HLayout.h>
25
#include <Nux/BaseWindow.h>
26
#include <Nux/WindowCompositor.h>
28
#include "IconRenderer.h"
30
#include "LauncherIcon.h"
31
#include "LauncherController.h"
32
#include "PlacesSettings.h"
33
#include "GeisAdapter.h"
34
#include "DevicesSettings.h"
35
#include "PluginAdapter.h"
36
#include "StartupNotifyService.h"
38
#include "unityshell.h"
39
#include "BackgroundEffectHelper.h"
41
#include <dbus/dbus.h>
42
#include <dbus/dbus-glib.h>
43
#include <glib/gi18n-lib.h>
46
#include <libnotify/notify.h>
50
#include <core/atoms.h>
52
#include "unitya11y.h"
54
#include "ubus-server.h"
55
#include "UBusMessages.h"
59
/* FIXME: once we get a better method to add the toplevel windows to
60
the accessible root object, this include would not be required */
61
#include "unity-util-accessible.h"
63
using namespace unity::switcher;
65
/* Set up vtable symbols */
66
COMPIZ_PLUGIN_20090315(unityshell, UnityPluginVTable);
68
using ::unity::logger::Timer;
73
nux::logging::Logger logger("unity.shell");
75
UnityScreen* uScreen = 0;
77
void configure_logging();
78
void capture_g_log_calls(const gchar* log_domain,
79
GLogLevelFlags log_level,
82
gboolean is_extension_supported(const gchar* extensions, const gchar* extension);
83
gfloat get_opengl_version_f32(const gchar* version_string);
87
UnityScreen::UnityScreen(CompScreen* screen)
88
: BaseSwitchScreen (screen)
89
, PluginClassHandler <UnityScreen, CompScreen> (screen)
91
, cScreen(CompositeScreen::get(screen))
92
, gScreen(GLScreen::get(screen))
95
, panelController(nullptr)
96
, switcherController(nullptr)
97
, gestureEngine(nullptr)
99
, launcherWindow(nullptr)
100
, panelWindow(nullptr)
102
, needsRelayout(false)
103
, relayoutSourceId(0)
104
, _edge_trigger_handle(0)
106
, newFocusedWindow(nullptr)
107
, lastFocusedWindow(nullptr)
108
, doShellRepaint(false)
109
, allowWindowPaint(false)
111
, _key_nav_mode_requested(false)
112
, _last_output(nullptr)
113
, switcher_desktop_icon(nullptr)
118
LOG_DEBUG(logger) << __PRETTY_FUNCTION__;
119
int (*old_handler)(Display*, XErrorEvent*);
120
old_handler = XSetErrorHandler(NULL);
122
notify_init("unityshell");
125
dbus_g_thread_init();
127
unity_a11y_preset_environment();
129
XSetErrorHandler(old_handler);
131
/* Wrap compiz interfaces */
132
ScreenInterface::setHandler(screen);
133
CompositeScreenInterface::setHandler(cScreen);
134
GLScreenInterface::setHandler(gScreen);
136
PluginAdapter::Initialize(screen);
137
WindowManager::SetDefault(PluginAdapter::Default());
139
StartupNotifyService::Default()->SetSnDisplay(screen->snDisplay(), screen->screenNum());
141
nux::NuxInitialize(0);
142
wt = nux::CreateFromForeignWindow(cScreen->output(),
143
glXGetCurrentContext(),
144
&UnityScreen::initUnity,
147
wt->RedrawRequested.connect(sigc::mem_fun(this, &UnityScreen::onRedrawRequested));
152
bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
153
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
158
debugger = new DebugDBusInterface(this);
160
_edge_timeout = optionGetLauncherRevealEdgeTimeout ();
164
foreach (CompOutput &o, screen->outputDevs ())
165
uScreen->mFbos[&o] = UnityFBO::Ptr (new UnityFBO (&o));
167
uScreen->mFbos[&(screen->fullscreenOutput ())] = UnityFBO::Ptr (new UnityFBO (&(screen->fullscreenOutput ())));
170
optionSetLauncherHideModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
171
optionSetBacklightModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
172
optionSetLaunchAnimationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
173
optionSetUrgentAnimationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
174
optionSetPanelOpacityNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
175
optionSetLauncherOpacityNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
176
optionSetIconSizeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
177
optionSetAutohideAnimationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
178
optionSetDashBlurExperimentalNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
179
optionSetDevicesOptionNotify(boost::bind (&UnityScreen::optionChanged, this, _1, _2));
180
optionSetShowLauncherInitiate(boost::bind(&UnityScreen::showLauncherKeyInitiate, this, _1, _2, _3));
181
optionSetShowLauncherTerminate(boost::bind(&UnityScreen::showLauncherKeyTerminate, this, _1, _2, _3));
182
optionSetKeyboardFocusInitiate(boost::bind(&UnityScreen::setKeyboardFocusKeyInitiate, this, _1, _2, _3));
183
//optionSetKeyboardFocusTerminate (boost::bind (&UnityScreen::setKeyboardFocusKeyTerminate, this, _1, _2, _3));
184
optionSetExecuteCommandInitiate(boost::bind(&UnityScreen::executeCommand, this, _1, _2, _3));
185
optionSetPanelFirstMenuInitiate(boost::bind(&UnityScreen::showPanelFirstMenuKeyInitiate, this, _1, _2, _3));
186
optionSetPanelFirstMenuTerminate(boost::bind(&UnityScreen::showPanelFirstMenuKeyTerminate, this, _1, _2, _3));
187
optionSetLauncherRevealEdgeInitiate(boost::bind(&UnityScreen::launcherRevealEdgeInitiate, this, _1, _2, _3));
188
optionSetLauncherRevealEdgeTimeoutNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
189
optionSetAutomaximizeValueNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
190
optionSetAltTabTimeoutNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
192
optionSetAltTabForwardInitiate(boost::bind(&UnityScreen::altTabForwardInitiate, this, _1, _2, _3));
193
optionSetAltTabForwardTerminate(boost::bind(&UnityScreen::altTabForwardTerminate, this, _1, _2, _3));
195
optionSetAltTabPrevInitiate(boost::bind(&UnityScreen::altTabPrevInitiate, this, _1, _2, _3));
196
optionSetAltTabPrevTerminate(boost::bind(&UnityScreen::altTabPrevTerminate, this, _1, _2, _3));
198
optionSetAltTabDetailStartInitiate(boost::bind(&UnityScreen::altTabDetailStartInitiate, this, _1, _2, _3));
199
optionSetAltTabDetailStartTerminate(boost::bind(&UnityScreen::altTabDetailStartTerminate, this, _1, _2, _3));
201
optionSetAltTabDetailStopInitiate(boost::bind(&UnityScreen::altTabDetailStopInitiate, this, _1, _2, _3));
202
optionSetAltTabDetailStopTerminate(boost::bind(&UnityScreen::altTabDetailStopTerminate, this, _1, _2, _3));
204
optionSetAltTabNextWindowInitiate(boost::bind(&UnityScreen::altTabNextWindowInitiate, this, _1, _2, _3));
205
optionSetAltTabNextWindowTerminate(boost::bind(&UnityScreen::altTabNextWindowTerminate, this, _1, _2, _3));
207
optionSetAltTabExitInitiate(boost::bind(&UnityScreen::altTabExitInitiate, this, _1, _2, _3));
208
optionSetAltTabExitTerminate(boost::bind(&UnityScreen::altTabExitTerminate, this, _1, _2, _3));
211
for (unsigned int i = 0; i < G_N_ELEMENTS(_ubus_handles); i++)
212
_ubus_handles[i] = 0;
214
UBusServer* ubus = ubus_server_get_default();
215
_ubus_handles[0] = ubus_server_register_interest(ubus,
216
UBUS_LAUNCHER_START_KEY_NAV,
217
(UBusCallback)&UnityScreen::OnLauncherStartKeyNav,
220
_ubus_handles[1] = ubus_server_register_interest(ubus,
221
UBUS_LAUNCHER_END_KEY_NAV,
222
(UBusCallback)&UnityScreen::OnLauncherEndKeyNav,
225
_ubus_handles[2] = ubus_server_register_interest(ubus,
226
UBUS_QUICKLIST_END_KEY_NAV,
227
(UBusCallback)&UnityScreen::OnQuicklistEndKeyNav,
230
g_timeout_add(0, &UnityScreen::initPluginActions, this);
232
GeisAdapter::Default(screen)->Run();
233
gestureEngine = new GestureEngine(screen);
235
CompString name(PKGDATADIR"/panel-shadow.png");
236
CompString pname("unityshell");
237
CompSize size(1, 20);
238
_shadow_texture = GLTexture::readImageToTexture(name, pname, size);
240
ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_SHOWN, [&](GVariant* args) { dash_is_open_ = true; });
241
ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_HIDDEN, [&](GVariant* args) { dash_is_open_ = false; });
245
LOG_INFO(logger) << "UnityScreen constructed: " << timer.ElapsedSeconds() << "s";
248
UnityScreen::~UnityScreen()
250
panelController->UnReference();
252
launcher->UnReference();
253
launcherWindow->UnReference();
257
unity_a11y_finalize();
259
UBusServer* ubus = ubus_server_get_default();
260
for (unsigned int i = 0; i < G_N_ELEMENTS(_ubus_handles); i++)
262
if (_ubus_handles[i] != 0)
263
ubus_server_unregister_interest(ubus, _ubus_handles[i]);
266
if (relayoutSourceId != 0)
267
g_source_remove(relayoutSourceId);
269
// Deleting the windows thread calls XCloseDisplay, which calls XSync, which
270
// sits waiting for a reply.
273
::unity::ui::IconRenderer::DestroyTextures();
276
void UnityScreen::EnsureKeybindings()
278
for (auto action : _shortcut_actions)
279
screen->removeAction(action.get());
281
_shortcut_actions.clear ();
283
for (auto icon : *(launcher->GetModel()))
285
guint64 shortcut = icon->GetShortcut();
289
CompActionPtr action(new CompAction());
291
CompAction::KeyBinding binding;
292
std::ostringstream sout;
293
sout << "<Super>" << static_cast<char>(shortcut);
294
binding.fromString(sout.str());
296
action->setKey(binding);
298
screen->addAction(action.get());
299
_shortcut_actions.push_back(action);
303
void UnityScreen::nuxPrologue()
305
/* Vertex lighting isn't used in Unity, we disable that state as it could have
306
* been leaked by another plugin. That should theoretically be switched off
307
* right after PushAttrib since ENABLE_BIT is meant to restore the LIGHTING
308
* bit, but we do that here in order to workaround a bug (?) in the NVIDIA
309
* drivers (lp:703140). */
310
glDisable(GL_LIGHTING);
313
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT |
314
GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT | GL_SCISSOR_BIT);
316
glMatrixMode(GL_PROJECTION);
319
glMatrixMode(GL_MODELVIEW);
325
void UnityScreen::nuxEpilogue()
327
(*GL::bindFramebuffer)(GL_FRAMEBUFFER_EXT, mActiveFbo);
329
glMatrixMode(GL_PROJECTION);
331
glMatrixMode(GL_MODELVIEW);
334
glViewport(-1, -1, 2, 2);
337
gScreen->resetRasterPos();
339
glMatrixMode(GL_PROJECTION);
341
glMatrixMode(GL_MODELVIEW);
344
glDrawBuffer(GL_BACK);
345
glReadBuffer(GL_BACK);
349
glDisable(GL_SCISSOR_TEST);
352
void UnityScreen::OnLauncherHiddenChanged()
354
if (launcher->Hidden())
355
screen->addAction(&optionGetLauncherRevealEdge());
357
screen->removeAction(&optionGetLauncherRevealEdge());
360
void UnityScreen::paintPanelShadow(const GLMatrix& matrix)
362
if (relayoutSourceId > 0)
365
if (PluginAdapter::Default()->IsExpoActive())
370
CompOutput* output = _last_output;
374
float panel_h = 24.0f;
376
float x1 = output->x();
378
float x2 = x1 + output->width();
388
foreach(GLTexture * tex, _shadow_texture)
391
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
393
GL::activeTexture(GL_TEXTURE0_ARB);
394
tex->enable(GLTexture::Fast);
396
glTexParameteri(tex->target(), GL_TEXTURE_WRAP_S, GL_REPEAT);
400
glTexCoord2f(COMP_TEX_COORD_X(tex->matrix(), 0), COMP_TEX_COORD_Y(tex->matrix(), 0));
401
glVertex2f(vc[0], vc[2]);
403
glTexCoord2f(COMP_TEX_COORD_X(tex->matrix(), 0), COMP_TEX_COORD_Y(tex->matrix(), h));
404
glVertex2f(vc[0], vc[3]);
406
glTexCoord2f(COMP_TEX_COORD_X(tex->matrix(), w), COMP_TEX_COORD_Y(tex->matrix(), h));
407
glVertex2f(vc[1], vc[3]);
409
glTexCoord2f(COMP_TEX_COORD_X(tex->matrix(), w), COMP_TEX_COORD_Y(tex->matrix(), 0));
410
glVertex2f(vc[1], vc[2]);
422
UnityWindow::updateIconPos (int &wx,
429
wx = x + (last_bound.width - width) / 2;
430
wy = y + (last_bound.height - height) / 2;
433
void UnityScreen::paintDisplay(const CompRegion& region, const GLMatrix& transform, unsigned int mask)
435
CompOutput *output = _last_output;
437
mFbos[output]->unbind ();
439
/* Draw the bit of the relevant framebuffer for each output */
440
mFbos[output]->paint ();
443
nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture =
444
nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(mFbos[output]->texture(),
445
output->width(), output->height(), 1, nux::BITFMT_R8G8B8A8);
447
nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture;
449
nux::Geometry geo = nux::Geometry (output->x (), output->y (), output->width (), output->height ());
451
wt->RenderInterfaceFromForeignCmd (&geo);
454
if (switcherController->Visible ())
456
LayoutWindowList targets = switcherController->ExternalRenderTargets ();
458
for (LayoutWindow::Ptr target : targets)
460
CompWindow* window = screen->findWindow(target->xid);
461
UnityWindow *unity_window = UnityWindow::get (window);
463
unity_window->paintThumbnail (target->result, target->alpha);
467
doShellRepaint = false;
469
BackgroundEffectHelper::updates_enabled = true;
472
void UnityWindow::paintThumbnail (nux::Geometry const& bounding, float alpha)
475
matrix.toScreenSpace (UnityScreen::get (screen)->_last_output, -DEFAULT_Z_CAMERA);
477
nux::Geometry geo = bounding;
486
GLWindowPaintAttrib attrib = gWindow->lastPaintAttrib ();
487
attrib.opacity = (GLushort) (alpha * G_MAXUSHORT);
500
/* called whenever we need to repaint parts of the screen */
501
bool UnityScreen::glPaintOutput(const GLScreenPaintAttrib& attrib,
502
const GLMatrix& transform,
503
const CompRegion& region,
509
/* bind the framebuffer here */
510
mFbos[output]->bind ();
512
doShellRepaint = true;
513
allowWindowPaint = true;
514
_last_output = output;
516
/* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
517
ret = gScreen->glPaintOutput(attrib, transform, region, output, mask);
520
paintDisplay(region, transform, mask);
525
/* called whenever a plugin needs to paint the entire scene
528
void UnityScreen::glPaintTransformedOutput(const GLScreenPaintAttrib& attrib,
529
const GLMatrix& transform,
530
const CompRegion& region,
534
/* bind the framebuffer here */
535
mFbos[output]->bind ();
536
allowWindowPaint = false;
538
gScreen->glPaintOutput(attrib, transform, region, output, mask);
541
void UnityScreen::preparePaint(int ms)
543
if (BackgroundEffectHelper::blur_type == unity::BLUR_ACTIVE)
545
// this causes queue draws to be called, we obviously dont want to disable updates
546
// because we are updating the blur, so ignore them.
547
bool tmp = BackgroundEffectHelper::updates_enabled;
548
BackgroundEffectHelper::QueueDrawOnOwners();
549
BackgroundEffectHelper::updates_enabled = tmp;
552
cScreen->preparePaint(ms);
562
/* Grab changed nux regions and add damage rects for them */
563
void UnityScreen::damageNuxRegions()
568
std::vector<nux::Geometry> dirty = wt->GetDrawList();
571
for (std::vector<nux::Geometry>::iterator it = dirty.begin(), end = dirty.end();
574
nux::Geometry const& geo = *it;
575
cScreen->damageRegion(CompRegion(geo.x, geo.y, geo.width, geo.height));
578
nux::Geometry geo = wt->GetWindowCompositor().GetTooltipMainWindowGeometry();
579
cScreen->damageRegion(CompRegion(geo.x, geo.y, geo.width, geo.height));
580
cScreen->damageRegion(CompRegion(lastTooltipArea.x, lastTooltipArea.y,
581
lastTooltipArea.width, lastTooltipArea.height));
583
lastTooltipArea = geo;
588
/* handle X Events */
589
void UnityScreen::handleEvent(XEvent* event)
591
bool skip_other_plugins = false;
597
if (event->xfocus.mode == NotifyGrab)
598
PluginAdapter::Default()->OnScreenGrabbed();
599
else if (event->xfocus.mode == NotifyUngrab)
600
PluginAdapter::Default()->OnScreenUngrabbed();
601
cScreen->damageScreen(); // evil hack
602
if (_key_nav_mode_requested)
603
launcher->startKeyNavMode();
604
_key_nav_mode_requested = false;
610
if ((result = XLookupString(&(event->xkey), key_string, 2, &key_sym, 0)) > 0)
612
key_string[result] = 0;
613
skip_other_plugins = launcher->CheckSuperShortcutPressed(key_sym, event->xkey.keycode, event->xkey.state, key_string);
618
// avoid further propagation (key conflict for instance)
619
if (!skip_other_plugins)
620
screen->handleEvent(event);
622
if (!skip_other_plugins && screen->otherGrabExist("deco", "move", "switcher", "resize", NULL))
624
wt->ProcessForeignEvent(event, NULL);
628
void UnityScreen::handleCompizEvent(const char* plugin,
630
CompOption::Vector& option)
633
* don't take into account window over launcher state during
634
* the ws switch as we can get false positives
635
* (like switching to an empty viewport while grabbing a fullscreen window)
637
if (strcmp(event, "start_viewport_switch") == 0)
638
launcher->EnableCheckWindowOverLauncher(false);
639
else if (strcmp(event, "end_viewport_switch") == 0)
641
// compute again the list of all window on the new viewport
642
// to decide if we should or not hide the launcher
643
launcher->EnableCheckWindowOverLauncher(true);
644
launcher->CheckWindowOverLauncher();
646
screen->handleCompizEvent(plugin, event, option);
649
bool UnityScreen::showLauncherKeyInitiate(CompAction* action,
650
CompAction::State state,
651
CompOption::Vector& options)
653
// to receive the Terminate event
654
if (state & CompAction::StateInitKey)
655
action->setState(action->state() | CompAction::StateTermKey);
657
launcher->StartKeyShowLauncher();
658
EnsureKeybindings ();
662
bool UnityScreen::showLauncherKeyTerminate(CompAction* action,
663
CompAction::State state,
664
CompOption::Vector& options)
666
launcher->EndKeyShowLauncher();
670
bool UnityScreen::showPanelFirstMenuKeyInitiate(CompAction* action,
671
CompAction::State state,
672
CompOption::Vector& options)
674
// to receive the Terminate event
675
if (state & CompAction::StateInitKey)
676
action->setState(action->state() | CompAction::StateTermKey);
678
panelController->StartFirstMenuShow();
682
bool UnityScreen::showPanelFirstMenuKeyTerminate(CompAction* action,
683
CompAction::State state,
684
CompOption::Vector& options)
686
panelController->EndFirstMenuShow();
690
gboolean UnityScreen::OnEdgeTriggerTimeout(gpointer data)
692
UnityScreen* self = reinterpret_cast<UnityScreen*>(data);
696
if (abs(pointerY-self->_edge_pointerY) <= 5)
698
self->launcher->EdgeRevealTriggered();
702
/* We are still in the edge, but moving in Y, maybe we need another chance */
704
if (abs(pointerY-self->_edge_pointerY) > 20)
706
/* We're quite far from the first hit spot, let's wait again */
707
self->_edge_pointerY = pointerY;
712
/* We're quite near to the first hit spot, so we can reduce our timeout */
713
self->_edge_pointerY = pointerY;
714
g_source_remove(self->_edge_trigger_handle);
715
self->_edge_trigger_handle = g_timeout_add(self->_edge_timeout/2,
716
&UnityScreen::OnEdgeTriggerTimeout,
723
self->_edge_trigger_handle = 0;
727
bool UnityScreen::launcherRevealEdgeInitiate(CompAction* action,
728
CompAction::State state,
729
CompOption::Vector& options)
731
if (screen->grabbed())
734
if (_edge_trigger_handle)
735
g_source_remove(_edge_trigger_handle);
739
_edge_pointerY = pointerY;
740
_edge_trigger_handle = g_timeout_add(_edge_timeout,
741
&UnityScreen::OnEdgeTriggerTimeout,
748
void UnityScreen::SendExecuteCommand()
750
ubus_server_send_message(ubus_server_get_default(),
751
UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
752
g_variant_new("(sus)",
758
bool UnityScreen::executeCommand(CompAction* action,
759
CompAction::State state,
760
CompOption::Vector& options)
762
SendExecuteCommand();
766
void UnityScreen::restartLauncherKeyNav()
768
// set input-focus on launcher-window and start key-nav mode
769
if (newFocusedWindow != NULL)
771
newFocusedWindow->moveInputFocusTo();
772
launcher->startKeyNavMode();
776
void UnityScreen::startLauncherKeyNav()
778
// get CompWindow* of launcher-window
779
newFocusedWindow = screen->findWindow(launcherWindow->GetInputWindowId());
781
// check if currently focused window isn't the launcher-window
782
if (newFocusedWindow != screen->findWindow(screen->activeWindow()))
783
lastFocusedWindow = screen->findWindow(screen->activeWindow());
785
// set input-focus on launcher-window and start key-nav mode
786
if (newFocusedWindow != NULL)
788
// Put the launcher BaseWindow at the top of the BaseWindow stack. The
789
// input focus coming from the XinputWindow will be processed by the
790
// launcher BaseWindow only. Then the Launcher BaseWindow will decide
791
// which View will get the input focus.
792
launcherWindow->PushToFront();
793
newFocusedWindow->moveInputFocusTo();
797
bool UnityScreen::setKeyboardFocusKeyInitiate(CompAction* action,
798
CompAction::State state,
799
CompOption::Vector& options)
801
_key_nav_mode_requested = true;
805
bool UnityScreen::altTabForwardInitiate(CompAction* action,
806
CompAction::State state,
807
CompOption::Vector& options)
809
if (switcherController->Visible())
811
switcherController->Next();
815
std::vector<AbstractLauncherIcon*> results;
817
if (!switcher_desktop_icon)
819
switcher_desktop_icon = new DesktopLauncherIcon(launcher);
820
switcher_desktop_icon->SinkReference();
823
results.push_back(switcher_desktop_icon);
825
LauncherModel::iterator it;
826
for (it = launcher->GetModel()->begin(); it != launcher->GetModel()->end(); it++)
827
if ((*it)->ShowInSwitcher())
828
results.push_back(*it);
830
// maybe check launcher position/hide state?
831
switcherController->SetWorkspace(nux::Geometry(_primary_monitor.x + 100,
832
_primary_monitor.y + 100,
833
_primary_monitor.width - 200,
834
_primary_monitor.height - 200));
835
switcherController->Show(SwitcherController::ALL, SwitcherController::FOCUS_ORDER, false, results);
838
action->setState(action->state() | CompAction::StateTermKey);
842
bool UnityScreen::altTabForwardTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
844
action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
845
bool accept_state = (state & CompAction::StateCancel) == 0;
846
switcherController->Hide(accept_state);
850
bool UnityScreen::altTabPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
852
if (switcherController->Visible())
853
switcherController->Prev();
855
action->setState(action->state() | CompAction::StateTermKey);
859
bool UnityScreen::altTabPrevTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
861
action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
865
bool UnityScreen::altTabDetailStartInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
867
if (switcherController->Visible())
868
switcherController->SetDetail(true);
870
action->setState(action->state() | CompAction::StateTermKey);
874
bool UnityScreen::altTabDetailStartTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
876
action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
880
bool UnityScreen::altTabDetailStopInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
882
if (switcherController->Visible())
883
switcherController->SetDetail(false);
885
action->setState(action->state() | CompAction::StateTermKey);
889
bool UnityScreen::altTabDetailStopTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
891
action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
895
bool UnityScreen::altTabNextWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
897
if (switcherController->Visible())
898
switcherController->NextDetail();
900
action->setState(action->state() | CompAction::StateTermKey);
904
bool UnityScreen::altTabNextWindowTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
906
action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
910
bool UnityScreen::altTabExitInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
912
switcherController->Hide(false);
913
action->setState(action->state() | CompAction::StateTermKey);
917
bool UnityScreen::altTabExitTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
919
action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
923
void UnityScreen::OnLauncherStartKeyNav(GVariant* data, void* value)
925
UnityScreen* self = reinterpret_cast<UnityScreen*>(value);
926
self->startLauncherKeyNav();
929
void UnityScreen::OnLauncherEndKeyNav(GVariant* data, void* value)
931
UnityScreen* self = reinterpret_cast<UnityScreen*>(value);
932
bool preserve_focus = false;
936
preserve_focus = g_variant_get_boolean(data);
939
// Return input-focus to previously focused window (before key-nav-mode was
941
if (preserve_focus && (self->lastFocusedWindow != NULL))
943
self->lastFocusedWindow->moveInputFocusTo();
947
void UnityScreen::OnQuicklistEndKeyNav(GVariant* data, void* value)
949
UnityScreen* self = reinterpret_cast<UnityScreen*>(value);
950
self->restartLauncherKeyNav();
953
gboolean UnityScreen::initPluginActions(gpointer data)
955
CompPlugin* p = CompPlugin::find("expo");
959
MultiActionList expoActions(0);
961
foreach(CompOption & option, p->vTable->getOptions())
963
if (option.name() == "expo_key" ||
964
option.name() == "expo_button" ||
965
option.name() == "expo_edge")
967
CompAction* action = &option.value().action();
968
expoActions.AddNewAction(action, false);
973
PluginAdapter::Default()->SetExpoAction(expoActions);
976
p = CompPlugin::find("scale");
980
MultiActionList scaleActions(0);
982
foreach(CompOption & option, p->vTable->getOptions())
984
if (option.name() == "initiate_all_key" ||
985
option.name() == "initiate_all_edge" ||
986
option.name() == "initiate_key" ||
987
option.name() == "initiate_button" ||
988
option.name() == "initiate_edge" ||
989
option.name() == "initiate_group_key" ||
990
option.name() == "initiate_group_button" ||
991
option.name() == "initiate_group_edge" ||
992
option.name() == "initiate_output_key" ||
993
option.name() == "initiate_output_button" ||
994
option.name() == "initiate_output_edge")
996
CompAction* action = &option.value().action();
997
scaleActions.AddNewAction(action, false);
999
else if (option.name() == "initiate_all_button")
1001
CompAction* action = &option.value().action();
1002
scaleActions.AddNewAction(action, true);
1006
PluginAdapter::Default()->SetScaleAction(scaleActions);
1009
p = CompPlugin::find("unitymtgrabhandles");
1013
foreach(CompOption & option, p->vTable->getOptions())
1015
if (option.name() == "show_handles_key")
1016
PluginAdapter::Default()->SetShowHandlesAction(&option.value().action());
1017
else if (option.name() == "hide_handles_key")
1018
PluginAdapter::Default()->SetHideHandlesAction(&option.value().action());
1019
else if (option.name() == "toggle_handles_key")
1020
PluginAdapter::Default()->SetToggleHandlesAction(&option.value().action());
1027
/* Set up expo and scale actions on the launcher */
1028
bool UnityScreen::initPluginForScreen(CompPlugin* p)
1030
if (p->vTable->name() == "expo" ||
1031
p->vTable->name() == "scale")
1033
initPluginActions(this);
1036
return screen->initPluginForScreen(p);
1039
void UnityScreen::AddProperties(GVariantBuilder* builder)
1043
const gchar* UnityScreen::GetName()
1048
const CompWindowList& UnityScreen::getWindowPaintList()
1050
CompWindowList& pl = _withRemovedNuxWindows = cScreen->getWindowPaintList();
1051
CompWindowList::reverse_iterator it = pl.rbegin();
1052
CompWindowList::reverse_iterator end = pl.rend();
1053
std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
1055
unsigned int size = xwns.size();
1059
bool erased = false;
1060
auto id = (*it)->id();
1061
for (unsigned int i = 0; i < size; ++i)
1065
/* Increment the reverse_iterator to ensure
1066
* it is valid, then it++ returns the old
1068
CompWindowList::reverse_iterator oit = it++;
1069
/* Get the base and offset by -1 since
1070
* &*(reverse_iterator(i)) == &*(i - 1)) */
1071
CompWindowList::iterator eit = --(oit.base ());
1075
/* Remove that from the list */
1088
/* handle window painting in an opengl context
1090
* we want to paint underneath other windows here,
1091
* so we need to find if this window is actually
1092
* stacked on top of one of the nux input windows
1093
* and if so paint nux and stop us from painting
1094
* other windows or on top of the whole screen */
1095
bool UnityWindow::glDraw(const GLMatrix& matrix,
1096
GLFragment::Attrib& attrib,
1097
const CompRegion& region,
1100
if (uScreen->doShellRepaint && uScreen->allowWindowPaint)
1102
std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
1103
unsigned int size = xwns.size();
1105
for (CompWindow* w = window; w && uScreen->doShellRepaint; w = w->prev)
1108
for (unsigned int i = 0; i < size; ++i)
1112
uScreen->paintDisplay(region, matrix, mask);
1119
bool ret = gWindow->glDraw(matrix, attrib, region, mask);
1121
if (window->type() == CompWindowTypeDesktopMask)
1123
uScreen->paintPanelShadow(matrix);
1129
/* Called whenever a window is mapped, unmapped, minimized etc */
1130
void UnityWindow::windowNotify(CompWindowNotify n)
1132
PluginAdapter::Default()->Notify(window, n);
1133
window->windowNotify(n);
1136
void UnityWindow::stateChangeNotify(unsigned int lastState)
1138
PluginAdapter::Default()->NotifyStateChange(window, window->state(), lastState);
1139
window->stateChangeNotify(lastState);
1142
void UnityWindow::moveNotify(int x, int y, bool immediate)
1144
PluginAdapter::Default()->NotifyMoved(window, x, y);
1145
window->moveNotify(x, y, immediate);
1148
void UnityWindow::resizeNotify(int x, int y, int w, int h)
1150
PluginAdapter::Default()->NotifyResized(window, x, y, w, h);
1151
window->resizeNotify(x, y, w, h);
1154
CompPoint UnityWindow::tryNotIntersectLauncher(CompPoint& pos)
1156
UnityScreen* us = UnityScreen::get(screen);
1157
nux::Geometry geo = us->launcher->GetAbsoluteGeometry();
1158
CompRect launcherGeo(geo.x, geo.y, geo.width, geo.height);
1160
if (launcherGeo.contains(pos))
1162
if (screen->workArea().contains(CompRect(launcherGeo.right() + 1, pos.y(), window->width(), window->height())))
1163
pos.setX(launcherGeo.right() + 1);
1169
bool UnityWindow::place(CompPoint& pos)
1171
UnityScreen* us = UnityScreen::get(screen);
1172
Launcher::LauncherHideMode hideMode = us->launcher->GetHideMode();
1174
bool result = window->place(pos);
1178
case Launcher::LAUNCHER_HIDE_DODGE_WINDOWS:
1179
case Launcher::LAUNCHER_HIDE_DODGE_ACTIVE_WINDOW:
1180
pos = tryNotIntersectLauncher(pos);
1190
/* Configure callback for the launcher window */
1191
void UnityScreen::launcherWindowConfigureCallback(int WindowWidth, int WindowHeight,
1192
nux::Geometry& geo, void* user_data)
1194
UnityScreen* self = reinterpret_cast<UnityScreen*>(user_data);
1195
geo = nux::Geometry(self->_primary_monitor.x, self->_primary_monitor.y + 24,
1196
geo.width, self->_primary_monitor.height - 24);
1199
/* Start up nux after OpenGL is initialized */
1200
void UnityScreen::initUnity(nux::NThread* thread, void* InitData)
1203
initLauncher(thread, InitData);
1205
nux::ColorLayer background(nux::color::Transparent);
1206
static_cast<nux::WindowThread*>(thread)->SetWindowBackgroundPaintLayer(&background);
1207
LOG_INFO(logger) << "UnityScreen::initUnity: " << timer.ElapsedSeconds() << "s";
1210
void UnityScreen::onRedrawRequested()
1212
// disable blur updates so we dont waste perf. This can stall the blur during animations
1213
// but ensures a smooth animation.
1214
BackgroundEffectHelper::updates_enabled = false;
1218
/* Handle option changes and plug that into nux windows */
1219
void UnityScreen::optionChanged(CompOption* opt, UnityshellOptions::Options num)
1223
case UnityshellOptions::LauncherHideMode:
1224
launcher->SetHideMode((Launcher::LauncherHideMode) optionGetLauncherHideMode());
1226
case UnityshellOptions::BacklightMode:
1227
launcher->SetBacklightMode((Launcher::BacklightMode) optionGetBacklightMode());
1229
case UnityshellOptions::LaunchAnimation:
1230
launcher->SetLaunchAnimation((Launcher::LaunchAnimation) optionGetLaunchAnimation());
1232
case UnityshellOptions::UrgentAnimation:
1233
launcher->SetUrgentAnimation((Launcher::UrgentAnimation) optionGetUrgentAnimation());
1235
case UnityshellOptions::PanelOpacity:
1236
panelController->SetOpacity(optionGetPanelOpacity());
1238
case UnityshellOptions::LauncherOpacity:
1239
launcher->SetBackgroundAlpha(optionGetLauncherOpacity());
1241
case UnityshellOptions::IconSize:
1242
panelController->SetBFBSize(optionGetIconSize() + 18);
1243
launcher->SetIconSize(optionGetIconSize() + 6, optionGetIconSize());
1244
dashController->launcher_width = optionGetIconSize() + 18;
1246
case UnityshellOptions::AutohideAnimation:
1247
launcher->SetAutoHideAnimation((Launcher::AutoHideAnimation) optionGetAutohideAnimation());
1249
case UnityshellOptions::DashBlurExperimental:
1250
BackgroundEffectHelper::blur_type = (unity::BlurType)optionGetDashBlurExperimental();
1252
case UnityshellOptions::AutomaximizeValue:
1253
PluginAdapter::Default()->SetCoverageAreaBeforeAutomaximize(optionGetAutomaximizeValue() / 100.0f);
1255
case UnityshellOptions::DevicesOption:
1256
unity::DevicesSettings::GetDefault().SetDevicesOption((unity::DevicesSettings::DevicesOption) optionGetDevicesOption());
1258
case UnityshellOptions::LauncherRevealEdgeTimeout:
1259
_edge_timeout = optionGetLauncherRevealEdgeTimeout();
1261
case UnityshellOptions::AltTabTimeout:
1262
switcherController->detail_on_timeout = optionGetAltTabTimeout();
1269
void UnityScreen::NeedsRelayout()
1271
needsRelayout = true;
1274
void UnityScreen::ScheduleRelayout(guint timeout)
1276
if (relayoutSourceId == 0)
1277
relayoutSourceId = g_timeout_add(timeout, &UnityScreen::RelayoutTimeout, this);
1280
void UnityScreen::Relayout()
1284
nux::Geometry lCurGeom;
1285
gint primary_monitor;
1286
int panel_height = 24;
1293
foreach (CompOutput &o, screen->outputDevs ())
1294
uScreen->mFbos[&o] = UnityFBO::Ptr (new UnityFBO (&o));
1296
uScreen->mFbos[&(screen->fullscreenOutput ())] = UnityFBO::Ptr (new UnityFBO (&(screen->fullscreenOutput ())));
1299
scr = gdk_screen_get_default ();
1300
primary_monitor = gdk_screen_get_primary_monitor (scr);
1301
gdk_screen_get_monitor_geometry (scr, primary_monitor, &rect);
1302
_primary_monitor = rect;
1304
wt->SetWindowSize(rect.width, rect.height);
1306
lCurGeom = launcherWindow->GetGeometry();
1307
launcher->SetMaximumHeight(rect.height - panel_height);
1309
g_debug("Setting to primary screen rect: x=%d y=%d w=%d h=%d",
1315
launcherWindow->SetGeometry(nux::Geometry(rect.x,
1316
rect.y + panel_height,
1318
rect.height - panel_height));
1319
launcher->SetGeometry(nux::Geometry(rect.x,
1320
rect.y + panel_height,
1322
rect.height - panel_height));
1323
needsRelayout = false;
1326
gboolean UnityScreen::RelayoutTimeout(gpointer data)
1328
UnityScreen* uScr = reinterpret_cast<UnityScreen*>(data);
1330
uScreen->mFbos.clear ();
1332
uScr->NeedsRelayout ();
1334
uScr->relayoutSourceId = 0;
1336
uScr->cScreen->damageScreen();
1341
/* Handle changes in the number of workspaces by showing the switcher
1342
* or not showing the switcher */
1343
bool UnityScreen::setOptionForPlugin(const char* plugin, const char* name,
1344
CompOption::Value& v)
1346
bool status = screen->setOptionForPlugin(plugin, name, v);
1349
if (strcmp(plugin, "core") == 0 && strcmp(name, "hsize") == 0)
1351
controller->UpdateNumWorkspaces(screen->vpSize().width() * screen->vpSize().height());
1357
void UnityScreen::outputChangeNotify()
1359
ScheduleRelayout(500);
1362
void UnityFBO::paint ()
1364
//CompositeScreen *cScreen = CompositeScreen::get (screen);
1365
//unsigned int mask = cScreen->damageMask ();
1366
float texx, texy, texwidth, texheight;
1368
/* Draw the bit of the relevant framebuffer for each output */
1371
glViewport (output->x (), screen->height () - output->y2 (), output->width (), output->height ());
1373
transform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
1375
glLoadMatrixf (transform.getMatrix ());
1377
/* Note that texcoords here are normalized, so it's just (0,0)-(1,1) */
1385
glEnable (GL_TEXTURE_2D);
1386
GL::activeTexture (GL_TEXTURE0_ARB);
1387
glBindTexture (GL_TEXTURE_2D, mFBTexture);
1388
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1389
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1391
glPushAttrib (GL_SCISSOR_BIT);
1392
glEnable (GL_SCISSOR_TEST);
1394
glScissor (output->x1 (), screen->height () - output->y2 (),
1395
output->width (), output->height ());
1397
/* FIXME: This needs to be GL_TRIANGLE_STRIP */
1399
glTexCoord2f (texx, texy + texheight);
1400
glVertex2i (output->x1 (), output->y1 ());
1401
glTexCoord2f (texx, texy);
1402
glVertex2i (output->x1 (), output->y2 ());
1403
glTexCoord2f (texx + texwidth, texy);
1404
glVertex2i (output->x2 (), output->y2 ());
1405
glTexCoord2f (texx + texwidth, texy + texheight);
1406
glVertex2i (output->x2 (), output->y1 ());
1409
GL::activeTexture (GL_TEXTURE0_ARB);
1410
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1411
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1412
glBindTexture (GL_TEXTURE_2D, 0);
1413
glEnable (GL_TEXTURE_2D);
1415
glDisable (GL_SCISSOR_TEST);
1422
void UnityFBO::unbind ()
1424
uScreen->setActiveFbo (0);
1425
(*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0);
1427
glDrawBuffer (GL_BACK);
1428
glReadBuffer (GL_BACK);
1432
bool UnityFBO::status ()
1437
void UnityFBO::bind ()
1441
glGenTextures (1, &mFBTexture);
1443
glBindTexture (GL_TEXTURE_2D, mFBTexture);
1444
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1445
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1446
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1447
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1448
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, output->width (), output->height (), 0, GL_BGRA,
1449
#if IMAGE_BYTE_ORDER == MSBFirst
1450
GL_UNSIGNED_INT_8_8_8_8_REV,
1456
glBindTexture (GL_TEXTURE_2D, 0);
1461
(*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, mFboHandle);
1463
(*GL::framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
1464
GL_TEXTURE_2D, mFBTexture, 0);
1466
/* Ensure that a framebuffer is actually available */
1469
GLint status = (*GL::checkFramebufferStatus) (GL_DRAW_FRAMEBUFFER);
1471
if (status != GL_FRAMEBUFFER_COMPLETE)
1475
case GL_FRAMEBUFFER_UNDEFINED:
1476
compLogMessage ("unity", CompLogLevelWarn, "no window"); break;
1477
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
1478
compLogMessage ("unity", CompLogLevelWarn, "attachment incomplete"); break;
1479
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
1480
compLogMessage ("unity", CompLogLevelWarn, "no buffers attached to fbo"); break;
1481
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
1482
compLogMessage ("unity", CompLogLevelWarn, "some attachment in glDrawBuffers doesn't exist in FBO"); break;
1483
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
1484
compLogMessage ("unity", CompLogLevelWarn, "some attachment in glReadBuffers doesn't exist in FBO"); break;
1485
case GL_FRAMEBUFFER_UNSUPPORTED:
1486
compLogMessage ("unity", CompLogLevelWarn, "unsupported internal format"); break;
1487
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
1488
compLogMessage ("unity", CompLogLevelWarn, "different levels of sampling for each attachment"); break;
1489
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
1490
compLogMessage ("unity", CompLogLevelWarn, "number of layers is different"); break;
1492
compLogMessage ("unity", CompLogLevelWarn, "unable to bind the framebuffer for an unknown reason"); break;
1495
GL::bindFramebuffer (GL_FRAMEBUFFER_EXT, 0);
1496
GL::deleteFramebuffers (1, &mFboHandle);
1498
glDrawBuffer (GL_BACK);
1499
glReadBuffer (GL_BACK);
1504
uScreen->setActiveFbo (0);
1512
uScreen->setActiveFbo (mFboHandle);
1514
glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
1515
glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
1525
UnityFBO::UnityFBO (CompOutput *o)
1526
: mFboStatus (false)
1530
(*GL::genFramebuffers) (1, &mFboHandle);
1533
UnityFBO::~UnityFBO ()
1535
(*GL::deleteFramebuffers) (1, &mFboHandle);
1538
glDeleteTextures (1, &mFBTexture);
1541
/* Start up the launcher */
1542
void UnityScreen::initLauncher(nux::NThread* thread, void* InitData)
1545
UnityScreen* self = reinterpret_cast<UnityScreen*>(InitData);
1547
self->launcherWindow = new nux::BaseWindow(TEXT("LauncherWindow"));
1548
self->launcherWindow->SinkReference();
1550
self->launcher = new Launcher(self->launcherWindow, self->screen);
1551
self->launcher->SinkReference();
1552
self->launcher->hidden_changed.connect(sigc::mem_fun(self, &UnityScreen::OnLauncherHiddenChanged));
1554
self->AddChild(self->launcher);
1556
nux::HLayout* layout = new nux::HLayout();
1557
layout->AddView(self->launcher, 1);
1558
layout->SetContentDistribution(nux::eStackLeft);
1559
layout->SetVerticalExternalMargin(0);
1560
layout->SetHorizontalExternalMargin(0);
1562
self->controller = new LauncherController(self->launcher, self->screen);
1564
self->launcherWindow->SetConfigureNotifyCallback(&UnityScreen::launcherWindowConfigureCallback, self);
1565
self->launcherWindow->SetLayout(layout);
1566
self->launcherWindow->SetBackgroundColor(nux::Color(0x00000000));
1567
self->launcherWindow->ShowWindow(true);
1568
self->launcherWindow->EnableInputWindow(true, "launcher", false, false);
1569
self->launcherWindow->InputWindowEnableStruts(true);
1570
self->launcherWindow->SetEnterFocusInputArea(self->launcher);
1572
self->switcherController = new SwitcherController();
1573
/* FIXME: this should not be manual, should be managed with a
1574
show/hide callback like in GAIL*/
1575
if (unity_a11y_initialized () == TRUE)
1577
AtkObject *atk_obj = NULL;
1579
atk_obj = unity_util_accessible_add_window (self->launcherWindow);
1581
atk_object_set_name (atk_obj, _("Launcher"));
1584
self->launcher->SetIconSize(54, 48);
1585
self->launcher->SetBacklightMode(Launcher::BACKLIGHT_ALWAYS_ON);
1587
LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s";
1591
self->panelController = new PanelController();
1592
self->AddChild(self->panelController);
1593
LOG_INFO(logger) << "initLauncher-Panel " << timer.ElapsedSeconds() << "s";
1596
self->dashController = DashController::Ptr(new DashController());
1598
/* FIXME: this should not be manual, should be managed with a
1599
show/hide callback like in GAIL
1600
if (unity_a11y_initialized() == TRUE)
1602
AtkObject* atk_obj = NULL;
1604
atk_obj = unity_util_accessible_add_window(self->placesController->GetWindow());
1606
atk_object_set_name(atk_obj, _("Places"));
1610
self->launcher->SetHideMode(Launcher::LAUNCHER_HIDE_DODGE_WINDOWS);
1611
self->launcher->SetLaunchAnimation(Launcher::LAUNCH_ANIMATION_PULSE);
1612
self->launcher->SetUrgentAnimation(Launcher::URGENT_ANIMATION_WIGGLE);
1613
self->ScheduleRelayout(0);
1615
self->OnLauncherHiddenChanged();
1619
UnityWindow::UnityWindow(CompWindow* window)
1620
: BaseSwitchWindow (dynamic_cast<BaseSwitchScreen *> (UnityScreen::get (screen)), window)
1621
, PluginClassHandler<UnityWindow, CompWindow>(window)
1623
, gWindow(GLWindow::get(window))
1625
WindowInterface::setHandler(window);
1626
GLWindowInterface::setHandler(gWindow);
1629
UnityWindow::~UnityWindow()
1631
UnityScreen* us = UnityScreen::get(screen);
1632
if (us->newFocusedWindow && (UnityWindow::get(us->newFocusedWindow) == this))
1633
us->newFocusedWindow = NULL;
1634
if (us->lastFocusedWindow && (UnityWindow::get(us->lastFocusedWindow) == this))
1635
us->lastFocusedWindow = NULL;
1639
bool UnityPluginVTable::init()
1644
if (!CompPlugin::checkPluginABI("core", CORE_ABIVERSION))
1646
if (!CompPlugin::checkPluginABI("composite", COMPIZ_COMPOSITE_ABI))
1648
if (!CompPlugin::checkPluginABI("opengl", COMPIZ_OPENGL_ABI))
1651
/* Ensure OpenGL version is 1.4+. */
1652
version = get_opengl_version_f32((const gchar*) glGetString(GL_VERSION));
1655
compLogMessage("unityshell", CompLogLevelError,
1656
"OpenGL 1.4+ not supported\n");
1660
/* Ensure OpenGL extensions required by the Unity plugin are available. */
1661
extensions = (gchar*) glGetString(GL_EXTENSIONS);
1662
if (!is_extension_supported(extensions, "GL_ARB_vertex_program"))
1664
compLogMessage("unityshell", CompLogLevelError,
1665
"GL_ARB_vertex_program not supported\n");
1668
if (!is_extension_supported(extensions, "GL_ARB_fragment_program"))
1670
compLogMessage("unityshell", CompLogLevelError,
1671
"GL_ARB_fragment_program not supported\n");
1674
if (!is_extension_supported(extensions, "GL_ARB_vertex_buffer_object"))
1676
compLogMessage("unityshell", CompLogLevelError,
1677
"GL_ARB_vertex_buffer_object not supported\n");
1680
if (!is_extension_supported(extensions, "GL_ARB_framebuffer_object"))
1682
if (!is_extension_supported(extensions, "GL_EXT_framebuffer_object"))
1684
compLogMessage("unityshell", CompLogLevelError,
1685
"GL_ARB_framebuffer_object or GL_EXT_framebuffer_object "
1690
if (!is_extension_supported(extensions, "GL_ARB_texture_non_power_of_two"))
1692
if (!is_extension_supported(extensions, "GL_ARB_texture_rectangle"))
1694
compLogMessage("unityshell", CompLogLevelError,
1695
"GL_ARB_texture_non_power_of_two or "
1696
"GL_ARB_texture_rectangle not supported\n");
1708
void configure_logging()
1710
// The default behaviour of the logging infrastructure is to send all output
1711
// to std::cout for warning or above.
1713
// TODO: write a file output handler that keeps track of backups.
1714
nux::logging::configure_logging(::getenv("UNITY_LOG_SEVERITY"));
1715
g_log_set_default_handler(capture_g_log_calls, NULL);
1718
/* Checks whether an extension is supported by the GLX or OpenGL implementation
1719
* given the extension name and the list of supported extensions. */
1720
gboolean is_extension_supported(const gchar* extensions, const gchar* extension)
1722
if (extensions != NULL && extension != NULL)
1724
const gsize len = strlen(extension);
1725
gchar* p = (gchar*) extensions;
1726
gchar* end = p + strlen(p);
1730
const gsize size = strcspn(p, " ");
1731
if (len == size && strncmp(extension, p, size) == 0)
1740
/* Gets the OpenGL version as a floating-point number given the string. */
1741
gfloat get_opengl_version_f32(const gchar* version_string)
1743
gfloat version = 0.0f;
1746
for (i = 0; isdigit(version_string[i]); i++)
1747
version = version * 10.0f + (version_string[i] - 48);
1749
if ((version_string[i] == '.' || version_string[i] == ',') &&
1750
isdigit(version_string[i + 1]))
1752
version = version * 10.0f + (version_string[i + 1] - 48);
1753
return (version + 0.1f) * 0.1f;
1759
nux::logging::Level glog_level_to_nux(GLogLevelFlags log_level)
1761
// For some weird reason, ERROR is more critical than CRITICAL in gnome.
1762
if (log_level & G_LOG_LEVEL_ERROR)
1763
return nux::logging::Critical;
1764
if (log_level & G_LOG_LEVEL_CRITICAL)
1765
return nux::logging::Error;
1766
if (log_level & G_LOG_LEVEL_WARNING)
1767
return nux::logging::Warning;
1768
if (log_level & G_LOG_LEVEL_MESSAGE ||
1769
log_level & G_LOG_LEVEL_INFO)
1770
return nux::logging::Info;
1771
// default to debug.
1772
return nux::logging::Debug;
1775
void capture_g_log_calls(const gchar* log_domain,
1776
GLogLevelFlags log_level,
1777
const gchar* message,
1780
// Since we aren't entirely sure if log_domain contains anything, lets have
1782
std::string module("glib");
1785
module += std::string(".") + log_domain;
1787
nux::logging::Logger logger(module);
1788
nux::logging::Level level = glog_level_to_nux(log_level);
1789
if (logger.GetEffectiveLogLevel() >= level)
1791
nux::logging::LogStream(level, logger.module(), "<unknown>", 0).stream()
1796
} // anonymous namespace