mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 11:12:45 +00:00 
			
		
		
		
	WindowServer+Keymap+LibGUI: Add widget to display current keymap
This commit is contained in:
		
							parent
							
								
									68a01f0e27
								
							
						
					
					
						commit
						b9c558f6c6
					
				
					 14 changed files with 160 additions and 17 deletions
				
			
		|  | @ -32,7 +32,7 @@ DoubleClickSpeed=250 | |||
| Mode=stretch | ||||
| 
 | ||||
| [Applet] | ||||
| Order=WorkspacePicker,CPUGraph,MemoryGraph,Network,ClipboardHistory,Audio | ||||
| Order=WorkspacePicker,CPUGraph,MemoryGraph,Network,ClipboardHistory,Audio,Keymap | ||||
| 
 | ||||
| [Workspaces] | ||||
| Rows=2 | ||||
|  |  | |||
|  | @ -3,3 +3,4 @@ add_subdirectory(ClipboardHistory) | |||
| add_subdirectory(Network) | ||||
| add_subdirectory(ResourceGraph) | ||||
| add_subdirectory(WorkspacePicker) | ||||
| add_subdirectory(Keymap) | ||||
|  |  | |||
							
								
								
									
										13
									
								
								Userland/Applets/Keymap/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Userland/Applets/Keymap/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| serenity_component( | ||||
|     Keymap.Applet | ||||
|     REQUIRED | ||||
|     TARGETS Keymap.Applet | ||||
| ) | ||||
| 
 | ||||
| set(SOURCES | ||||
|     KeymapStatusWindow.cpp | ||||
|     main.cpp | ||||
| ) | ||||
| 
 | ||||
| serenity_bin(Keymap.Applet) | ||||
| target_link_libraries(Keymap.Applet LibGUI LibCore LibGfx LibMain LibKeyboard) | ||||
							
								
								
									
										44
									
								
								Userland/Applets/Keymap/KeymapStatusWindow.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								Userland/Applets/Keymap/KeymapStatusWindow.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2021, Timur Sultanov <SultanovTS@yandex.ru> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #include "KeymapStatusWindow.h" | ||||
| #include <LibGUI/Painter.h> | ||||
| #include <LibGUI/WindowManagerServerConnection.h> | ||||
| #include <LibKeyboard/CharacterMap.h> | ||||
| 
 | ||||
| KeymapStatusWindow::KeymapStatusWindow() | ||||
| { | ||||
|     set_window_type(GUI::WindowType::Applet); | ||||
|     set_has_alpha_channel(true); | ||||
|     m_label = &set_main_widget<GUI::Label>(); | ||||
| 
 | ||||
|     auto current_keymap = MUST(Keyboard::CharacterMap::fetch_system_map()); | ||||
|     auto current_keymap_name = current_keymap.character_map_name(); | ||||
|     m_label->set_tooltip(current_keymap_name); | ||||
|     m_label->set_text(current_keymap_name.substring(0, 2)); | ||||
| } | ||||
| 
 | ||||
| KeymapStatusWindow::~KeymapStatusWindow() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void KeymapStatusWindow::wm_event(GUI::WMEvent& event) | ||||
| { | ||||
|     if (event.type() == GUI::WMEvent::WM_KeymapChanged) { | ||||
|         auto& keymap_event = static_cast<GUI::WMKeymapChangedEvent&>(event); | ||||
|         auto keymap = keymap_event.keymap(); | ||||
|         set_keymap_text(keymap); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void KeymapStatusWindow::set_keymap_text(const String& keymap) | ||||
| { | ||||
|     GUI::Painter painter(*m_label); | ||||
|     painter.clear_rect(m_label->rect(), Color::from_rgba(0)); | ||||
| 
 | ||||
|     m_label->set_tooltip(keymap); | ||||
|     m_label->set_text(keymap.substring(0, 2)); | ||||
| } | ||||
							
								
								
									
										27
									
								
								Userland/Applets/Keymap/KeymapStatusWindow.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Userland/Applets/Keymap/KeymapStatusWindow.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2021, Timur Sultanov <SultanovTS@yandex.ru> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <LibGUI/Label.h> | ||||
| #include <LibGUI/Window.h> | ||||
| 
 | ||||
| class KeymapStatusWidget; | ||||
| 
 | ||||
| class KeymapStatusWindow final : public GUI::Window { | ||||
|     C_OBJECT(KeymapStatusWindow) | ||||
| public: | ||||
|     virtual ~KeymapStatusWindow() override; | ||||
| 
 | ||||
| private: | ||||
|     void wm_event(GUI::WMEvent&) override; | ||||
| 
 | ||||
|     KeymapStatusWindow(); | ||||
| 
 | ||||
|     RefPtr<GUI::Label> m_label; | ||||
| 
 | ||||
|     void set_keymap_text(String const& keymap); | ||||
| }; | ||||
							
								
								
									
										30
									
								
								Userland/Applets/Keymap/main.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Userland/Applets/Keymap/main.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2021, Timur Sultanov <SultanovTS@yandex.ru> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #include "KeymapStatusWindow.h" | ||||
| #include <LibCore/System.h> | ||||
| #include <LibGUI/Application.h> | ||||
| #include <LibGUI/WindowManagerServerConnection.h> | ||||
| #include <LibMain/Main.h> | ||||
| #include <WindowServer/Window.h> | ||||
| 
 | ||||
| ErrorOr<int> serenity_main(Main::Arguments arguments) | ||||
| { | ||||
|     TRY(Core::System::pledge("stdio recvfd sendfd rpath unix getkeymap")); | ||||
| 
 | ||||
|     auto app = TRY(GUI::Application::try_create(arguments)); | ||||
| 
 | ||||
|     auto window = TRY(KeymapStatusWindow::try_create()); | ||||
|     window->set_has_alpha_channel(true); | ||||
|     window->set_title("Keymap"); | ||||
|     window->resize(16, 16); | ||||
|     window->show(); | ||||
|     window->make_window_manager(WindowServer::WMEventMask::KeymapChanged); | ||||
| 
 | ||||
|     TRY(Core::System::pledge("stdio recvfd sendfd rpath getkeymap")); | ||||
| 
 | ||||
|     return app->exec(); | ||||
| } | ||||
|  | @ -67,6 +67,7 @@ public: | |||
|         WM_SuperKeyPressed, | ||||
|         WM_SuperSpaceKeyPressed, | ||||
|         WM_WorkspaceChanged, | ||||
|         WM_KeymapChanged, | ||||
|         __End_WM_Events, | ||||
|     }; | ||||
| 
 | ||||
|  | @ -228,6 +229,20 @@ private: | |||
|     const unsigned m_current_column; | ||||
| }; | ||||
| 
 | ||||
| class WMKeymapChangedEvent : public WMEvent { | ||||
| public: | ||||
|     explicit WMKeymapChangedEvent(int client_id, String const& keymap) | ||||
|         : WMEvent(Event::Type::WM_KeymapChanged, client_id, 0) | ||||
|         , m_keymap(keymap) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     String const& keymap() const { return m_keymap; } | ||||
| 
 | ||||
| private: | ||||
|     const String m_keymap; | ||||
| }; | ||||
| 
 | ||||
| class MultiPaintEvent final : public Event { | ||||
| public: | ||||
|     explicit MultiPaintEvent(Vector<Gfx::IntRect, 32> rects, Gfx::IntSize const& window_size) | ||||
|  |  | |||
|  | @ -70,4 +70,10 @@ void WindowManagerServerConnection::workspace_changed(i32 wm_id, u32 row, u32 co | |||
|         Core::EventLoop::current().post_event(*window, make<WMWorkspaceChangedEvent>(wm_id, row, column)); | ||||
| } | ||||
| 
 | ||||
| void WindowManagerServerConnection::keymap_changed(i32 wm_id, String const& keymap) | ||||
| { | ||||
|     if (auto* window = Window::from_window_id(wm_id)) | ||||
|         Core::EventLoop::current().post_event(*window, make<WMKeymapChangedEvent>(wm_id, keymap)); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ private: | |||
|     virtual void super_key_pressed(i32) override; | ||||
|     virtual void super_space_key_pressed(i32) override; | ||||
|     virtual void workspace_changed(i32, u32, u32) override; | ||||
|     virtual void keymap_changed(i32, String const&) override; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -12,17 +12,8 @@ | |||
| 
 | ||||
| namespace WindowServer { | ||||
| 
 | ||||
| static KeymapSwitcher* s_the; | ||||
| 
 | ||||
| KeymapSwitcher& KeymapSwitcher::the() | ||||
| { | ||||
|     VERIFY(s_the); | ||||
|     return *s_the; | ||||
| } | ||||
| 
 | ||||
| KeymapSwitcher::KeymapSwitcher() | ||||
| { | ||||
|     s_the = this; | ||||
| } | ||||
| 
 | ||||
| KeymapSwitcher::~KeymapSwitcher() | ||||
|  | @ -80,10 +71,7 @@ String KeymapSwitcher::get_current_keymap() const | |||
|     auto json = JsonValue::from_string(proc_keymap->read_all()).release_value_but_fixme_should_propagate_errors(); | ||||
|     auto const& keymap_object = json.as_object(); | ||||
|     VERIFY(keymap_object.has("keymap")); | ||||
|     auto keymap = keymap_object.get("keymap").to_string(); | ||||
|     dbgln("Current keymap is: {}", keymap); | ||||
| 
 | ||||
|     return keymap; | ||||
|     return keymap_object.get("keymap").to_string(); | ||||
| } | ||||
| 
 | ||||
| void KeymapSwitcher::setkeymap(const AK::String& keymap) | ||||
|  | @ -94,6 +82,8 @@ void KeymapSwitcher::setkeymap(const AK::String& keymap) | |||
|         perror("posix_spawn"); | ||||
|         dbgln("Failed to call /bin/keymap, error: {} ({})", errno, strerror(errno)); | ||||
|     } | ||||
|     if (on_keymap_change) | ||||
|         on_keymap_change(keymap); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -11,27 +11,29 @@ | |||
| #include <AK/WeakPtr.h> | ||||
| #include <LibCore/Object.h> | ||||
| #include <LibKeyboard/CharacterMap.h> | ||||
| #include <WindowServer/WMClientConnection.h> | ||||
| 
 | ||||
| namespace WindowServer { | ||||
| 
 | ||||
| class KeymapSwitcher final : public Core::Object { | ||||
|     C_OBJECT(KeymapSwitcher) | ||||
| public: | ||||
|     static KeymapSwitcher& the(); | ||||
| 
 | ||||
|     virtual ~KeymapSwitcher() override; | ||||
| 
 | ||||
|     void refresh(); | ||||
| 
 | ||||
|     void next_keymap(); | ||||
| 
 | ||||
|     Function<void(String const& keymap)> on_keymap_change; | ||||
| 
 | ||||
|     String get_current_keymap() const; | ||||
| 
 | ||||
| private: | ||||
|     KeymapSwitcher(); | ||||
| 
 | ||||
|     Vector<AK::String> m_keymaps; | ||||
| 
 | ||||
|     void setkeymap(AK::String const&); | ||||
|     String get_current_keymap() const; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ enum WMEventMask { | |||
|     WindowIconChanges = 1 << 2, | ||||
|     WindowRemovals = 1 << 3, | ||||
|     WorkspaceChanges = 1 << 4, | ||||
|     KeymapChanged = 1 << 5, | ||||
| }; | ||||
| 
 | ||||
| enum class WindowTileType { | ||||
|  |  | |||
|  | @ -53,6 +53,18 @@ WindowManager::WindowManager(Gfx::PaletteImpl const& palette) | |||
| 
 | ||||
|     reload_config(); | ||||
| 
 | ||||
|     m_keymap_switcher->on_keymap_change = [&](String const& keymap) { | ||||
|         for_each_window_manager([&keymap](WMClientConnection& conn) { | ||||
|             if (!(conn.event_mask() & WMEventMask::KeymapChanged)) | ||||
|                 return IterationDecision::Continue; | ||||
|             if (conn.window_id() < 0) | ||||
|                 return IterationDecision::Continue; | ||||
| 
 | ||||
|             conn.async_keymap_changed(conn.window_id(), keymap); | ||||
|             return IterationDecision::Continue; | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     Compositor::the().did_construct_window_manager({}); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,4 +10,5 @@ endpoint WindowManagerClient | |||
|     super_key_pressed(i32 wm_id) =| | ||||
|     super_space_key_pressed(i32 wm_id) =| | ||||
|     workspace_changed(i32 wm_id, u32 row, u32 column) =| | ||||
|     keymap_changed(i32 wm_id, [UTF8] String keymap) =| | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timur Sultanov
						Timur Sultanov