Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions data/css/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,16 @@

.wf-panel .command-output.icon-bottom label {
padding-bottom: 5px;
}

.wf-panel .language {
min-width: 48px;
}

.wf-panel .language label {
background-color: #24283B;
padding: 5px;
margin: 5px;
border-radius: 3px;
color: #41A6B5;
}
2 changes: 2 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ 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')
json = dependency('nlohmann_json')

if get_option('wayland-logout') == true
wayland_logout = subproject('wayland-logout')
Expand Down
3 changes: 2 additions & 1 deletion src/panel/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ widget_sources = ['widgets/battery.cpp',
'widgets/menu.cpp',
'widgets/clock.cpp',
'widgets/command-output.cpp',
'widgets/language.cpp',
'widgets/launchers.cpp',
'widgets/network.cpp',
'widgets/spacing.cpp',
Expand All @@ -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, dbusmenu_gtk, xkbregistry]

if libpulse.found()
widget_sources += 'widgets/volume.cpp'
Expand Down
17 changes: 13 additions & 4 deletions src/panel/panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#include <gdk/gdkwayland.h>
#include <gtk-layer-shell.h>

#include <stdio.h>
#include <iostream>
#include <memory>
#include <sstream>

#include <map>
Expand All @@ -16,8 +16,10 @@
#include "panel.hpp"
#include "../util/gtk-utils.hpp"

#include "wf-ipc.hpp"
#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"
Expand All @@ -36,6 +38,7 @@
class WayfirePanel::impl
{
std::unique_ptr<WayfireAutohidingWindow> window;
WayfireIPC* ipc;

Gtk::HBox content_box;
Gtk::HBox left_box, center_box, right_box;
Expand Down Expand Up @@ -226,6 +229,11 @@ class WayfirePanel::impl
return Widget(new WfCommandOutputButtons());
}

if (name == "language")
{
return Widget(new WayfireLanguage(ipc));
}

if (auto pixel = widget_with_value(name, "spacing"))
{
return Widget(new WayfireSpacing(*pixel));
Expand Down Expand Up @@ -313,7 +321,7 @@ class WayfirePanel::impl
}

public:
impl(WayfireOutput *output) : output(output)
impl(WayfireOutput *output, WayfireIPC *ipc) : ipc(ipc), output(output)
{
create_window();
}
Expand Down Expand Up @@ -347,8 +355,9 @@ class WayfirePanel::impl
}
};

WayfirePanel::WayfirePanel(WayfireOutput *output) : pimpl(new impl(output))
WayfirePanel::WayfirePanel(WayfireOutput *output, WayfireIPC *ipc) : pimpl(new impl(output, ipc))
{}

wl_surface*WayfirePanel::get_wl_surface()
{
return pimpl->get_wl_surface();
Expand Down Expand Up @@ -437,7 +446,7 @@ void WayfirePanelApp::add_css_file(std::string file, int priority)
void WayfirePanelApp::handle_new_output(WayfireOutput *output)
{
priv->panels[output] = std::unique_ptr<WayfirePanel>(
new WayfirePanel(output));
new WayfirePanel(output, ipc));
}

WayfirePanel*WayfirePanelApp::panel_for_wl_output(wl_output *output)
Expand Down
3 changes: 2 additions & 1 deletion src/panel/panel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
#include <gtkmm/window.h>
#include <gtkmm/cssprovider.h>

#include "wf-ipc.hpp"
#include "wf-shell-app.hpp"

class WayfirePanel
{
public:
WayfirePanel(WayfireOutput *output);
WayfirePanel(WayfireOutput *output, WayfireIPC *ipc);

wl_surface *get_wl_surface();
Gtk::Window& get_window();
Expand Down
105 changes: 105 additions & 0 deletions src/panel/widgets/language.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include <cstddef>
#include <cstdint>
#include <glibmm.h>
#include <map>
#include <nlohmann/json_fwd.hpp>
#include <string>
#include <vector>
#include <xkbcommon/xkbregistry.h>
#include "language.hpp"
#include "gtkmm/button.h"
#include "sigc++/functors/mem_fun.h"

void WayfireLanguage::init(Gtk::HBox *container) {
button.get_style_context()->add_class("language");
button.add(label);
button.get_style_context()->add_class("flat");
button.get_style_context()->remove_class("activated");
button.signal_clicked().connect_notify(sigc::mem_fun(this, &WayfireLanguage::next_layout));
button.show();
label.show();

ipc->subscribe(this, {"keyboard-modifier-state-changed"});
ipc->send("{\"method\":\"wayfire/get-keyboard-state\"}", [=](nlohmann::json data) {
set_available(data["possible-layouts"]);
set_current(data["layout-index"]);
});

container->pack_start(button, false, false);
}

void WayfireLanguage::on_event(nlohmann::json data) {
if (data["event"] == "keyboard-modifier-state-changed") {
if (available_layouts.size() == 0) {
set_available(data["state"]["possible-layouts"]);
}

auto state_layout = data["state"]["layout-index"];
if (state_layout != current_layout) {
current_layout = state_layout;
set_current(state_layout);
}
}
}

bool WayfireLanguage::update_label() {
if (current_layout >= available_layouts.size()) {
return false;
}
label.set_text(available_layouts[current_layout].ID);
return true;
}

void WayfireLanguage::set_current(uint32_t index) {
current_layout = index;
update_label();
}

void WayfireLanguage::set_available(nlohmann::json layouts) {
std::vector<Layout> layouts_available;
std::map<std::string, uint32_t> names;

for(size_t i = 0; i < layouts.size(); i++) {
auto elem = layouts[i];
names[elem] = i;
layouts_available.push_back(Layout{
.Name = (std::string)elem,
.ID = "",
});
}

auto context = rxkb_context_new(RXKB_CONTEXT_NO_FLAGS);
rxkb_context_parse_default_ruleset(context);
auto rlayout = rxkb_layout_first(context);
for (; rlayout != NULL; rlayout = rxkb_layout_next(rlayout)) {
auto descr = rxkb_layout_get_description(rlayout);
auto name = names.find(descr);
if (name != names.end()) {
layouts_available[name->second].ID = rxkb_layout_get_brief(rlayout);
}
}

available_layouts = layouts_available;
update_label();
}

void WayfireLanguage::next_layout() {
uint32_t next = current_layout + 1;
if (next >= available_layouts.size())
{
next = 0;
}

nlohmann::json message;
message["method"] = "wayfire/set-keyboard-state";
message["data"] = nlohmann::json::object();
message["data"]["layout-index"] = next;
ipc->send(message.dump());
}

WayfireLanguage::WayfireLanguage(WayfireIPC *ipc): ipc(ipc)
{}

WayfireLanguage::~WayfireLanguage() {
ipc->unsubscribe(this);
}
40 changes: 40 additions & 0 deletions src/panel/widgets/language.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef WIDGETS_LANGUAGE_HPP
#define WIDGETS_LANGUAGE_HPP

#include "../widget.hpp"
#include "gtkmm/button.h"
#include "wf-ipc.hpp"
#include <cstdint>
#include <gtkmm/calendar.h>
#include <gtkmm/label.h>
#include <nlohmann/json_fwd.hpp>
#include <string>
#include <vector>

struct Layout
{
std::string Name;
std::string ID;
};

class WayfireLanguage : public WayfireWidget, public IIPCSubscriber
{
Gtk::Label label;
Gtk::Button button;

WayfireIPC *ipc;
uint32_t current_layout;
std::vector<Layout> available_layouts;

public:
void init(Gtk::HBox *container) override;
void on_event(nlohmann::json data) override;
bool update_label();
void set_current(uint32_t index);
void set_available(nlohmann::json layouts);
void next_layout();
WayfireLanguage(WayfireIPC *ipc);
~WayfireLanguage();
};

#endif /* end of include guard: WIDGETS_LANGUAGE_HPP */
4 changes: 2 additions & 2 deletions src/util/meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
util = static_library('util', ['gtk-utils.cpp', 'wf-shell-app.cpp', 'wf-autohide-window.cpp', 'wf-popover.cpp'],
dependencies: [wf_protos, wayland_client, gtkmm, wfconfig, libinotify, gtklayershell])
util = static_library('util', ['gtk-utils.cpp', 'wf-shell-app.cpp', 'wf-autohide-window.cpp', 'wf-popover.cpp', 'wf-ipc.cpp'],
dependencies: [wf_protos, wayland_client, gtkmm, wfconfig, libinotify, gtklayershell, json])

util_includes = include_directories('.')
libutil = declare_dependency(
Expand Down
Loading
Loading