Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
steps:
- run: echo 'http://dl-cdn.alpinelinux.org/alpine/v3.22/community' > /etc/apk/repositories
- run: echo 'http://dl-cdn.alpinelinux.org/alpine/v3.22/main' >> /etc/apk/repositories
- run: apk --no-cache add git g++ binutils pkgconf meson ninja musl-dev gtkmm4-dev vala gobject-introspection gobject-introspection-dev pulseaudio-dev libdbusmenu-glib-dev alsa-lib-dev
- run: apk --no-cache add git g++ binutils pkgconf meson ninja musl-dev gtkmm4-dev vala gobject-introspection gobject-introspection-dev pulseaudio-dev libdbusmenu-glib-dev alsa-lib-dev yyjson-dev
- run: echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories
- run: echo 'http://dl-cdn.alpinelinux.org/alpine/edge/main' >> /etc/apk/repositories
- run: apk --no-cache add wayland-protocols wayfire-dev gtk4-layer-shell-dev gtk4-layer-shell
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "subprojects/gtk4-layer-shell"]
path = subprojects/gtk4-layer-shell
url = https://github.com/wmww/gtk4-layer-shell.git
[submodule "subprojects/wf-json"]
path = subprojects/wf-json
url = https://github.com/WayfireWM/wf-json
11 changes: 11 additions & 0 deletions data/css/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@
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;
}
.excellent {
color: #00ff00;
}
Expand Down
1 change: 1 addition & 0 deletions dependencies/wayfire-upstream
Submodule wayfire-upstream added at 60231d
2 changes: 2 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ gtklayershell = dependency('gtk4-layer-shell-0', fallback: ['gtk4-layer-shell'])
libpulse = dependency('libpulse', required: get_option('pulse'))
dbusmenu_gtk = dependency('dbusmenu-glib-0.4')
libgvc = subproject('gvc', default_options: ['static=true'], required: get_option('pulse'))
xkbregistry = dependency('xkbregistry')
json = subproject('wf-json').get_variable('wfjson')

if get_option('wayland-logout') == true
wayland_logout = subproject('wayland-logout')
Expand Down
3 changes: 3 additions & 0 deletions src/panel/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ widget_sources = [
'widgets/menu.cpp',
'widgets/clock.cpp',
'widgets/command-output.cpp',
'widgets/language.cpp',
'widgets/launchers.cpp',
'widgets/network.cpp',
'widgets/spacing.cpp',
Expand All @@ -29,6 +30,8 @@ deps = [
wf_protos,
wfconfig,
dbusmenu_gtk,
xkbregistry,
json,
]

if libpulse.found()
Expand Down
9 changes: 9 additions & 0 deletions src/panel/panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@
#include <gtk4-layer-shell.h>

#include <iostream>
#include <memory>
#include <sstream>

#include <map>
#include <css-config.hpp>
#include "panel.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 Down Expand Up @@ -184,6 +187,11 @@ class WayfirePanel::impl
return Widget(new WfCommandOutputButtons());
}

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

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

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

wl_surface*WayfirePanel::get_wl_surface()
{
return pimpl->get_wl_surface();
Expand Down
124 changes: 124 additions & 0 deletions src/panel/widgets/language.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include <cstddef>
#include <cstdint>
#include <glibmm.h>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <wayfire/util/log.hpp>
#include <xkbcommon/xkbregistry.h>
#include "language.hpp"
#include "gtkmm/button.h"
#include "sigc++/functors/mem_fun.h"
#include "wf-ipc.hpp"

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

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

container->append(button);
}

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

auto state_layout = data["state"]["layout-index"].as_uint();
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;
}

button.set_label(available_layouts[current_layout].ID);
return true;
}

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

void WayfireLanguage::set_available(wf::json_t 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;
}

wf::json_t message;
message["method"] = "wayfire/set-keyboard-state";
message["data"] = wf::json_t();
message["data"]["layout-index"] = next;
ipc_client->send(message.serialize());
}

WayfireLanguage::WayfireLanguage()
{
ipc_client = WayfireIPC::get_instance()->create_client();
}

WayfireLanguage::~WayfireLanguage()
{
ipc_client->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 <wayfire/nonstd/json.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;

std::shared_ptr<IPCClient> ipc_client;
uint32_t current_layout;
std::vector<Layout> available_layouts;

public:
void init(Gtk::Box *container);
void on_event(wf::json_t data) override;
bool update_label();
void set_current(uint32_t index);
void set_available(wf::json_t layouts);
void next_layout();
WayfireLanguage();
~WayfireLanguage();
};

#endif /* end of include guard: WIDGETS_LANGUAGE_HPP */
3 changes: 2 additions & 1 deletion src/util/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ util = static_library(
'wf-autohide-window.cpp',
'wf-popover.cpp',
'css-config.cpp',
'wf-ipc.cpp',
],
dependencies: [wf_protos, gtklayershell, wayland_client, gtkmm, wfconfig, libinotify],
dependencies: [wf_protos, gtklayershell, wayland_client, gtkmm, wfconfig, libinotify, json],
)

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