Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix active window not working on the framebuffer #94

Merged
merged 1 commit into from
Feb 2, 2025

Conversation

weihsinyeh
Copy link
Collaborator

Remove the inefficiently function twin_active_pixmap(). This function finds the currently and previously active window pixel map by traversing the list of pixel maps. This function will be called every time the screen needs to be updated. Set the active variable of the window only when the window's event TwinEventButtonDown is triggered to avoid redundant operations. Additionally, implement the function twin_window_active_paint() to only repaint the title bar instead of calling the function twin_window_draw() to indirectly call the function twin_window_frame to repaint the title bar of the window.

Close #92

src/window.c Outdated Show resolved Hide resolved
@shengwen-tw
Copy link
Collaborator

Looks legitimate to me, but since I am not familiar with recent developments, I would like to see if others have different opinions.

@huaxinliao
Copy link
Collaborator

huaxinliao commented Jan 26, 2025

I confirmed that fbdev can run on a VM with Ubuntu 24.04 and a Pi 3B. Below is the output from the Pi 3B.

test.mp4

@weihsinyeh
Copy link
Collaborator Author

The title bars of the active and inactive window don't display on the video.

src/window.c Outdated
twin_fixed_t bw_2 = bw / 2;
if (window->active) {
twin_paint_path(window->pixmap, TWIN_ACTIVE_BG, path);
twin_paint_stroke(window->pixmap, TWIN_ACTIVE_BORDER, path, bw_2 * 2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason that the title bars don't show is because you need to determine the trajectory you want to paint first and then use twin_paint_path or twin_paint_stroke to fill the graph or draw the border.

I think the twin_window_active_paint would be like

static void twin_window_active_paint(twin_window_t *window)
{
    // Ignore the above
    twin_path_t *path = twin_path_create();
    twin_path_move(path, c_left, c_top);
    twin_path_draw(path, c_right, c_top);
    twin_path_curve(path, c_right, w_top + t_arc_1, c_right - t_arc_1, w_top,
                    c_right - t_h, w_top);
    twin_path_draw(path, c_left + t_h, w_top);
    twin_path_curve(path, c_left + t_arc_1, w_top, c_left, w_top + t_arc_1,
                    c_left, c_top);
    twin_path_close(path);
    if (window->active) {
        twin_paint_path(window->pixmap, TWIN_ACTIVE_BG, path);
        twin_paint_stroke(window->pixmap, TWIN_ACTIVE_BORDER, path, bw_2 * 2);
    } else {
        twin_paint_path(window->pixmap, TWIN_INACTIVE_BG, path);
        twin_paint_stroke(window->pixmap, TWIN_INACTIVE_BORDER, path, bw_2 * 2);
    }
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! It seems that using the "twin_window_frame()" function directly is still the better option. Originally, I thought this just changed the BG and border colors. But since there is no path record, it is not sure where to apply the colors.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about adding a twin_path_t *label_path member to twin_window_t? In twin_window_frame, you could initialize the path, and in twin_window_active_paint, determine the color to paint when the top window changes. Then you can still apply the colors in the same logic.

static void twin_window_active_paint(twin_window_t *window)
{
    twin_fixed_t bw = twin_int_to_fixed(TWIN_TITLE_BW);
    twin_path_t *path = twin_path_create();
    twin_fixed_t bw_2 = bw / 2;
    if (window->active) {
        twin_paint_path(window->pixmap, TWIN_ACTIVE_BG, window->label_path);
        twin_paint_stroke(window->pixmap, TWIN_ACTIVE_BORDER, window->label_path, bw_2 * 2);
    } else {
        twin_paint_path(window->pixmap, TWIN_INACTIVE_BG, window->label_path);
        twin_paint_stroke(window->pixmap, TWIN_INACTIVE_BORDER, window->label_path, bw_2 * 2);
    }
}

static void twin_window_frame(twin_window_t *window)
{
    /* Ignore the above */
    window->label_path = twin_path_create();
    twin_path_move(window->label_path, c_left, c_top);
    twin_path_draw(window->label_path, c_right, c_top);
    twin_path_curve(window->label_path, c_right, w_top + t_arc_1, c_right - t_arc_1, w_top,
                    c_right - t_h, w_top);
    twin_path_draw(window->label_path, c_left + t_h, w_top);
    twin_path_curve(window->label_path, c_left + t_arc_1, w_top, c_left, w_top + t_arc_1,
                    c_left, c_top);
    twin_path_close(window->label_path);
    twin_window_active_paint(window);
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, Thank you! we can try which one can work on framebuffer.

@huaxinliao
Copy link
Collaborator

Here's the output from 512a891 on the Pi 3B.

drm.mp4

include/twin.h Outdated Show resolved Hide resolved
@jserv jserv requested a review from ndsl7109256 January 29, 2025 12:31
src/window.c Outdated
@@ -157,7 +157,7 @@ void twin_window_set_name(twin_window_t *window, const char *name)
twin_window_draw(window);
}

static void twin_window_frame(twin_window_t *window)
void twin_window_frame(twin_window_t *window)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change this function from static to non-static?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because, originally, in order to call twin_window_frame() in _twin_box_dispatch(), I placed twin_window_frame() in twin.h. Therefore, I make this modification. However, I later changed the location where twin_window_frame() is called to achieve the same effect, so it no longer needs to be called in box.c. It was my mistake for forgetting to change it back.

@weihsinyeh
Copy link
Collaborator Author

At the beginning, is it reasonable for there to be no active window displayed?

@ndsl7109256
Copy link
Collaborator

At the beginning, is it reasonable for there to be no active window displayed?

On macOS, there is always an active window at the top, but I'm not sure how it performs on other platforms. Besides, I noticed that if I click the top window first, it doesn't get activated.

2025-02-01.2.44.09.mov

Remove the inefficiently function twin_active_pixmap(). This function
finds the currently and previously active window pixel map by traversing
the list of pixel maps. This function will be called every time the
screen needs to be updated. Set the active variable of the window only
when the window's event TwinEventButtonDown is triggered to avoid
redundant operations.

Close sysprog21#92

Signed-off-by: Wei-Hsin Yeh <[email protected]>
@huaxinliao
Copy link
Collaborator

Here's the output of fbdev from commit e80e45e on the Raspberry Pi 3B.

20250202_fbdev.mp4

@jserv jserv merged commit a290fd0 into sysprog21:main Feb 2, 2025
3 checks passed
@jserv
Copy link
Contributor

jserv commented Feb 2, 2025

Thank @weihsinyeh for contributing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unexpected null screen in Linux framebuffer backend
5 participants