mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
WindowServer: Put a clock in the top right corner of the screen.
This way we don't even need the Clock app anymore. Very cool :^)
This commit is contained in:
parent
cac8153436
commit
c5a00a56c8
Notes:
sideshowbarker
2024-07-19 15:45:43 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c5a00a56c83
7 changed files with 106 additions and 14 deletions
|
@ -64,6 +64,19 @@ static unsigned days_in_years_since_epoch(unsigned year)
|
|||
return days;
|
||||
}
|
||||
|
||||
void read_registers(unsigned& year, unsigned& month, unsigned& day, unsigned& hour, unsigned& minute, unsigned& second)
|
||||
{
|
||||
while (update_in_progress())
|
||||
;
|
||||
|
||||
year = (CMOS::read(0x32) * 100) + CMOS::read(0x09);
|
||||
month = CMOS::read(0x08);
|
||||
day = CMOS::read(0x07);
|
||||
hour = CMOS::read(0x04);
|
||||
minute = CMOS::read(0x02);
|
||||
second = CMOS::read(0x00);
|
||||
}
|
||||
|
||||
time_t now()
|
||||
{
|
||||
// FIXME: We should probably do something more robust here.
|
||||
|
@ -72,12 +85,8 @@ time_t now()
|
|||
while (update_in_progress())
|
||||
;
|
||||
|
||||
unsigned year = (CMOS::read(0x32) * 100) + CMOS::read(0x09);
|
||||
unsigned month = CMOS::read(0x08);
|
||||
unsigned day = CMOS::read(0x07);
|
||||
unsigned hour = CMOS::read(0x04);
|
||||
unsigned minute = CMOS::read(0x02);
|
||||
unsigned second = CMOS::read(0x00);
|
||||
unsigned year, month, day, hour, minute, second;
|
||||
read_registers(year, month, day, hour, minute, second);
|
||||
|
||||
ASSERT(year >= 2018);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace RTC {
|
|||
void initialize();
|
||||
time_t now();
|
||||
time_t boot_time();
|
||||
void read_registers(unsigned& year, unsigned& month, unsigned& day, unsigned& hour, unsigned& minute, unsigned& second);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
//#define SPAWN_GUITEST
|
||||
#define SPAWN_LAUNCHER
|
||||
//#define SPAWN_GUITEST2
|
||||
#define SPAWN_CLOCK
|
||||
#define SPAWN_FILE_MANAGER
|
||||
//#define SPAWN_FONTEDITOR
|
||||
//#define SPAWN_MULTIPLE_SHELLS
|
||||
|
@ -116,9 +115,6 @@ static void init_stage2()
|
|||
#ifdef SPAWN_LAUNCHER
|
||||
Process::create_user_process("/bin/Launcher", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, { }, tty0);
|
||||
#endif
|
||||
#ifdef SPAWN_CLOCK
|
||||
Process::create_user_process("/bin/Clock", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, { }, tty0);
|
||||
#endif
|
||||
#ifdef SPAWN_FILE_MANAGER
|
||||
Process::create_user_process("/bin/FileManager", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, { }, tty0);
|
||||
#endif
|
||||
|
|
|
@ -110,6 +110,37 @@ void WSMessageLoop::post_message(WSMessageReceiver* receiver, OwnPtr<WSMessage>&
|
|||
m_server_process->request_wakeup();
|
||||
}
|
||||
|
||||
void WSMessageLoop::Timer::reload()
|
||||
{
|
||||
struct timeval now;
|
||||
current->sys$gettimeofday(&now);
|
||||
next_fire_time = {
|
||||
now.tv_sec + (interval / 1000),
|
||||
now.tv_usec + (interval % 1000)
|
||||
};
|
||||
}
|
||||
|
||||
int WSMessageLoop::start_timer(int interval, Function<void()>&& callback)
|
||||
{
|
||||
auto timer = make<Timer>();
|
||||
int timer_id = m_next_timer_id++;
|
||||
timer->timer_id = timer_id;
|
||||
timer->callback = move(callback);
|
||||
timer->interval = interval;
|
||||
timer->reload();
|
||||
m_timers.set(timer_id, move(timer));
|
||||
return timer_id;
|
||||
}
|
||||
|
||||
int WSMessageLoop::stop_timer(int timer_id)
|
||||
{
|
||||
auto it = m_timers.find(timer_id);
|
||||
if (it == m_timers.end())
|
||||
return -1;
|
||||
m_timers.remove(it);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WSMessageLoop::wait_for_message()
|
||||
{
|
||||
fd_set rfds;
|
||||
|
@ -123,7 +154,19 @@ void WSMessageLoop::wait_for_message()
|
|||
params.writefds = nullptr;
|
||||
params.exceptfds = nullptr;
|
||||
struct timeval timeout = { 0, 0 };
|
||||
if (m_queued_messages.is_empty())
|
||||
bool had_any_timer = false;
|
||||
|
||||
for (auto& it : m_timers) {
|
||||
auto& timer = *it.value;
|
||||
if (!had_any_timer) {
|
||||
timeout = timer.next_fire_time;
|
||||
continue;
|
||||
}
|
||||
if (timer.next_fire_time.tv_sec > timeout.tv_sec || (timer.next_fire_time.tv_sec == timeout.tv_sec && timer.next_fire_time.tv_usec > timeout.tv_usec))
|
||||
timeout = timer.next_fire_time;
|
||||
}
|
||||
|
||||
if (m_timers.is_empty() && m_queued_messages.is_empty())
|
||||
params.timeout = nullptr;
|
||||
else
|
||||
params.timeout = &timeout;
|
||||
|
@ -134,6 +177,16 @@ void WSMessageLoop::wait_for_message()
|
|||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
struct timeval now;
|
||||
current->sys$gettimeofday(&now);
|
||||
for (auto& it : m_timers) {
|
||||
auto& timer = *it.value;
|
||||
if (now.tv_sec > timer.next_fire_time.tv_sec || (now.tv_sec == timer.next_fire_time.tv_sec && now.tv_usec > timer.next_fire_time.tv_usec)) {
|
||||
timer.callback();
|
||||
timer.reload();
|
||||
}
|
||||
}
|
||||
|
||||
if (bitmap.get(m_keyboard_fd))
|
||||
drain_keyboard();
|
||||
if (bitmap.get(m_mouse_fd))
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
#include "WSMessage.h"
|
||||
#include <AK/Lock.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <AK/Function.h>
|
||||
|
||||
class WSMessageReceiver;
|
||||
class Process;
|
||||
|
@ -24,6 +26,9 @@ public:
|
|||
|
||||
void set_server_process(Process& process) { m_server_process = &process; }
|
||||
|
||||
int start_timer(int ms, Function<void()>&&);
|
||||
int stop_timer(int timer_id);
|
||||
|
||||
private:
|
||||
void wait_for_message();
|
||||
void drain_mouse();
|
||||
|
@ -42,4 +47,16 @@ private:
|
|||
|
||||
int m_keyboard_fd { -1 };
|
||||
int m_mouse_fd { -1 };
|
||||
|
||||
struct Timer {
|
||||
void reload();
|
||||
|
||||
int timer_id { 0 };
|
||||
int interval { 0 };
|
||||
struct timeval next_fire_time { 0, 0 };
|
||||
Function<void()> callback;
|
||||
};
|
||||
|
||||
int m_next_timer_id { 1 };
|
||||
HashMap<int, OwnPtr<Timer>> m_timers;
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "WSMenu.h"
|
||||
#include "WSMenuBar.h"
|
||||
#include "WSMenuItem.h"
|
||||
#include <Kernel/RTC.h>
|
||||
|
||||
//#define DEBUG_COUNTERS
|
||||
//#define DEBUG_WID_IN_TITLE_BAR
|
||||
|
@ -210,6 +211,10 @@ WSWindowManager::WSWindowManager()
|
|||
// NOTE: This ensures that the system menu has the correct dimensions.
|
||||
set_current_menubar(nullptr);
|
||||
|
||||
WSMessageLoop::the().start_timer(300, [this] {
|
||||
invalidate(menubar_rect());
|
||||
});
|
||||
|
||||
invalidate();
|
||||
compose();
|
||||
}
|
||||
|
@ -226,16 +231,20 @@ void WSWindowManager::for_each_active_menubar_menu(Callback callback)
|
|||
m_current_menubar->for_each_menu(callback);
|
||||
}
|
||||
|
||||
int WSWindowManager::menubar_menu_margin() const
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
m_current_menubar = menubar;
|
||||
dbgprintf("[WM] Current menubar is now %p\n", menubar);
|
||||
int menu_margin = 16;
|
||||
Point next_menu_location { menu_margin / 2, 3 };
|
||||
Point next_menu_location { menubar_menu_margin() / 2, 3 };
|
||||
for_each_active_menubar_menu([&] (WSMenu& menu) {
|
||||
int text_width = font().width(menu.name());
|
||||
menu.set_rect_in_menubar({ next_menu_location.x() - menu_margin / 2, 0, text_width + menu_margin, menubar_rect().height() - 1 });
|
||||
menu.set_rect_in_menubar({ next_menu_location.x() - menubar_menu_margin() / 2, 0, text_width + menubar_menu_margin(), menubar_rect().height() - 1 });
|
||||
menu.set_text_rect_in_menubar({ next_menu_location, { text_width, font().glyph_height() } });
|
||||
next_menu_location.move_by(menu.rect_in_menubar().width(), 0);
|
||||
return true;
|
||||
|
@ -682,6 +691,12 @@ void WSWindowManager::draw_menubar()
|
|||
m_back_painter->draw_text(menu.text_rect_in_menubar(), menu.name(), TextAlignment::CenterLeft, text_color);
|
||||
return true;
|
||||
});
|
||||
|
||||
unsigned year, month, day, hour, minute, second;
|
||||
RTC::read_registers(year, month, day, hour, minute, second);
|
||||
auto time_text = String::format("%04u-%02u-%02u %02u:%02u:%02u", year, month, day, hour, minute, second);
|
||||
auto time_rect = menubar_rect().translated(-(menubar_menu_margin() / 2), 0);
|
||||
m_back_painter->draw_text(time_rect, time_text, TextAlignment::CenterRight, Color::Black);
|
||||
}
|
||||
|
||||
void WSWindowManager::draw_cursor()
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
|
||||
void close_menu(WSMenu&);
|
||||
Color menu_selection_color() const { return m_menu_selection_color; }
|
||||
int menubar_menu_margin() const;
|
||||
|
||||
int api$menubar_create();
|
||||
int api$menubar_destroy(int menubar_id);
|
||||
|
|
Loading…
Reference in a new issue