Skip to content

Commit

Permalink
fix: flicker on bottom, sticky dragging, no highlight color (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
eagleoflqj authored Feb 8, 2024
1 parent 0aff851 commit 8db198a
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 33 deletions.
9 changes: 8 additions & 1 deletion include/webview_candidate_window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@ class WebviewCandidateWindow : public CandidateWindow {
void hide() override;

void update_accent_color();
void set_accent_color();

private:
void set_transparent_background();
webview::webview w_;
void *listener_;
bool first_draw_ = true;
double cursor_x_ = 0;
double cursor_y_ = 0;
double x_ = 0;
double y_ = 0;
bool hidden_ = true;
bool was_above_ = false;
bool accent_color_nil_ = false;
int accent_color_ = 0;

private:
Expand Down
4 changes: 2 additions & 2 deletions page/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ declare global {
interface Window {
// C++ APIs that api.ts calls
_select: (index: number) => void
_resize: (x: number, y: number, width: number, height: number) => void
_resize: (dx: number, dy: number, width: number, height: number, dragging: boolean) => void

// JavaScript APIs that webview_candidate_window.mm calls
setCandidates: (cands: string[], labels: string[], highlighted: number) => void
setLayout: (layout: 0 | 1) => void
updateInputPanel: (preeditHTML: string, auxUpHTML: string, auxDownHTML: string) => void
resize: (x: number, y: number) => void
resize: (dx: number, dy: number, dragging: boolean) => void
setTheme: (theme: 0 | 1 | 2) => void
setAccentColor: (color: number | null) => void
}
Expand Down
2 changes: 1 addition & 1 deletion page/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</style>
</head>
<body>
<div class="panel macos">
<div class="panel macos blue">
<div class="panel-blur">
<div class="header">
<div class="aux-up hidden"></div>
Expand Down
10 changes: 3 additions & 7 deletions page/ux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@ import {
candidates
} from './selector'

let cursorX = 0
let cursorY = 0
let pressed = false
let dragging = false
let startX = 0
let startY = 0

export function resize (x: number, y: number) {
cursorX = x
cursorY = y
export function resize (dx: number, dy: number, dragging: boolean) {
const rect = panel.getBoundingClientRect()
window._resize(x, y, rect.width, rect.height)
window._resize(dx, dy, rect.width, rect.height, dragging)
}

document.addEventListener('mousedown', e => {
Expand All @@ -29,7 +25,7 @@ document.addEventListener('mousemove', e => {
}
dragging = true
// minus because macOS has bottom-left (0, 0)
resize(cursorX + (e.clientX - startX), cursorY - (e.clientY - startY))
resize(e.clientX - startX, -(e.clientY - startY), true)
})

document.addEventListener('mouseup', e => {
Expand Down
64 changes: 46 additions & 18 deletions src/webview_candidate_window.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ @implementation NotificationListener

- (void)accentColorChanged:(NSNotification *)notification {
self.candidateWindow->update_accent_color();
self.candidateWindow->set_accent_color();
}

@end
Expand All @@ -38,26 +39,38 @@ - (void)accentColorChanged:(NSNotification *)notification {
selector:@selector(accentColorChanged:)
name:@"AppleColorPreferencesChangedNotification"
object:nil];
update_accent_color();

bind("_resize", [this](double x, double y, double width, double height) {
bind("_resize", [this](double dx, double dy, double width, double height,
bool dragging) {
const int gap = 4;
const int preedit_height = 24;
int screen_width = [[NSScreen mainScreen] frame].size.width;

if (x + width > screen_width) {
x = screen_width - width;
}
if (x < 0) {
x = 0;
}
if (height + gap > y) { // No enough space underneath
y = std::max<double>(y + preedit_height + gap, 0);
if (dragging) {
x_ += dx;
y_ += dy;
} else {
y -= height + gap;
x_ = cursor_x_;
y_ = cursor_y_;
if (x_ + width > screen_width) {
x_ = screen_width - width;
}
if (x_ < 0) {
x_ = 0;
}
if (height + gap > y_ // No enough space underneath
|| (!hidden_ && was_above_)) { // It was above, avoid flicker
y_ = std::max<double>(y_ + preedit_height + gap, 0);
was_above_ = true;
} else {
y_ -= height + gap;
was_above_ = false;
}
}

hidden_ = false;
NSWindow *window = static_cast<NSWindow *>(w_.window());
[window setFrame:NSMakeRect(x, y, width, height)
[window setFrame:NSMakeRect(x_, y_, width, height)
display:YES
animate:NO];
[window orderFront:nil];
Expand Down Expand Up @@ -87,9 +100,18 @@ - (void)accentColorChanged:(NSNotification *)notification {
NSNumber *accentColor = [[NSUserDefaults standardUserDefaults]
objectForKey:@"AppleAccentColor"];
if (accentColor == nil) {
invoke_js("setAccentColor", nil);
accent_color_nil_ = true;
} else {
accent_color_nil_ = false;
accent_color_ = [accentColor intValue];
}
}

void WebviewCandidateWindow::set_accent_color() {
if (accent_color_nil_) {
invoke_js("setAccentColor", nullptr);
} else {
invoke_js("setAccentColor", [accentColor intValue]);
invoke_js("setAccentColor", accent_color_);
}
}

Expand All @@ -108,17 +130,23 @@ - (void)accentColorChanged:(NSNotification *)notification {
}

void WebviewCandidateWindow::show(double x, double y) {
if (first_draw_) {
first_draw_ = false;
update_accent_color();
cursor_x_ = x;
cursor_y_ = y;
// It's _resize which is called by resize that actually shows the window
if (hidden_) {
// Ideally this could be called only on first draw since we listen on
// accent color change, but the first draw may fail if webview is not
// warmed-up yet, and it won't be updated until user changes color.
set_accent_color();
}
invoke_js("resize", x, y);
invoke_js("resize", 0., 0., false);
}

void WebviewCandidateWindow::hide() {
auto window = static_cast<NSWindow *>(w_.window());
[window orderBack:nil];
[window setIsVisible:NO];
hidden_ = true;
}

static void build_html_open_tags(std::stringstream &ss, int flags) {
Expand Down
2 changes: 1 addition & 1 deletion tests/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
declare global {
type CppCall = {
resize: [number, number, number, number]
resize: [number, number, number, number, boolean]
} | {
select: number
}
Expand Down
2 changes: 1 addition & 1 deletion tests/test-generic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ test('HTML structure', async ({ page }) => {

const actual = (await panel(page).evaluate(el => el.outerHTML)).replaceAll('> <', '><')
const expected = `
<div class="panel dark">
<div class="blue panel dark">
<div class="panel-blur">
<div class="header">
<div class="aux-up hidden"></div>
Expand Down
4 changes: 2 additions & 2 deletions tests/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ export async function init (page: Page) {
await page.evaluate(() => {
window.setTheme(2)
window.cppCalls = []
window._resize = (x: number, y: number, width: number, height: number) => {
window._resize = (dx: number, dy: number, width: number, height: number, dragging: boolean) => {
window.cppCalls.push({
resize: [x, y, width, height]
resize: [dx, dy, width, height, dragging]
})
}
window._select = (index: number) => {
Expand Down

0 comments on commit 8db198a

Please sign in to comment.