diff --git a/.gitmodules b/.gitmodules
index 03ef7c62..cf4f912a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
[submodule "subprojects/wayland-logout"]
path = subprojects/wayland-logout
url = https://github.com/soreau/wayland-logout
+[submodule "subprojects/wf-json"]
+ path = subprojects/wf-json
+ url = https://github.com/WayfireWM/wf-json
diff --git a/meson.build b/meson.build
index 147c4e35..83492f5e 100644
--- a/meson.build
+++ b/meson.build
@@ -14,6 +14,7 @@ project(
)
wayfire = dependency('wayfire')
+json = subproject('wf-json').get_variable('wfjson')
wayland_client = dependency('wayland-client')
wayland_protos = dependency('wayland-protocols')
gtkmm = dependency('gtkmm-3.0', version: '>=3.24')
@@ -22,6 +23,7 @@ gtklayershell = dependency('gtk-layer-shell-0', version: '>= 0.6', fallback: ['
libpulse = dependency('libpulse', required : get_option('pulse'))
dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4')
libgvc = subproject('gvc', default_options: ['static=true'], required : get_option('pulse'))
+xkbregistry = dependency('xkbregistry')
if get_option('wayland-logout') == true
wayland_logout = subproject('wayland-logout')
diff --git a/metadata/dock.xml b/metadata/dock.xml
index 1c74e047..040ecd89 100644
--- a/metadata/dock.xml
+++ b/metadata/dock.xml
@@ -15,6 +15,16 @@
<_short>Autohide duration
300
+
+
+
+
+
@@ -128,6 +153,10 @@
<_short>Battery Font
default
+
<_short>Network
@@ -247,6 +276,10 @@
<_short>Volume Scroll Sensitivity
0.05
+
<_short>Notifications
@@ -254,6 +287,18 @@
<_short>Notifications Display Timeout
<_long>Set to negative value to disable.
2.5
+
+
+
+
<_short>Tray
diff --git a/src/panel/meson.build b/src/panel/meson.build
index 0a511c76..a9386a2c 100644
--- a/src/panel/meson.build
+++ b/src/panel/meson.build
@@ -6,6 +6,7 @@ widget_sources = ['widgets/battery.cpp',
'widgets/network.cpp',
'widgets/spacing.cpp',
'widgets/separator.cpp',
+ 'widgets/language.cpp',
'widgets/window-list/window-list.cpp',
'widgets/window-list/toplevel.cpp',
'widgets/notifications/daemon.cpp',
@@ -17,7 +18,7 @@ widget_sources = ['widgets/battery.cpp',
'widgets/tray/item.cpp',
'widgets/tray/host.cpp']
-deps = [gtkmm, wayland_client, libutil, wf_protos, wfconfig, gtklayershell, dbusmenu_gtk]
+deps = [gtkmm, wayland_client, libutil, wf_protos, wfconfig, gtklayershell, xkbregistry, json, dbusmenu_gtk]
if libpulse.found()
widget_sources += 'widgets/volume.cpp'
diff --git a/src/panel/panel.cpp b/src/panel/panel.cpp
index 566dd517..75914786 100644
--- a/src/panel/panel.cpp
+++ b/src/panel/panel.cpp
@@ -18,6 +18,7 @@
#include "widgets/battery.hpp"
#include "widgets/command-output.hpp"
+#include "widgets/language.hpp"
#include "widgets/menu.hpp"
#include "widgets/clock.hpp"
#include "widgets/launchers.hpp"
@@ -78,7 +79,7 @@ class WayfirePanel::impl
window->override_background_color(rgba);
};
-
+
WfOption panel_layer{"panel/layer"};
std::function set_panel_layer = [=] ()
{
@@ -119,10 +120,7 @@ class WayfirePanel::impl
bg_color.set_callback(on_window_color_updated);
on_window_color_updated(); // set initial color
- window->show_all();
- init_widgets();
- init_layout();
-
+
window->signal_delete_event().connect(
sigc::mem_fun(this, &WayfirePanel::impl::on_delete));
}
@@ -134,22 +132,7 @@ class WayfirePanel::impl
return true;
}
- void init_layout()
- {
- left_box.get_style_context()->add_class("left");
- center_box.get_style_context()->add_class("center");
- right_box.get_style_context()->add_class("right");
- content_box.pack_start(left_box, false, false);
- content_box.pack_end(right_box, false, false);
- if (!center_box.get_children().empty())
- {
- content_box.set_center_widget(center_box);
- }
- center_box.show_all();
- window->add(content_box);
- window->show_all();
- }
std::optional widget_with_value(std::string value, std::string prefix)
{
@@ -225,6 +208,19 @@ class WayfirePanel::impl
{
return Widget(new WfCommandOutputButtons());
}
+
+ if (name == "language")
+ {
+ if (get_ipc_server_instance()->connected)
+ {
+ return Widget(new WayfireLanguage());
+ } else
+ {
+ std::cerr << "Wayfire IPC not connected, which is required to load language widget." <<
+ std::endl;
+ return nullptr;
+ }
+ }
if (auto pixel = widget_with_value(name, "spacing"))
{
@@ -285,34 +281,10 @@ class WayfirePanel::impl
WfOption left_widgets_opt{"panel/widgets_left"};
WfOption right_widgets_opt{"panel/widgets_right"};
WfOption center_widgets_opt{"panel/widgets_center"};
- void init_widgets()
- {
- left_widgets_opt.set_callback([=] ()
- {
- reload_widgets((std::string)left_widgets_opt, left_widgets, left_box);
- });
- right_widgets_opt.set_callback([=] ()
- {
- reload_widgets((std::string)right_widgets_opt, right_widgets, right_box);
- });
- center_widgets_opt.set_callback([=] ()
- {
- reload_widgets((std::string)center_widgets_opt, center_widgets, center_box);
- if (center_box.get_children().empty())
- {
- content_box.unset_center_widget();
- } else
- {
- content_box.set_center_widget(center_box);
- }
- });
- reload_widgets((std::string)left_widgets_opt, left_widgets, left_box);
- reload_widgets((std::string)right_widgets_opt, right_widgets, right_box);
- reload_widgets((std::string)center_widgets_opt, center_widgets, center_box);
- }
public:
+
impl(WayfireOutput *output) : output(output)
{
create_window();
@@ -345,6 +317,67 @@ class WayfirePanel::impl
w->handle_config_reload();
}
}
+
+ WayfirePanelApp *panel_app;
+ void set_panel_app(WayfirePanelApp *panel_app)
+ {
+ this->panel_app = panel_app;
+ }
+
+ void init_widgets()
+ {
+
+ left_widgets_opt.set_callback([=] ()
+ {
+ reload_widgets((std::string)left_widgets_opt, left_widgets, left_box);
+ });
+ right_widgets_opt.set_callback([=] ()
+ {
+ reload_widgets((std::string)right_widgets_opt, right_widgets, right_box);
+ });
+ center_widgets_opt.set_callback([=] ()
+ {
+ reload_widgets((std::string)center_widgets_opt, center_widgets, center_box);
+ if (center_box.get_children().empty())
+ {
+ content_box.unset_center_widget();
+ } else
+ {
+ content_box.set_center_widget(center_box);
+ }
+ });
+
+ reload_widgets((std::string)left_widgets_opt, left_widgets, left_box);
+ reload_widgets((std::string)right_widgets_opt, right_widgets, right_box);
+ reload_widgets((std::string)center_widgets_opt, center_widgets, center_box);
+ }
+
+ void init_layout()
+ {
+ left_box.get_style_context()->add_class("left");
+ center_box.get_style_context()->add_class("center");
+ right_box.get_style_context()->add_class("right");
+ content_box.pack_start(left_box, false, false);
+ content_box.pack_end(right_box, false, false);
+ if (!center_box.get_children().empty())
+ {
+ content_box.set_center_widget(center_box);
+ }
+
+ center_box.show_all();
+ window->add(content_box);
+ window->show_all();
+ }
+ void unhide_now()
+ {
+
+ window->m_show_uncertain();
+
+ }
+ std::shared_ptr get_ipc_server_instance()
+ {
+ return panel_app->get_ipc_server_instance();
+ }
};
WayfirePanel::WayfirePanel(WayfireOutput *output) : pimpl(new impl(output))
@@ -364,6 +397,27 @@ void WayfirePanel::handle_config_reload()
return pimpl->handle_config_reload();
}
+void WayfirePanel::init_widgets()
+{
+ pimpl->init_widgets();
+}
+
+void WayfirePanel::init_layout()
+{
+ pimpl->init_layout();
+}
+
+void WayfirePanel::unhide_now()
+{
+ pimpl->unhide_now();
+}
+
+void WayfirePanel::set_panel_app(WayfirePanelApp *panel_app)
+{
+ pimpl->set_panel_app(panel_app);
+}
+
+
class WayfirePanelApp::impl
{
public:
@@ -436,8 +490,18 @@ void WayfirePanelApp::add_css_file(std::string file, int priority)
void WayfirePanelApp::handle_new_output(WayfireOutput *output)
{
+ if (!ipc_server)
+ {
+ ipc_server = WayfireIPC::get_instance();
+ }
+
priv->panels[output] = std::unique_ptr(
new WayfirePanel(output));
+ priv->panels[output]->handle_config_reload();
+ priv->panels[output]->set_panel_app(this);
+ priv->panels[output]->init_widgets();
+ priv->panels[output]->init_layout();
+
}
WayfirePanel*WayfirePanelApp::panel_for_wl_output(wl_output *output)
@@ -468,6 +532,11 @@ WayfirePanelApp& WayfirePanelApp::get()
return dynamic_cast(*instance.get());
}
+std::shared_ptr WayfirePanelApp::get_ipc_server_instance()
+{
+ return ipc_server;
+}
+
void WayfirePanelApp::create(int argc, char **argv)
{
if (instance)
@@ -479,6 +548,14 @@ void WayfirePanelApp::create(int argc, char **argv)
instance->run();
}
+void WayfirePanelApp::unhide_now()
+{
+ for (auto& p : priv->panels)
+ {
+ p.second->unhide_now();
+ }
+}
+
WayfirePanelApp::~WayfirePanelApp() = default;
WayfirePanelApp::WayfirePanelApp(int argc, char **argv) :
WayfireShellApp(argc, argv), priv(new impl())
diff --git a/src/panel/panel.hpp b/src/panel/panel.hpp
index c20f94b9..fc5bfdc7 100644
--- a/src/panel/panel.hpp
+++ b/src/panel/panel.hpp
@@ -7,7 +7,9 @@
#include
#include "wf-shell-app.hpp"
+#include "wf-ipc.hpp"
+class WayfirePanelApp;
class WayfirePanel
{
public:
@@ -16,6 +18,11 @@ class WayfirePanel
wl_surface *get_wl_surface();
Gtk::Window& get_window();
void handle_config_reload();
+ void init_widgets();
+ void init_layout();
+ void unhide_now();
+ void set_panel_app(WayfirePanelApp *panel_app);
+ std::shared_ptr get_ipc_server_instance();
private:
class impl;
@@ -32,11 +39,14 @@ class WayfirePanelApp : public WayfireShellApp
* call to create() */
static void create(int argc, char **argv);
~WayfirePanelApp();
-
+
void handle_new_output(WayfireOutput *output) override;
void handle_output_removed(WayfireOutput *output) override;
void on_config_reload() override;
void on_css_reload() override;
+ void unhide_now();
+ std::shared_ptr get_ipc_server_instance();
+ std::shared_ptr ipc_server = nullptr;
private:
WayfirePanelApp(int argc, char **argv);
diff --git a/src/panel/widgets/battery.cpp b/src/panel/widgets/battery.cpp
index 2491044d..943dd0b4 100644
--- a/src/panel/widgets/battery.cpp
+++ b/src/panel/widgets/battery.cpp
@@ -174,6 +174,17 @@ void WayfireBatteryInfo::update_details()
}
}
+void WayfireBatteryInfo::button_press_cb(GdkEventButton *event)
+{
+
+ if ((event->button == 3) && (event->type == GDK_BUTTON_PRESS))
+ {
+ if (g_spawn_command_line_async (std::string(battery_left_click_command).c_str(), NULL) == FALSE)
+ g_warning ("Couldn't execute command: %s", std::string(battery_left_click_command).c_str());
+ }
+}
+
+
void WayfireBatteryInfo::update_state()
{
std::cout << "unimplemented reached, in battery.cpp: "
@@ -234,6 +245,8 @@ void WayfireBatteryInfo::init(Gtk::HBox *container)
button_box.add(icon);
button.get_style_context()->add_class("battery");
button.get_style_context()->add_class("flat");
+ button.signal_button_press_event().connect_notify(
+ sigc::mem_fun(this, &WayfireBatteryInfo::button_press_cb));
status_opt.set_callback([=] () { update_details(); });
font_opt.set_callback([=] () { update_font(); });
diff --git a/src/panel/widgets/battery.hpp b/src/panel/widgets/battery.hpp
index b2a5d986..817a5761 100644
--- a/src/panel/widgets/battery.hpp
+++ b/src/panel/widgets/battery.hpp
@@ -25,6 +25,7 @@ class WayfireBatteryInfo : public WayfireWidget
WfOption font_opt{"panel/battery_font"};
WfOption size_opt{"panel/battery_icon_size"};
WfOption invert_opt{"panel/battery_icon_invert"};
+ WfOption battery_left_click_command{"panel/battery_left_click_command"};
Gtk::Button button;
Gtk::Label label;
@@ -41,6 +42,7 @@ class WayfireBatteryInfo : public WayfireWidget
void update_icon();
void update_details();
void update_state();
+ void button_press_cb(GdkEventButton *event);
void on_properties_changed(
const Gio::DBus::Proxy::MapChangedProperties& properties,
diff --git a/src/panel/widgets/language.cpp b/src/panel/widgets/language.cpp
new file mode 100644
index 00000000..66ceff66
--- /dev/null
+++ b/src/panel/widgets/language.cpp
@@ -0,0 +1,156 @@
+#include
+#include
+#include
+
+#include
+#include
+
+#include