summaryrefslogtreecommitdiff
diff options
authorNeil Jagdish Patel <neil.patel@canonical.com>2011-03-22 14:15:09 +0000
committerNeil Jagdish Patel <neil.patel@canonical.com>2011-03-22 14:15:09 +0000
commit5300e5d870a9a8ff4e4c6600ffe46571e13f8740 (patch)
treeee2fd661b3883d4bc8cfdb5b5b2a4fd5838266e8
parente2c0ed652b75f54aa8b37e5e86439ff56ae87aef (diff)
Beginnings of multiple panel support
(bzr r989.1.1)
-rw-r--r--src/PanelController.cpp144
-rw-r--r--src/PanelController.h51
-rw-r--r--src/PanelView.cpp14
-rw-r--r--src/PanelView.h3
-rw-r--r--src/PlacesController.h1
-rw-r--r--src/UScreen.cpp121
-rw-r--r--src/UScreen.h53
-rw-r--r--src/unityshell.cpp3
-rw-r--r--src/unityshell.h3
9 files changed, 390 insertions, 3 deletions
diff --git a/src/PanelController.cpp b/src/PanelController.cpp
new file mode 100644
index 000000000..9b1c2dc8f
--- /dev/null
+++ b/src/PanelController.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
+ */
+
+#include "PanelController.h"
+
+#include "UScreen.h"
+
+#include "unitya11y.h"
+#include "unity-util-accessible.h"
+
+PanelController::PanelController ()
+{
+ UScreen *screen = UScreen::GetDefault ();
+
+ screen->changed.connect (sigc::mem_fun (this, &PanelController::OnScreenChanged));
+
+ OnScreenChanged (screen->GetPrimaryMonitor (), screen->GetMonitors ());
+}
+
+PanelController::~PanelController ()
+{
+
+}
+
+void
+PanelController::SetPrimary (nux::BaseWindow *window, bool primary)
+{
+ nux::Layout *layout = window->GetLayout ();
+ std::list<nux::Area *>::iterator it = layout->GetChildren ().begin ();
+
+ static_cast<PanelView *> (*it)->SetPrimary (primary);
+}
+
+// We need to put a panel on every monitor, and try and re-use the panels we already have
+void
+PanelController::OnScreenChanged (int primary_monitor, std::vector<nux::Geometry>& monitors)
+{
+ std::vector<nux::BaseWindow *>::iterator it, eit = _windows.end ();
+ int n_monitors = monitors.size ();
+ int i = 0;
+
+ for (it = _windows.begin (); it != eit; ++it)
+ {
+ if (i < n_monitors)
+ {
+ nux::Geometry geo = monitors[i];
+ geo.height = 24;
+ (*it)->SetGeometry (geo);
+ SetPrimary (*it, i == primary_monitor);
+ i++;
+ }
+ }
+
+ // Add new ones if needed
+ if (i < n_monitors)
+ {
+ for (i = i; i < n_monitors; i++)
+ {
+ nux::BaseWindow *window;
+ PanelView *view;
+ nux::HLayout *layout;
+
+ layout = new nux::HLayout();
+
+ view = new PanelView ();
+ view->SetMaximumHeight (24);
+ AddChild (view);
+
+ layout->AddView (view, 1);
+ layout->SetContentDistribution (nux::eStackLeft);
+ layout->SetVerticalExternalMargin (0);
+ layout->SetHorizontalExternalMargin (0);
+
+ window = new nux::BaseWindow("");
+ window->SinkReference ();
+ window->SetConfigureNotifyCallback(&PanelController::WindowConfigureCallback, window);
+ window->SetLayout(layout);
+ window->SetBackgroundColor(nux::Color(0x00000000));
+ window->ShowWindow(true);
+ window->EnableInputWindow(true, "panel", false, false);
+ window->InputWindowEnableStruts(true);
+
+ nux::Geometry geo = monitors[i];
+ geo.height = 24;
+ window->SetGeometry (geo);
+ SetPrimary (window, i == primary_monitor);
+
+ /* FIXME: this should not be manual, should be managed with a
+ show/hide callback like in GAIL*/
+ if (unity_a11y_initialized () == TRUE)
+ unity_util_accessible_add_window (window);
+
+ _windows.push_back (window);
+ }
+ }
+
+ if ((int)_windows.size () > n_monitors)
+ {
+ std::vector<nux::BaseWindow*>::iterator sit;
+ for (sit = it; sit != eit; ++sit)
+ {
+ (*sit)->UnReference ();
+ }
+
+ _windows.erase (it, _windows.end ());
+ }
+}
+
+void
+PanelController::WindowConfigureCallback (int window_width,
+ int window_height,
+ nux::Geometry& geo,
+ void *user_data)
+{
+ nux::BaseWindow *window = static_cast<nux::BaseWindow *> (user_data);
+ geo = window->GetGeometry ();
+}
+
+const gchar *
+PanelController::GetName ()
+{
+ return "PanelController";
+}
+
+void
+PanelController::AddProperties (GVariantBuilder *builder)
+{
+
+}
diff --git a/src/PanelController.h b/src/PanelController.h
new file mode 100644
index 000000000..6e96e7389
--- /dev/null
+++ b/src/PanelController.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
+ */
+
+#ifndef _PANEL_CONTROLLER_H_
+#define _PANEL_CONTROLLER_H_
+
+#include <Nux/Nux.h>
+#include <Nux/BaseWindow.h>
+#include <vector>
+
+#include "Introspectable.h"
+#include "PanelView.h"
+
+class PanelController : public nux::Object, public Introspectable
+{
+public:
+ PanelController ();
+ ~PanelController ();
+
+protected:
+ const gchar * GetName ();
+ void AddProperties (GVariantBuilder *builder);
+
+private:
+ void SetPrimary (nux::BaseWindow *window, bool primary);
+ void OnScreenChanged (int primary_monitor, std::vector<nux::Geometry>& monitors);
+
+ static void WindowConfigureCallback (int window_width,
+ int window_height,
+ nux::Geometry& geo,
+ void *user_data);
+private:
+ std::vector<nux::BaseWindow *> _windows;
+};
+
+#endif // _PANEL_CONTROLLER_H_
diff --git a/src/PanelView.cpp b/src/PanelView.cpp
index fe24c8482..819525878 100644
--- a/src/PanelView.cpp
+++ b/src/PanelView.cpp
@@ -46,7 +46,8 @@ NUX_IMPLEMENT_OBJECT_TYPE (PanelView);
PanelView::PanelView (NUX_FILE_LINE_DECL)
: View (NUX_FILE_LINE_PARAM),
_is_dirty (true),
- _opacity (1.0f)
+ _opacity (1.0f),
+ _is_primary (false)
{
_needs_geo_sync = false;
_style = new PanelStyle ();
@@ -129,7 +130,7 @@ PanelView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw)
GfxContext.PopClippingRectangle ();
- if (_needs_geo_sync)
+ if (_needs_geo_sync && _is_primary)
{
SyncGeometries ();
_needs_geo_sync = false;
@@ -371,6 +372,9 @@ PanelView::EndFirstMenuShow ()
{
std::list<Area *>::iterator it;
+ if (!_is_primary)
+ return;
+
std::list<Area *> my_children = _layout->GetChildren ();
for (it = my_children.begin(); it != my_children.end(); it++)
{
@@ -426,6 +430,12 @@ on_sync_geometries_done_cb (GObject *source,
}
void
+PanelView::SetPrimary (bool primary)
+{
+ _is_primary = primary;
+}
+
+void
PanelView::SyncGeometries ()
{
GVariantBuilder b;
diff --git a/src/PanelView.h b/src/PanelView.h
index 6af744f76..258a6a589 100644
--- a/src/PanelView.h
+++ b/src/PanelView.h
@@ -52,6 +52,8 @@ public:
void OnEntryActivateRequest (const char *entry_id);
void OnEntryActivated (const char *entry_id);
void OnSynced ();
+
+ void SetPrimary (bool primary);
PanelHomeButton * HomeButton ();
@@ -89,6 +91,7 @@ private:
bool _is_dirty;
float _opacity;
bool _needs_geo_sync;
+ bool _is_primary;
};
#endif // PANEL_VIEW_H
diff --git a/src/PlacesController.h b/src/PlacesController.h
index 6ebe9ead7..f4e2c2569 100644
--- a/src/PlacesController.h
+++ b/src/PlacesController.h
@@ -14,6 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Gordon Allott <gord.allott@canonical.com>
+ * Neil Jagdish Patel <neil.patel@canonical.com>
*/
#ifndef PLACES_CONTROLLER_H
diff --git a/src/UScreen.cpp b/src/UScreen.cpp
new file mode 100644
index 000000000..8cb863883
--- /dev/null
+++ b/src/UScreen.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
+ */
+
+#include "UScreen.h"
+
+static UScreen *_default_screen = NULL;
+
+UScreen::UScreen ()
+: _refresh_id (0)
+{
+ GdkScreen *screen;
+
+ screen = gdk_screen_get_default ();
+ g_signal_connect (screen, "size-changed",
+ (GCallback)UScreen::Changed, this);
+ g_signal_connect (screen, "monitors-changed",
+ (GCallback)UScreen::Changed, this);
+
+ Refresh ();
+}
+
+UScreen::~UScreen ()
+{
+ if (_default_screen == this)
+ _default_screen = NULL;
+
+ g_signal_handlers_disconnect_by_func ((gpointer)gdk_screen_get_default (),
+ (gpointer)UScreen::Changed,
+ (gpointer)this);
+}
+
+UScreen *
+UScreen::GetDefault ()
+{
+ if (G_UNLIKELY (!_default_screen))
+ _default_screen = new UScreen ();
+
+ return _default_screen;
+}
+
+int
+UScreen::GetPrimaryMonitor ()
+{
+ return gdk_screen_get_primary_monitor (gdk_screen_get_default ());
+}
+
+nux::Geometry
+UScreen::GetPrimaryMonitorGeometry ()
+{
+ return _monitors[GetPrimaryMonitor ()];
+}
+
+std::vector<nux::Geometry>&
+UScreen::GetMonitors ()
+{
+ return _monitors;
+}
+
+void
+UScreen::Changed (GdkScreen *screen, UScreen *self)
+{
+ if (self->_refresh_id)
+ return;
+
+ self->_refresh_id = g_idle_add ((GSourceFunc)UScreen::OnIdleChanged, self);
+}
+
+gboolean
+UScreen::OnIdleChanged (UScreen *self)
+{
+ self->_refresh_id = 0;
+ self->Refresh ();
+
+ return FALSE;
+}
+
+void
+UScreen::Refresh ()
+{
+ GdkScreen *screen;
+ int primary;
+
+ screen = gdk_screen_get_default ();
+ primary = GetPrimaryMonitor ();
+
+ _monitors.erase (_monitors.begin (), _monitors.end ());
+
+ g_print ("\nScreen geometry changed:\n");
+
+ for (int i = 0; i < gdk_screen_get_n_monitors (screen); i++)
+ {
+ GdkRectangle rect = { 0 };
+
+ gdk_screen_get_monitor_geometry (screen, i, &rect);
+
+ nux::Geometry geo (rect.x, rect.y, rect.width, rect.height);
+ _monitors.push_back (geo);
+
+ g_print (" Monitor %d%s\n", i, i == primary ? "(primary)" : "");
+ g_print (" %dx%dx%dx%d\n", geo.x, geo.y, geo.width, geo.height);
+ }
+
+ g_print ("\n");
+
+ changed.emit (primary, _monitors);
+}
diff --git a/src/UScreen.h b/src/UScreen.h
new file mode 100644
index 000000000..9a7f1a2d1
--- /dev/null
+++ b/src/UScreen.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
+ */
+
+#ifndef _UNITY_SCREEN_H_
+#define _UNITY_SCREEN_H_
+
+#include <gdk/gdk.h>
+#include <Nux/Nux.h>
+#include <sigc++/sigc++.h>
+#include <vector>
+
+class UScreen : public sigc::trackable
+{
+public:
+ UScreen ();
+ ~UScreen ();
+
+ static UScreen * GetDefault ();
+
+ int GetPrimaryMonitor ();
+ nux::Geometry GetPrimaryMonitorGeometry ();
+
+ std::vector<nux::Geometry>& GetMonitors ();
+
+ // <void, primary_monitor, monitors>
+ sigc::signal<void, int, std::vector<nux::Geometry>&> changed;
+
+private:
+ static void Changed (GdkScreen *screen, UScreen *self);
+ static gboolean OnIdleChanged (UScreen *self);
+ void Refresh ();
+
+private:
+ std::vector<nux::Geometry> _monitors;
+ guint32 _refresh_id;
+};
+
+#endif // _UNITY_SCREEN_H_
diff --git a/src/unityshell.cpp b/src/unityshell.cpp
index 48fe43cd3..5e893486b 100644
--- a/src/unityshell.cpp
+++ b/src/unityshell.cpp
@@ -917,6 +917,7 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData)
/* Setup panel */
LOGGER_START_PROCESS ("initLauncher-Panel");
+ self->panelController = new PanelController ();
self->panelView = new PanelView ();
self->AddChild (self->panelView);
@@ -936,7 +937,7 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData)
self->panelWindow->SetConfigureNotifyCallback(&UnityScreen::panelWindowConfigureCallback, self);
self->panelWindow->SetLayout(layout);
self->panelWindow->SetBackgroundColor(nux::Color(0x00000000));
- self->panelWindow->ShowWindow(true);
+ //self->panelWindow->ShowWindow(true);
self->panelWindow->EnableInputWindow(true, "panel", false, false);
self->panelWindow->InputWindowEnableStruts(true);
diff --git a/src/unityshell.h b/src/unityshell.h
index 5a6a46d9b..1cb0c5338 100644
--- a/src/unityshell.h
+++ b/src/unityshell.h
@@ -33,6 +33,8 @@
#include "Introspectable.h"
#include "Launcher.h"
#include "LauncherController.h"
+#include "PanelController.h"
+#include "UScreen.h"
#include "PanelView.h"
#include "PanelHomeButton.h"
#include "PlacesController.h"
@@ -204,6 +206,7 @@ class UnityScreen :
Launcher *launcher;
LauncherController *controller;
+ PanelController *panelController;
PanelView *panelView;
PanelHomeButton *panelHomeButton;
PlacesController *placesController;