lvgl / lvgl

Embedded graphics library to create beautiful UIs for any MCU, MPU and display type.
https://lvgl.io
MIT License
17.5k stars 3.29k forks source link

After using the Pinyin plugin of the Chinese character library, it will crash when entering specific uppercase letters. #6843

Closed proyrb-petalmail closed 1 month ago

proyrb-petalmail commented 2 months ago

LVGL version

v9.2.0

What happened?

I added a Pinyin plugin to my keyboard and used a custom font library and dictionary.

At this point, I can input Chinese using the keyboard normally, but when I switch to uppercase English letters for input, the problem I want to mention arises: "First, clear the content of the text editing area bound to the keyboard, and then click on any of these uppercase letters (T, P, D, H, L, X) on the keyboard, which will cause the lvgl program to crash.

Codes (from gui.cpp):

lv_obj_t *const keyboard = lv_keyboard_create(screen);
lv_obj_set_size(keyboard, lv_obj_get_width(screen), lv_obj_get_height(screen) / 3);
lv_keyboard_set_textarea(keyboard, textarea);

lv_obj_t *const pinyin = lv_ime_pinyin_create(screen);
lv_obj_set_style_bg_opa(pinyin, LV_OPA_COVER, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(pinyin, lv_color_hex(FOREGROUND_COLOR), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_font(pinyin, &lv_font_custom_30, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_ime_pinyin_set_dict(pinyin, lv_ime_pinyin_def_dict);
lv_ime_pinyin_set_keyboard(pinyin, keyboard);

An example video: Uploading c45aef4b6925a65ce540b146ac4fb429.mp4…

How to reproduce?

From the repository: duo_app

Gui.cpp

#include "gui.hpp"
#include "debug.hpp"
#include "error.hpp"
#include "lvgl.h"

#include <unistd.h>

#define BACKGROUND_COLOR 0xEEEEEE
#define FOREGROUND_COLOR 0xFFFFFF
#define CONTAINER_MARGIN 100
#define BAR_HEIGHT       100
#define BAR_RADIUS       BAR_HEIGHT / 4
#define EXIT_BUTTON_SIZE BAR_HEIGHT * 0.7
#define BAR_PAD          (BAR_HEIGHT - EXIT_BUTTON_SIZE) / 2

using namespace std;

namespace NAMESPACE
{
    void gui::quit(lv_event_t *event)
    {
        LOG_MESSAGE("quit");
        exit(0);
    }

    gui *gui::only_one = nullptr;

    gui::gui(context *const context)
    {
        this->context_pointer = context;
        LOG_MESSAGE("initialize variables");

        lv_init();
        LOG_MESSAGE("initialize lvgl");

        LOG_MESSAGE("generate only_one");
    }

    gui::~gui() {}

    void gui::deploy(void)
    {
        lv_obj_t *const screen = lv_screen_active();
        lv_obj_set_style_bg_color(screen, lv_color_hex(BACKGROUND_COLOR), LV_PART_MAIN | LV_STATE_DEFAULT);
        LOG_MESSAGE("deploy screen");

        lv_obj_t *const container = lv_obj_create(screen);
        lv_obj_remove_style_all(container);
        lv_obj_set_size(container, lv_obj_get_width(screen) - 2 * CONTAINER_MARGIN, lv_obj_get_height(screen) - 2 * CONTAINER_MARGIN);
        lv_obj_set_align(container, LV_ALIGN_CENTER);
        lv_obj_remove_flag(container, LV_OBJ_FLAG_SCROLLABLE);
        lv_obj_update_layout(screen);
        LOG_MESSAGE("deploy container");

        lv_obj_t *const bar = lv_obj_create(container);
        lv_obj_set_size(bar, lv_obj_get_width(container), BAR_HEIGHT);
        lv_obj_set_align(bar, LV_ALIGN_TOP_MID);
        lv_obj_set_style_bg_color(bar, lv_color_hex(FOREGROUND_COLOR), LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_set_style_radius(bar, BAR_RADIUS, LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_set_style_pad_hor(bar, BAR_PAD, LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_remove_flag(bar, LV_OBJ_FLAG_SCROLLABLE);
        lv_obj_update_layout(screen);
        LOG_MESSAGE("deploy bar");

        lv_obj_t *const exit_button = lv_button_create(bar);
        lv_obj_set_size(exit_button, EXIT_BUTTON_SIZE, EXIT_BUTTON_SIZE);
        lv_obj_set_align(exit_button, LV_ALIGN_LEFT_MID);
        lv_obj_set_style_bg_opa(exit_button, LV_OPA_0, LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_set_style_bg_image_src(exit_button, this->context_pointer->get_exit_button_image_path().data(), LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_remove_flag(exit_button, LV_OBJ_FLAG_SCROLLABLE);
        lv_obj_add_event_cb(exit_button, quit, LV_EVENT_SHORT_CLICKED, NULL);
        lv_obj_update_layout(screen);
        LOG_MESSAGE("deploy exit_button");

        lv_obj_t *const label = lv_label_create(bar);
        lv_obj_set_align(label, LV_ALIGN_LEFT_MID);
        lv_obj_set_pos(label, lv_obj_get_width(exit_button) + BAR_PAD, 0);
        lv_obj_set_style_text_font(label, &lv_font_custom_40, LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_label_set_text(label, this->context_pointer->get_title().data());
        lv_obj_remove_flag(label, LV_OBJ_FLAG_SCROLLABLE);
        lv_obj_update_layout(screen);
        LOG_MESSAGE("deploy label");

        lv_obj_t *const textarea = lv_textarea_create(container);
        lv_obj_set_size(textarea, lv_obj_get_width(container), lv_pct(40));
        lv_obj_set_align(textarea, LV_ALIGN_TOP_MID);
        lv_obj_set_pos(textarea, 0, lv_obj_get_height(bar) + BAR_PAD);
        lv_obj_set_style_bg_color(textarea, lv_color_hex(FOREGROUND_COLOR), LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_set_style_radius(textarea, BAR_RADIUS, LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_set_style_pad_hor(textarea, BAR_PAD, LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_set_style_text_font(textarea, &lv_font_custom_30, LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_textarea_set_placeholder_text(textarea, "请输入");
        lv_obj_remove_flag(textarea, LV_OBJ_FLAG_SCROLLABLE);
        lv_obj_update_layout(screen);
        LOG_MESSAGE("deploy textarea");

        lv_obj_t *const keyboard = lv_keyboard_create(screen);
        lv_obj_set_size(keyboard, lv_obj_get_width(screen), lv_obj_get_height(screen) / 3);
        lv_keyboard_set_textarea(keyboard, textarea);
        LOG_MESSAGE("deploy keyboard");

        lv_obj_t *const pinyin = lv_ime_pinyin_create(screen);
        lv_obj_set_style_bg_opa(pinyin, LV_OPA_COVER, LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_set_style_bg_color(pinyin, lv_color_hex(FOREGROUND_COLOR), LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_obj_set_style_text_font(pinyin, &lv_font_custom_30, LV_PART_MAIN | LV_STATE_DEFAULT);
        lv_ime_pinyin_set_dict(pinyin, lv_ime_pinyin_def_dict);
        lv_ime_pinyin_set_keyboard(pinyin, keyboard);
        LOG_MESSAGE("deploy pinyin");
    }

    gui *const gui::get_only_one()
    {
        if (nullptr == gui::only_one)
        {
            LOG_MESSAGE("only_one need a context existed");
        }
        return gui::only_one;
    }

    gui *const gui::get_only_one(context *const context)
    {
        if (nullptr == context)
        {
            LOG_MESSAGE("only_one need a context existed");
            return nullptr;
        }

        if (nullptr != gui::only_one)
        {
            LOG_MESSAGE("only_one existed");
            return gui::only_one;
        }

        gui::only_one = new gui(context);

        return gui::only_one;
    }

    void gui::initialize(const string &fbdev, const string &evdev)
    {
        try
        {
            lv_display_t *display = lv_linux_fbdev_create();
            if (nullptr == display)
            {
                string error_information(ERROR_INFORMATION("failed to create display")); /* generate information of error */
                throw error(error_type_enum::CREATE_ERROR, error_information);           /* throw error */
            }
            LOG_MESSAGE("create display" COLON << display);

            lv_linux_fbdev_set_file(display, fbdev.data());
            LOG_MESSAGE("set fbdev driver" COLON << fbdev.data());

            lv_display_set_rotation(display, LV_DISPLAY_ROTATION_0);
            LOG_MESSAGE("set display rotation" COLON << lv_display_get_rotation(display));

            lv_indev_t *evdev_driver = lv_evdev_create(LV_INDEV_TYPE_POINTER, evdev.data());
            if (nullptr == evdev_driver)
            {
                string error_information(ERROR_INFORMATION("failed to create evdev")); /* generate information of error */
                throw error(error_type_enum::CREATE_ERROR, error_information);         /* throw error */
            }
            LOG_MESSAGE("create evdev" COLON << evdev_driver);
            LOG_MESSAGE("set evdev driver" COLON << evdev.data());
        }
        catch (error &error)
        {
            cerr << error.get_type_name() << COLON << error.get_message() << endl; /* output error information */
            exit(error.get_type_enum());                                           /* exit with error code */
        }
    }

    void gui::execute(void)
    {
        this->deploy(); /* deploy gui */

        while (true)
        {
            usleep(lv_timer_handler()); /* handle lvgl */
        }
    }
} // namespace NAMESPACE
kisvegabor commented 2 months ago

Hi,

I'm trying to reproduce it with lv_example_ime_pinyin_1 but it's working on my end. Can you try with the latest master?

proyrb-petalmail commented 2 months ago

Ok, i have take your suggestion. but it didn't work, emmmm. watch this mp4 and gif recorded.

https://github.com/user-attachments/assets/0314fa65-524e-4ebd-93cb-685d2f83fdf9

246acb4a99d07f9418a500b4d15fa9f1

proyrb-petalmail commented 2 months ago

Hi,

I'm trying to reproduce it with lv_example_ime_pinyin_1 but it's working on my end. Can you try with the latest master?

sorry, I've been busy lately and haven't replied in a timely manner。 i use my custom dictionary and font. i think it came of some settings at running set-function?

kisvegabor commented 1 month ago

I've tried it again here and it works like this: image

Can you send a more complete code to reproduce the issue? Including your custom directory.

lvgl-bot commented 1 month ago

We need some feedback on this issue.

Now we mark this as "Abandoned" because there was no activity here for 14 days.

Remove the "Stale" label or comment else this will be closed in 7 days.

kissa96 commented 1 month ago

@proyrb-petalmail Hi, how is the issue going? If resolved, can you please close it?