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

Add initial browser application #189

Draft
wants to merge 68 commits into
base: master
Choose a base branch
from
Draft

Add initial browser application #189

wants to merge 68 commits into from

Conversation

Eeems
Copy link
Collaborator

@Eeems Eeems commented Mar 29, 2021

Fix #178

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new web browser application with a complete user interface.
    • Added a customizable keyboard interface for user input.
    • Implemented a status icon and swipe area for enhanced user interaction.
    • Added various QML components, including custom buttons, menus, and keyboard keys.
  • Improvements

    • Enhanced CSS styling for a consistent look across web pages.
    • Added functionality for handling relative URLs in HTML content.
    • Improved application configuration and package management for easier installation.
  • Bug Fixes

    • Updated versioning logic to improve settings migration.
  • Documentation

    • Added new resource files and configuration for the web browser application.

@todo
Copy link

todo bot commented Mar 29, 2021

handle displaying error

https://github.com/Eeems/oxide/blob/83d0869f4e3c9af5693d7fff986c8bd7052f9bf2/applications/web-browser/main.qml#L102-L107


This comment was generated by todo based on a TODO comment in 83d0869 in #189. cc @Eeems.

@Eeems Eeems linked an issue Mar 29, 2021 that may be closed by this pull request
@lgtm-com
Copy link

lgtm-com bot commented Mar 29, 2021

This pull request introduces 1 alert when merging 83d0869 into 29c9b26 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

Base automatically changed from feature/gesure_disable to master July 11, 2021 16:48
Copy link

coderabbitai bot commented Oct 3, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes introduce a new web browser application within the project. This includes the addition of a web-browser module, which is integrated into the build configuration and has dependencies on existing modules. New classes and components for managing application state, user input, and UI elements are created, including a keyboard handler and various QML components for the interface. Additional files for styling and scripting are added, along with a JSON configuration for the application. Package management scripts are updated to handle the new application.

Changes

File Change Summary
applications/applications.pro Added web-browser to SUBDIRS and established dependency on system-service.
applications/screenshot-viewer/controller.h Renamed macro CORRUPT_SETTINGS_VERSION to ANXIETY_SETTINGS_VERSION.
applications/web-browser/.gitignore Created a .gitignore file to specify ignored files for the web-browser directory.
applications/web-browser/controller.h Introduced Controller class for managing application state and settings.
applications/web-browser/keyboardhandler.h Added KeyboardHandler class for handling keyboard events.
applications/web-browser/main.cpp Created main application file, initialized app, registered KeyboardHandler for QML.
applications/web-browser/main.qml Introduced UI layout for the web browser application.
applications/web-browser/page.css Added CSS styles for HTML elements in the web browser.
applications/web-browser/page.js Introduced functions for converting relative URLs to absolute URLs in HTML content.
applications/web-browser/qml.qrc Created resource collection file for QML components and assets.
applications/web-browser/web-browser.pro Configured project settings for the web browser application.
applications/web-browser/widgets/AppItem.qml Added custom QML component for displaying UI items with icons and text.
applications/web-browser/widgets/BetterButton.qml Introduced custom button component with visual feedback.
applications/web-browser/widgets/BetterMenu.qml Created a custom menu component with checkable items.
applications/web-browser/widgets/Button.qml Added customizable button component with state management.
applications/web-browser/widgets/CustomMenu.qml Introduced custom menu bar component for the application.
applications/web-browser/widgets/Keyboard.qml Created graphical keyboard interface for user input.
applications/web-browser/widgets/KeyboardKey.qml Added component representing individual keyboard keys with functionality.
applications/web-browser/widgets/StatusIcon.qml Introduced status icon widget with image source property.
applications/web-browser/widgets/SwipeArea.qml Created custom MouseArea for handling swipe gestures.
assets/opt/usr/share/applications/codes.eeems.mold.oxide Added JSON configuration file for the web browser application.
package Updated package management script to include new application and refine existing logic.

Assessment against linked issues

Objective Addressed Explanation
Create a web browser application (#178)
Integrate basic functionalities for browsing
Ensure the application is simple and user-friendly

🐰 In the meadow where bunnies play,
A web browser blooms, bright as day.
With clicks and swipes, it dances anew,
A joyful leap, for me and you!
Hopping through pages, so sleek and spry,
Let's surf the web, oh my, oh my! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Eeems
Copy link
Collaborator Author

Eeems commented Oct 3, 2024

@coderabbitai review

Copy link

coderabbitai bot commented Oct 3, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Eeems
Copy link
Collaborator Author

Eeems commented Oct 3, 2024

@coderabbitai review

Copy link

coderabbitai bot commented Oct 3, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 58

🧹 Outside diff range and nitpick comments (31)
applications/web-browser/widgets/StatusIcon.qml (3)

1-3: LGTM! Consider using newer versions if possible.

The imports are correct and necessary for the components used in this file. However, you might want to consider using newer versions of QtQuick and QtQuick.Controls if your project supports them, as they may offer improved performance and additional features.


6-6: Consider dynamic text color for better visibility.

The white text color is hardcoded, which may not be suitable for all background colors. Consider using a dynamic color that adapts to the background to ensure readability in all scenarios.

You could use a function to determine the text color based on the background:

color: getContrastColor(parent.color)

function getContrastColor(bgColor) {
    // Implementation to determine contrasting color
    // Return either "white" or "black" based on bgColor
}

4-15: LGTM! Consider adding size constraints and documentation.

The overall implementation of the StatusIcon component looks good. It creates a reusable label with an embedded icon, which is a common pattern in user interfaces. Here are some suggestions for improvement:

  1. Add size constraints to ensure the component renders correctly at different sizes:
Label {
    property string source
    property int minimumHeight: 20  // Add this line
    property int minimumWidth: 20   // Add this line
    
    implicitHeight: Math.max(20, contentHeight)  // Add this line
    implicitWidth: Math.max(100, contentWidth)   // Add this line
    
    // ... rest of the code
}
  1. Add documentation comments to describe the purpose and usage of the component:
/**
 * StatusIcon
 *
 * A custom Label component that displays an icon on the left side of the text.
 *
 * @property {string} source - The source URL of the icon image
 */
Label {
    // ... rest of the code
}

These changes will improve the robustness and usability of your component.

applications/web-browser/qml.qrc (1)

4-6: Review usage of custom vs. standard components.

The resource file includes both custom components (e.g., BetterMenu, BetterButton) and standard components (e.g., Button). To ensure consistency in the UI and avoid unnecessary complexity:

  1. Review the usage of custom components (BetterMenu, BetterButton) to confirm they provide necessary additional functionality or styling over their standard counterparts.
  2. If custom components are just slight modifications of standard ones, consider using styling or theming to achieve the desired look instead of creating new components.
  3. Ensure there's clear documentation on when to use custom components vs. standard ones to maintain consistency across the application.

This review will help in maintaining a more consistent and maintainable codebase.

Also applies to: 9-9, 13-13

applications/web-browser/page.css (1)

1-10: Overall review: Significant refactoring needed

After reviewing the entire CSS file, here are the key points and recommendations:

  1. Syntax Errors: All rules in the file use incorrect CSS syntax (:style( instead of {}). These need to be corrected for the styles to work properly.

  2. Overuse of !important: The !important flag is used excessively throughout the file. This can lead to specificity issues and make the stylesheet hard to maintain. Consider removing these flags and restructuring your CSS to achieve the desired specificity through proper selector use.

  3. Broad Selectors: Many rules apply styles to a wide range of elements. Consider if this broad approach is necessary, or if more specific selectors would be more appropriate.

  4. Consistency: Ensure consistent formatting across all rules (indentation, spacing, etc.) for better readability.

  5. Image Grayscale: The blanket application of a grayscale filter to all images may not be desirable. Consider using a class for this instead.

Next steps:

  1. Implement all the suggested fixes for each rule.
  2. After fixing the syntax, test the styles to ensure they're applied as intended.
  3. Review the use of !important and broad selectors, refactoring where possible to improve maintainability.
  4. Consider breaking this file into logical sections or separate files if it grows larger, to improve organization.
  5. Implement a CSS linting tool in your development process to catch syntax errors early.

If you need any assistance with implementing these changes or want to discuss alternative approaches, please let me know.

🧰 Tools
🪛 Biome

[error] 2-2: expected , but instead found (

Remove (

(parse)


[error] 2-2: expected , but instead found color

Remove color

(parse)


[error] 2-2: Unexpected value or character.

Expected one of:

(parse)


[error] 2-2: Expected an identifier but instead found '000000'.

Expected an identifier here.

(parse)


[error] 2-2: expected , but instead found important

Remove important

(parse)


[error] 2-2: expected , but instead found ;

Remove ;

(parse)


[error] 2-2: expected , but instead found background-color

Remove background-color

(parse)


[error] 2-2: Unexpected value or character.

Expected one of:

(parse)


[error] 2-2: Expected a compound selector but instead found '!'.

Expected a compound selector here.

(parse)


[error] 2-2: expected , but instead found important

Remove important

(parse)


[error] 2-2: expected , but instead found ;

Remove ;

(parse)


[error] 2-2: expected , but instead found text-shadow

Remove text-shadow

(parse)


[error] 2-2: Unexpected value or character.

Expected one of:

(parse)


[error] 2-2: expected , but instead found px

Remove px

(parse)


[error] 2-2: Expected a compound selector but instead found '0.22'.

Expected a compound selector here.

(parse)


[error] 2-2: expected , but instead found px

Remove px

(parse)


[error] 2-2: Expected a compound selector but instead found '!'.

Expected a compound selector here.

(parse)


[error] 2-2: expected , but instead found important

Remove important

(parse)


[error] 2-2: expected , but instead found ;

Remove ;

(parse)


[error] 4-4: expected , but instead found (

Remove (

(parse)

applications/web-browser/widgets/BetterButton.qml (4)

1-2: Consider updating QtQuick import to a more recent version

While the current imports will work, updating to a more recent version of QtQuick could provide access to newer features and optimizations. Consider updating the import on line 1 to import QtQuick 2.15 or the latest version supported by your Qt installation.


7-15: ContentItem implementation is good, but consider using theme colors

The Text element for the button's content is well-implemented, with proper bindings to the button's properties and appropriate text handling. However, consider replacing the hardcoded color values with theme colors for better maintainability and potential dark mode support.

Replace hardcoded colors with theme colors:

-        color: control.down ? "gray" : "black"
+        color: control.down ? control.palette.mid : control.palette.buttonText

This change will make the button's text color consistent with the application's theme and automatically adjust for different color schemes.


16-25: Background implementation is good, but consider improvements for flexibility

The Rectangle element for the button's background is well-implemented, providing a clean and professional look. However, there are a few suggestions for improvement:

  1. Use theme colors instead of hardcoded values for better maintainability and theme support.
  2. Consider making the dimensions and radius configurable for more flexible use in different contexts.

Here's a suggested refactor:

 background: Rectangle {
     anchors.fill: control
-    implicitWidth: 100
-    implicitHeight: 40
+    implicitWidth: control.implicitWidth
+    implicitHeight: control.implicitHeight
     opacity: enabled ? 1 : 0.3
-    color: "white"
-    border.color: "black"
+    color: control.palette.button
+    border.color: control.palette.buttonText
     border.width: 1
-    radius: 2
+    radius: control.radius
 }

Also, consider adding properties to the main Button element to allow customization:

Button {
    id: control
    property int implicitWidth: 100
    property int implicitHeight: 40
    property int radius: 2
    // ... rest of the button code
}

These changes will make the button more flexible and easier to maintain across different themes and use cases.


1-26: Overall, good implementation with room for improvement

The BetterButton component is well-designed and achieves its goal of creating a custom button with a clean, professional look. The use of custom contentItem and background elements provides precise control over the button's appearance, which is commendable.

However, there are a few areas where the component could be improved:

  1. Theme Integration: Replace hardcoded color values with theme-aware alternatives to ensure consistency across different application themes and color schemes.
  2. Configurability: Add properties to allow easy customization of dimensions, colors, and other visual aspects without modifying the component's internal code.
  3. Accessibility: Consider adding states or properties to enhance accessibility, such as focus indicators or hover effects.
  4. Documentation: Add documentation comments to describe the component's purpose, usage, and any custom properties or behaviors.

To improve the component's reusability and maintainability, consider creating a separate file for common button styles and importing it in this component. This approach would allow for consistent styling across different button types in your application.

Example:

// ButtonStyles.qml
import QtQuick 2.15

QtObject {
    property int defaultWidth: 100
    property int defaultHeight: 40
    property int defaultRadius: 2
    // Add more common style properties here
}

// In BetterButton.qml
import "path/to/ButtonStyles.qml" as ButtonStyle

Button {
    id: control
    implicitWidth: ButtonStyle.defaultWidth
    implicitHeight: ButtonStyle.defaultHeight
    // ... rest of the button code
}

This structure would make it easier to maintain a consistent look across your application's UI components.

applications/web-browser/widgets/CustomMenu.qml (3)

1-2: LGTM! Consider updating QtQuick version.

The import statements are correct for creating a custom menu component. However, you might want to consider using more recent versions of QtQuick and QtQuick.Controls if your project supports them, as they may offer improved performance and additional features.


4-28: Well-structured MenuBar component. Consider dynamic sizing.

The MenuBar component is well-organized and follows QML best practices. Good job on using id for the menuBarItem and providing comprehensive properties for the Text element.

However, consider the following suggestions:

  1. The fixed implicit sizes (40x40) for MenuBarItem and MenuBar backgrounds might not be flexible enough for different screen sizes or text lengths. Consider using Layout.fillWidth or binding sizes to the content.
  2. The color scheme (white text on black background) is hard-coded. Consider using theme colors or making these configurable.

Here's an example of how you might improve the flexibility:

import QtQuick.Layouts 1.3

MenuBar {
    id: menuBar
    Layout.fillWidth: true
    
    delegate: MenuBarItem {
        id: menuBarItem
        contentItem: Text {
            // ... existing properties ...
            color: menuBar.palette.buttonText
        }
        background: Rectangle {
            implicitWidth: contentItem.implicitWidth + 20
            implicitHeight: 40
            color: menuBar.palette.button
        }
    }
    background: Rectangle {
        implicitHeight: 40
        color: menuBar.palette.button
    }
}

This example uses Layout.fillWidth for the MenuBar, dynamic width for MenuBarItems, and palette colors for better theming support.


1-28: Summary: Good start, room for improvement

Overall, you've created a functional custom MenuBar component. The structure is sound and follows QML best practices. To elevate this component further, consider implementing the suggested improvements:

  1. More flexible sizing and theming
  2. Enhanced accessibility features
  3. Internationalization support

These changes will make your component more robust, user-friendly, and easier to maintain as your application grows.

If you'd like assistance implementing any of these suggestions or have any questions, please don't hesitate to ask. I'd be happy to provide more detailed code examples or explanations.

applications/applications.pro (1)

19-19: Summary: Proper integration of web-browser application into the build system

The changes in this file correctly integrate the new web-browser application into the project's build system. The addition to SUBDIRS ensures the application will be built, and the dependency declaration follows the project's existing pattern. These changes are minimal, focused, and align well with the PR objectives.

However, to maintain optimal modularity:

  1. Ensure that the dependency on system-service is indeed necessary for the web-browser application.
  2. Consider adding a brief comment explaining why this dependency is required, if it is confirmed to be necessary.

These steps will help future maintainers understand the project structure better.

Also applies to: 44-44

applications/web-browser/widgets/SwipeArea.qml (2)

1-6: LGTM with a minor suggestion.

The file header with attribution and the import statement look good. It's great to see proper attribution for the code source.

Consider removing the extra empty line (line 3) for consistency.


19-37: onPositionChanged handler is well-implemented.

The handler effectively determines the drag axis and emits the 'move' signal with appropriate coordinates. The logic for deciding the primary axis of movement is sound.

Consider making the threshold value (16 pixels) a configurable property of the component. This would allow for easier customization without modifying the core logic. For example:

property int dragThreshold: 16

Then use dragThreshold instead of the hardcoded value in the comparisons.

applications/web-browser/web-browser.pro (3)

18-20: Platform-specific configuration looks good.

The conditional linking of the qsgepaper library for the linux-oe-g++ platform is appropriate. This likely provides e-paper display support, which aligns with the project's context.

For improved clarity, consider adding a brief comment explaining the purpose of this platform-specific configuration:

linux-oe-g++ {
    # Link against qsgepaper for e-paper display support
    LIBS += -lqsgepaper
}

30-40: Additional file installations look good.

The installation of the desktop file, icons, and splash screen is well-structured and necessary for proper desktop integration. This setup suggests good attention to user experience details.

To improve maintainability, consider using variables for repeated path components:

OXIDE_ICON_PATH = /opt/usr/share/icons/oxide
OXIDE_APP_PATH = /opt/usr/share/applications

applications.files = ../../assets$${OXIDE_APP_PATH}/codes.eeems.mold.oxide
applications.path = $${OXIDE_APP_PATH}
INSTALLS += applications

icons.files += ../../assets$${OXIDE_ICON_PATH}/48x48/apps/web.png
icons.path = $${OXIDE_ICON_PATH}/48x48/apps
INSTALLS += icons

splash.files += ../../assets$${OXIDE_ICON_PATH}/702x702/splash/web.png
splash.path = $${OXIDE_ICON_PATH}/702x702/splash
INSTALLS += splash

This approach makes it easier to update paths in the future if needed.


42-48: Include paths and header files are well-structured.

The inclusion of shared headers and application-specific headers is well-organized. This structure promotes code reuse and modularity.

To improve organization and readability, consider grouping the headers by their origin:

INCLUDEPATH += ../../shared

HEADERS += \
    controller.h \
    keyboardhandler.h

SHARED_HEADERS += \
    ../../shared/dbussettings.h \
    ../../shared/devicesettings.h \
    ../../shared/eventfilter.h

HEADERS += $${SHARED_HEADERS}

This grouping makes it easier to distinguish between application-specific and shared headers at a glance.

applications/web-browser/widgets/BetterMenu.qml (1)

1-2: Consider updating QtQuick and QtQuick.Controls versions.

The current imports use QtQuick 2.10 and QtQuick.Controls 2.4, which are relatively old versions. If possible, consider updating to newer versions to take advantage of potential improvements and bug fixes.

applications/web-browser/widgets/AppItem.qml (3)

1-16: LGTM! Consider the necessity of clip: true.

The imports and root Item declaration are well-structured. The properties and signals are clearly defined, which is good for maintainability.

Consider if clip: true on line 8 is necessary, as it might affect performance. If the content is not expected to overflow, you can remove this property.


17-48: LGTM! Consider using a scalable border width.

The spacer and icon implementation are well-structured and use relative sizing for responsiveness. The Image properties are set appropriately for performance and aspect ratio preservation.

Consider making the border width scalable to ensure consistent appearance across different screen sizes. You can replace line 29 with:

border.width: Math.max(1, Math.round(root.width * 0.005))

This will set the border width to 0.5% of the root width, with a minimum of 1 pixel.


49-63: LGTM! Consider adding a fallback font.

The Text element is well-implemented with relative sizing and appropriate font properties for responsiveness and readability.

To ensure consistent appearance across devices, consider adding a fallback font. Replace line 55 with:

font.family: "Noto Serif, serif"

This will use "Noto Serif" if available, or fall back to a generic serif font if it's not installed on the device.

applications/screenshot-viewer/controller.h (1)

136-136: LGTM: Consistent macro usage in migrate function.

The migrate function has been updated correctly to use the new ANXIETY_SETTINGS_VERSION macro when setting the version. This change is consistent with the macro renaming and maintains the existing logic.

Consider adding a comment explaining the migration process, especially if more complex migrations are planned for future versions. For example:

// Migrate settings from version 0 to 1
// Future versions should add their migration logic here
settings->setValue("version", ANXIETY_SETTINGS_VERSION);

This would make it easier for future developers to understand and extend the migration process.

applications/web-browser/main.cpp (1)

48-49: Ensure application name consistency

The application name is set to "mold", while the display name is set to "Web Browser". This might cause confusion in logs or user settings.

Consider using a consistent name for both the application name and display name.

 app.setApplicationName("mold");
-app.setApplicationDisplayName("Web Browser");
+app.setApplicationDisplayName("mold");

Or, if "Web Browser" is the intended name:

-app.setApplicationName("mold");
+app.setApplicationName("Web Browser");
 app.setApplicationDisplayName("Web Browser");
applications/web-browser/controller.h (1)

25-25: Add a blank line before public: for better readability

According to the code style guidelines, there should be a blank line before access specifiers to enhance code readability. The static analysis tool also suggests adding a blank line before public:.

Suggested change:

Insert a blank line before line 25:

     QList<QObject*> applications;

+    public:
     Controller(QObject* parent)
🧰 Tools
🪛 GitHub Check: CodeFactor

[notice] 25-25: applications/web-browser/controller.h#L25
"public:" should be preceded by a blank line (whitespace/blank_line)

applications/web-browser/keyboardhandler.h (1)

13-13: Add a blank line before 'public:' for better code readability

According to coding style guidelines, adding a blank line before access specifiers like 'public:' improves readability.

🧰 Tools
🪛 GitHub Check: CodeFactor

[notice] 13-13: applications/web-browser/keyboardhandler.h#L13
"public:" should be preceded by a blank line (whitespace/blank_line)

applications/web-browser/widgets/KeyboardKey.qml (1)

7-21: Simplify modifier text properties using a mapping structure

Defining separate properties for every possible modifier combination can be inefficient and error-prone. This approach may not scale well with the addition of new modifiers or combinations.

Propose using a mapping (e.g., a JavaScript object) to associate modifier combinations with their corresponding texts. This simplifies property management and improves scalability. For example:

property var modifierTexts: ({
    '': text,
    'shift': shifttext,
    'alt': alttext,
    'ctrl': ctrltext,
    'meta': metatext,
    'shiftalt': shiftalttext,
    'shiftctrl': shiftctrltext,
    'shiftmeta': shiftmetatext,
    'altctrl': altctrltext,
    'altmeta': altmetatext,
    'ctrlmeta': ctrlmetatext,
    'shiftaltctrl': shiftaltctrltext,
    'shiftaltmeta': shiftaltmetatext,
    'shiftctrlmeta': shiftctrlmetatext,
    'shiftaltctrlmeta': shiftaltctrlmetatext
})

function getText(){
    var modifiers = [];
    if(keyboard.hasShift) modifiers.push('shift');
    if(keyboard.hasAlt) modifiers.push('alt');
    if(keyboard.hasCtrl) modifiers.push('ctrl');
    if(keyboard.hasMeta) modifiers.push('meta');
    var key = modifiers.join('');
    return modifierTexts[key] || text;
}

This solution centralizes modifier texts, making it easier to add or modify entries without altering the core logic of the getText() function.

applications/web-browser/widgets/Button.qml (2)

50-50: Review the usage of console.log with this

Using this inside console.log within QML may not provide meaningful output, as it refers to the JavaScript execution context. Consider removing this or replacing it with a more relevant identifier to improve the debug messages.

Apply this diff to modify the console.log statements:

-    console.log("click (" + this + ") " +  root.isSelected);
+    console.log("click (Button) " +  root.isSelected);

-    console.log("hold " + this);
+    console.log("hold (Button)");

-    console.log("release (" + this + ")");
+    console.log("release (Button)");

-    console.log("click clear (" + this + ") " +  root.isSelected);
+    console.log("click clear (Button) " +  root.isSelected);

Also applies to: 56-56, 64-64, 108-108


41-42: Remove unused hoverEnabled property or handle hover events

The hoverEnabled property is set to true, but there are no hover event handlers implemented. If hover events are not required, consider removing this property to simplify the code.

Apply this diff to remove hoverEnabled:

        MouseArea {
            anchors.fill: root
-           hoverEnabled: true

Alternatively, implement hover event handlers if hover functionality is intended.

applications/web-browser/main.qml (2)

80-81: Add confirmation dialog before exiting the application

Clicking "Exit" immediately quits the application without confirmation, which might lead to accidental closures.

Consider adding a confirmation prompt to confirm the user's intent before exiting.


104-105: Rename _history to improve code readability

The variable _history is used to manage forward navigation history. The underscore prefix can be confusing regarding its purpose.

Consider renaming _history to forwardHistory for better clarity.

Apply this diff to rename the variable:

 property var history: []
-property var _history: []
+property var forwardHistory: []
 
 function open(url){
     history.push(this.url);
-    _history = [];
+    forwardHistory = [];
     load(url);
 }
 
 function back(){
     if(!history.length){
         return;
     }
     var url = history.pop()
-    _history.push(url);
+    forwardHistory.push(url);
     load(url);
 }
 
 function next(){
     if(!forwardHistory.length){
         return;
     }
     var url = forwardHistory.pop();
     history.push(url);
     load(url);
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 769ab66 and b9c6063.

⛔ Files ignored due to path filters (3)
  • applications/web-browser/font/icomoon.ttf is excluded by !**/*.ttf
  • assets/opt/usr/share/icons/oxide/48x48/apps/web.png is excluded by !**/*.png
  • assets/opt/usr/share/icons/oxide/702x702/splash/web.png is excluded by !**/*.png
📒 Files selected for processing (22)
  • applications/applications.pro (2 hunks)
  • applications/screenshot-viewer/controller.h (3 hunks)
  • applications/web-browser/.gitignore (1 hunks)
  • applications/web-browser/controller.h (1 hunks)
  • applications/web-browser/keyboardhandler.h (1 hunks)
  • applications/web-browser/main.cpp (1 hunks)
  • applications/web-browser/main.qml (1 hunks)
  • applications/web-browser/page.css (1 hunks)
  • applications/web-browser/page.js (1 hunks)
  • applications/web-browser/qml.qrc (1 hunks)
  • applications/web-browser/web-browser.pro (1 hunks)
  • applications/web-browser/widgets/AppItem.qml (1 hunks)
  • applications/web-browser/widgets/BetterButton.qml (1 hunks)
  • applications/web-browser/widgets/BetterMenu.qml (1 hunks)
  • applications/web-browser/widgets/Button.qml (1 hunks)
  • applications/web-browser/widgets/CustomMenu.qml (1 hunks)
  • applications/web-browser/widgets/Keyboard.qml (1 hunks)
  • applications/web-browser/widgets/KeyboardKey.qml (1 hunks)
  • applications/web-browser/widgets/StatusIcon.qml (1 hunks)
  • applications/web-browser/widgets/SwipeArea.qml (1 hunks)
  • assets/opt/usr/share/applications/codes.eeems.mold.oxide (1 hunks)
  • package (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • applications/web-browser/.gitignore
🧰 Additional context used
🪛 GitHub Check: CodeFactor
applications/web-browser/controller.h

[notice] 25-25: applications/web-browser/controller.h#L25
"public:" should be preceded by a blank line (whitespace/blank_line)

applications/web-browser/keyboardhandler.h

[notice] 13-13: applications/web-browser/keyboardhandler.h#L13
"public:" should be preceded by a blank line (whitespace/blank_line)

applications/web-browser/page.js

[notice] 213-213: applications/web-browser/page.js#L213
'i' is assigned a value but never used. (no-unused-vars)


[warning] 202-202: applications/web-browser/page.js#L202
Unnecessary escape character: /. (no-useless-escape)


[notice] 1-1: applications/web-browser/page.js#L1
'replace_all_rel_by_abs' is defined but never used. (no-unused-vars)


[warning] 214-214: applications/web-browser/page.js#L214
Unnecessary escape character: /. (no-useless-escape)


[warning] 202-202: applications/web-browser/page.js#L202
Unnecessary escape character: /. (no-useless-escape)


[warning] 202-202: applications/web-browser/page.js#L202
Unnecessary escape character: :. (no-useless-escape)


[warning] 214-214: applications/web-browser/page.js#L214
Empty block statement. (no-empty)

🪛 Biome
applications/web-browser/page.css

[error] 2-2: expected , but instead found (

Remove (

(parse)


[error] 2-2: expected , but instead found color

Remove color

(parse)


[error] 2-2: Unexpected value or character.

Expected one of:

(parse)


[error] 2-2: Expected an identifier but instead found '000000'.

Expected an identifier here.

(parse)


[error] 2-2: expected , but instead found important

Remove important

(parse)


[error] 2-2: expected , but instead found ;

Remove ;

(parse)


[error] 2-2: expected , but instead found background-color

Remove background-color

(parse)


[error] 2-2: Unexpected value or character.

Expected one of:

(parse)


[error] 2-2: Expected a compound selector but instead found '!'.

Expected a compound selector here.

(parse)


[error] 2-2: expected , but instead found important

Remove important

(parse)


[error] 2-2: expected , but instead found ;

Remove ;

(parse)


[error] 2-2: expected , but instead found text-shadow

Remove text-shadow

(parse)


[error] 2-2: Unexpected value or character.

Expected one of:

(parse)


[error] 2-2: expected , but instead found px

Remove px

(parse)


[error] 2-2: Expected a compound selector but instead found '0.22'.

Expected a compound selector here.

(parse)


[error] 2-2: expected , but instead found px

Remove px

(parse)


[error] 2-2: Expected a compound selector but instead found '!'.

Expected a compound selector here.

(parse)


[error] 2-2: expected , but instead found important

Remove important

(parse)


[error] 2-2: expected , but instead found ;

Remove ;

(parse)


[error] 4-4: expected , but instead found (

Remove (

(parse)

applications/web-browser/page.js

[error] 43-43: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 203-203: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 214-214: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 111-111: Shouldn't redeclare 'handleAttr'. Consider to delete it or rename it.

'handleAttr' is defined here:

(lint/suspicious/noRedeclare)

🔇 Additional comments (28)
assets/opt/usr/share/applications/codes.eeems.mold.oxide (5)

2-3: LGTM: Appropriate display name and description.

The displayName and description properties accurately represent the application's purpose as a web browser, aligning with the PR objectives.


7-7: Confirm if empty flags array is intentional.

The flags property is currently an empty array. Please confirm if this is intentional or if there are any flags that should be added for the web browser application.


8-8: LGTM: Appropriate application type.

The type property is set to "foreground", which is suitable for a web browser application that requires user interaction.


5-6: Verify icon and splash resources.

The icon and splash properties use what appears to be a custom resource naming scheme (oxide:). Please ensure that these resources exist or will be created as part of this PR.

Additionally, consider documenting the naming convention for these resources if it's not already documented elsewhere in the project.

Run the following script to search for any documentation or usage of this naming scheme:

#!/bin/bash
# Description: Search for documentation or usage of the oxide: resource naming scheme

# Test: Search for documentation or usage of the oxide: scheme
rg --type-add 'docs:*.{md,txt}' --type docs 'oxide:' -C 3
rg --type python 'oxide:' -C 3

9-9: Consider adding necessary permissions.

The permissions property is currently an empty array. For a web browser application, you might need to specify certain permissions. Consider adding the following common permissions for a web browser:

  1. Network access
  2. File system access (for downloads)
  3. Camera and microphone access (for web conferencing features)

Please verify if these permissions are necessary and if they should be specified in this configuration file or if they are handled elsewhere in the system.

Run the following script to search for any documentation or usage of permissions in the project:

#!/bin/bash
# Description: Search for documentation or usage of permissions in the project

# Test: Search for documentation or usage of permissions
rg --type-add 'docs:*.{md,txt}' --type docs 'permissions?' -C 3
rg --type python 'permissions?' -C 3
applications/web-browser/qml.qrc (2)

1-2: LGTM: Correct QRC file structure.

The overall structure of the QRC file is correct. It properly defines the root element and a single element with the "/" prefix, which is a common practice for Qt applications.

Also applies to: 16-17


3-15: Verify usage of all included resources.

The included resources seem appropriate for a web browser application. However, it's important to ensure that all listed resources are actually used in the application to avoid bloating the resource file.

Please run the following script to check for the usage of these resources in the QML files:

This script will search for the usage of each resource in the QML files of the web-browser application. Review the output to ensure all resources are being utilized.

✅ Verification successful

All included resources are used in the application.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for the usage of resources in QML files

# Function to check resource usage
check_resource() {
    resource=$1
    echo "Checking usage of $resource"
    rg --type qml -i "$resource" applications/web-browser
}

# Check each resource
resources=(
    "AppItem" "CustomMenu" "BetterMenu" "icomoon.ttf" "StatusIcon"
    "BetterButton" "page.css" "page.js" "SwipeArea" "Button"
    "KeyboardKey" "Keyboard"
)

for resource in "${resources[@]}"; do
    check_resource "$resource"
done

Length of output: 31754

applications/web-browser/widgets/BetterButton.qml (1)

4-6: Main Button element looks good

The main Button element is well-defined. Using id: control is a good practice for self-referencing, and setting flat: true appropriately prepares the button for custom styling.

applications/applications.pro (2)

19-19: LGTM: Addition of 'web-browser' to SUBDIRS

The addition of 'web-browser' to the SUBDIRS list is correct and aligns with the PR objective of adding a web browser application. The alphabetical order of the list is maintained, which is good for readability and maintenance.


44-44: LGTM: Addition of 'web-browser' dependency, but verify necessity

The addition of the dependency "web-browser.depends = system-service" is syntactically correct and consistent with the structure of other applications in the project. However, it's important to ensure that this dependency is actually necessary for the web browser application.

Please verify that the web browser application indeed requires functionality from the system service. If it doesn't, consider removing this dependency to keep the application more modular.

To help verify this, you can run the following script to check for any direct usage of system-service in the web-browser code:

applications/web-browser/widgets/SwipeArea.qml (2)

13-17: onPressed handler looks good.

The onPressed event handler correctly initializes the drag axis and sets the origin point for the swipe gesture. Accepting the mouse event is a good practice for controlling event propagation.


1-53: Overall, the SwipeArea implementation looks good and aligns with the PR objectives.

This custom SwipeArea component provides a solid foundation for handling swipe gestures in the web browser application. It effectively detects and differentiates between horizontal and vertical swipes, which can be useful for navigation or other interactive features in the browser.

The implementation aligns well with the PR objective of creating a simple web browser application. By providing this gesture handling capability, it enhances the user interaction possibilities, potentially allowing for features like swiping to navigate back/forward or to switch between tabs.

To further improve the component:

  1. Address the unused 'ready' property.
  2. Make the drag threshold configurable.
  3. Resolve the undefined 'canceled' function issue.

These improvements will make the component more robust and flexible for use in the web browser application.

applications/web-browser/web-browser.pro (3)

50-51: QML resource inclusion is appropriate.

The addition of the qml.qrc resource file is consistent with the use of Qt Quick for the user interface. This is a standard approach for including QML and other resources in a Qt application.


53-55: Additional .pri files are included appropriately.

The inclusion of epaper.pri, liboxide.pri, and sentry.pri suggests a well-organized project structure with shared configurations. This approach promotes consistency across different parts of the project.

To ensure full understanding of the project structure, could you provide brief descriptions of the contents and purposes of these .pri files? Specifically:

  1. What e-paper specific configurations are in epaper.pri?
  2. What shared library configurations does liboxide.pri contain?
  3. How is Sentry configured in sentry.pri, and is it appropriately set up for both development and production environments?

This information will help in assessing the overall project setup and ensuring that all necessary configurations are properly included.


22-28: 🛠️ Refactor suggestion

Reconsider target name and verify installation path.

The configuration for source files and target is mostly standard, but there are two points to consider:

  1. The target name "mold" doesn't reflect the web browser nature of the application. Consider a more descriptive name like "oxide-browser" or "remarkable-browser".

  2. The installation path /opt/bin is non-standard for most Linux distributions. While this might be specific to your target system, it's worth verifying if this is the intended location.

Consider updating the target name:

TARGET = oxide-browser  # or another descriptive name

Please confirm if /opt/bin is the correct installation path for your target system. If it's a custom location, consider adding a comment explaining why this non-standard path is used.

applications/web-browser/widgets/BetterMenu.qml (2)

4-62: Well-structured Menu component.

The overall structure of the Menu component is well-designed. The use of a custom MenuItem delegate with separate child components for arrow, indicator, contentItem, and background allows for fine-grained control over the appearance and behavior of each menu item. This approach follows good QML practices.


1-62: Overall assessment: Good foundation with room for improvement

The BetterMenu.qml file provides a solid foundation for a custom Menu component. The overall structure and approach to customizing the MenuItem delegate are commendable. However, there are several areas where the implementation could be improved:

  1. Theming: Replace hard-coded colors with theme-aware alternatives.
  2. Configurability: Make sizes, colors, and other properties more configurable.
  3. Component usage: Consider using existing QtQuick.Controls components where appropriate.
  4. Visual feedback: Enhance state-based visual feedback for menu items.
  5. Accessibility: Implement accessibility features for better usability.
  6. Performance: Consider optimizations, especially for the arrow drawing.

Addressing these points will result in a more robust, flexible, and user-friendly Menu component. Despite these suggestions for improvement, the current implementation is a good starting point and demonstrates a solid understanding of QML component creation.

applications/web-browser/widgets/AppItem.qml (2)

64-76: LGTM! MouseArea implementation is comprehensive.

The MouseArea is well-implemented, covering all necessary user interactions and properly managing the component's state. The use of propagateComposedEvents: true is a good practice for complex layouts.


1-97: Overall, well-implemented component with room for minor improvements.

The AppItem component is generally well-structured and implements the required functionality effectively. Key strengths include:

  • Good use of relative sizing for responsiveness
  • Proper handling of user interactions
  • Asynchronous image loading for performance

Areas for improvement:

  1. Scalable border width for the icon
  2. Fallback font for text
  3. Defining property changes in states
  4. Smoother transitions with relative sizing

Addressing these points will enhance the component's scalability, performance, and user experience across different devices.

applications/screenshot-viewer/controller.h (2)

14-14: Macro renamed: Please clarify the reasoning.

The change from CORRUPT_SETTINGS_VERSION to ANXIETY_SETTINGS_VERSION has been implemented correctly. However, the choice of "ANXIETY" as a replacement for "CORRUPT" is unusual and might benefit from an explanation.

Could you provide some context for this naming change? It might be helpful to add a comment explaining the rationale behind using "ANXIETY" in the settings version macro.


58-58: LGTM: Consistent macro usage in version check.

The version check has been updated correctly to use the new ANXIETY_SETTINGS_VERSION macro. This change is consistent with the macro renaming and maintains the existing logic.

package (3)

Line range hint 1-196: Review other changes in the oxide() function.

While not directly related to the web browser addition, there are some changes in the oxide() function that should be noted:

  1. The conflicts and replaces lists now include decay and corrupt. This seems appropriate as these are likely components being integrated into the main oxide package.

  2. The configure() function now prompts the user to switch to oxide as the launcher if it's not currently set. This improves user experience by guiding them to use the new launcher.

  3. The preremove() function now ensures that if oxide is active or enabled, it switches to xochitl as the launcher during removal. This prevents leaving the system without a launcher when removing oxide.

These changes appear to enhance the package management logic and improve the user experience. They seem appropriate given the context of the PR.


Line range hint 1-196: Summary of review and next steps

The changes in this file successfully implement the addition of the mold web browser to the Oxide project, aligning with the PR objectives. The installation process for the web browser follows the established pattern for other applications in the script.

Additionally, the updates to the oxide() function enhance the package management logic and improve the user experience, which is commendable.

To complete this review:

  1. Please address the clarifications requested regarding the mold web browser implementation, specifically about its source, dependencies, and icon naming.
  2. Run the verification script provided to ensure the mold executable is properly included in the build process.
  3. Consider adding a brief description or comment about the mold web browser in the oxide-extra() function, similar to the comments for other applications.

Once these points are addressed, the changes can be approved for merging.


97-100: Web browser installation looks good, but needs clarification.

The addition of the mold web browser aligns with the PR objectives. However, please clarify the following points:

  1. What is the source of the mold executable? Is it built during the build() function or provided externally?
  2. Are there any specific dependencies required for the web browser that should be added to the installdepends array?
  3. Consider using a more specific name for the icon file (e.g., "mold.png" instead of "web.png") to avoid potential conflicts with other web-related applications.

To ensure the mold executable is properly built or included, please run the following script:

applications/web-browser/widgets/Button.qml (1)

54-58: Verify the availability of onPressAndHold in MouseArea

The onPressAndHold handler is used, but pressAndHoldInterval is not specified. Ensure that onPressAndHold is supported in QtQuick 2.9 and consider setting pressAndHoldInterval if needed.

Run the following script to check for pressAndHoldInterval usage in the codebase:

applications/web-browser/main.qml (2)

6-6: Ensure page.js is available and correctly implemented

The file imports page.js as JS, but the implementation details are not provided.

Verify that page.js exists and includes the replace_all_rel_by_abs function used in the load(url) function.

Would you like me to check for the existence of page.js in the codebase?


16-16: Verify the availability and licensing of /font/icomoon.ttf

The FontLoader is importing a font from /font/icomoon.ttf, but the file's existence and licensing are not confirmed.

Ensure that icomoon.ttf is present at the specified location and that its usage complies with the font's licensing terms.

Run the following script to check for the font file:

applications/web-browser/page.js (1)

1-1: Verify usage of 'replace_all_rel_by_abs' function

The function replace_all_rel_by_abs is defined but not used within this file.

Please confirm if this function is used elsewhere in the codebase or if it needs to be exported. If it's not needed, consider removing it to keep the code clean.

🧰 Tools
🪛 GitHub Check: CodeFactor

[notice] 1-1: applications/web-browser/page.js#L1
'replace_all_rel_by_abs' is defined but never used. (no-unused-vars)

Image {
id: icon
source: parent.source
height: parent.height - 10
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure non-negative height for the image.

The current height calculation (parent.height - 10) could result in a negative value if the parent's height is less than 10. Consider using Math.max() to ensure a non-negative height:

height: Math.max(parent.height - 10, 0)

This change will prevent potential rendering issues when the parent component is very small.

applications/web-browser/qml.qrc Show resolved Hide resolved
Comment on lines +9 to +10
/* Force grayscale */
img:style(filter:grayscale(100%) !important;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix CSS syntax for image grayscale filter.

The CSS rule for applying a grayscale filter to images has syntax errors. Here's how to fix and improve it:

  1. Replace :style( with {.
  2. Add a closing } at the end of the rule.
  3. Consider removing the !important flag unless it's absolutely necessary.
  4. Add missing semicolon after the property.

Apply this diff to fix the syntax and improve the rule:

-img:style(filter:grayscale(100%) !important;
+img {
+  filter: grayscale(100%);
+}

This correction ensures that the grayscale filter is properly applied to all images. However, consider the following:

  1. Applying a grayscale filter to all images might not be desirable for all use cases. Make sure this is the intended behavior.
  2. The use of !important here might be unnecessary and could make it difficult to override this style if needed in the future.

Consider adding a class (e.g., .grayscale) instead of applying this filter to all images. This would allow more flexibility in your design:

.grayscale {
  filter: grayscale(100%);
}

This approach would let you apply the grayscale effect selectively to images that need it, rather than forcing it on all images.

Comment on lines +5 to +6
/* Visited links */
a:visited,a:active(color:#808080 !important; background-color:#ffffff !important;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix CSS syntax for visited and active links.

The CSS rule for visited and active links has several syntax errors. Here's how to fix and improve it:

  1. Separate :visited and :active selectors with a comma.
  2. Use curly braces {} instead of parentheses.
  3. Remove !important flags unless absolutely necessary.

Apply this diff to fix the syntax and improve the rule:

-a:visited,a:active(color:#808080 !important; background-color:#ffffff !important;
+a:visited, a:active {
+  color: #808080;
+  background-color: #ffffff;
+}

This correction ensures that both visited and active links will have the specified styles. Consider if the !important flags are really necessary, as their overuse can lead to maintainability issues.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/* Visited links */
a:visited,a:active(color:#808080 !important; background-color:#ffffff !important;
/* Visited links */
a:visited, a:active {
color: #808080;
background-color: #ffffff;
}

applications/web-browser/page.js Show resolved Hide resolved
applications/web-browser/page.js Show resolved Hide resolved
Row {
spacing: parent.spacing
anchors.horizontalCenter: parent.horizontalCenter
KeyboardKey { id: caps; text: "Caps"; key: Qt.Key_CapsLock; size: 2; onClick: root.caps(this.state()); toggle: true }
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Incorrect usage of this.state() in onClick handlers

In the onClick handlers for toggle keys, this.state() may not correctly retrieve the toggle state. Consider using this.checked instead, which reflects the current toggle state of the key.

Apply this diff to correct the onClick handlers:

 // Example for the Caps Lock key
-KeyboardKey { id: caps; text: "Caps"; key: Qt.Key_CapsLock; size: 2; onClick: root.caps(this.state()); toggle: true }
+KeyboardKey { id: caps; text: "Caps"; key: Qt.Key_CapsLock; size: 2; onClick: root.caps(this.checked); toggle: true }

Repeat this change for all similar instances:

  • Lines 97: caps key
  • Lines 114 and 125: lshift and rshift keys
  • Lines 130 and 137: lctrl and rctrl keys
  • Lines 131 and 135: lmeta and rmeta keys
  • Lines 132 and 134: lalt and ralt keys

Also applies to: 114-114, 125-125, 130-132, 134-135, 137-137

Comment on lines +38 to +39
root.haCtrl = state;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Typo in property assignment: 'haCtrl' should be 'hasCtrl'

In the ctrl function, root.haCtrl should be corrected to root.hasCtrl to match the property declared on line 16.

Apply this diff to fix the typo:

 function ctrl(state){
-    root.haCtrl = state;
+    root.hasCtrl = state;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
root.haCtrl = state;
}
root.hasCtrl = state;
}

Comment on lines +273 to +279
page++;
if(page < 0){
page = 1;
}else if(page > 1){
page = 0;
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify the page toggling logic

The logic for toggling the page property can be simplified using the modulo operator, enhancing readability and maintainability.

Apply this diff to simplify the toggle logic:

 onClick: {
-    page++;
-    if(page < 0){
-        page = 1;
-    } else if(page > 1){
-        page = 0;
-    }
+    page = (page + 1) % 2;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
page++;
if(page < 0){
page = 1;
}else if(page > 1){
page = 0;
}
}
page = (page + 1) % 2;
}

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (1)
applications/web-browser/keyboardhandler.h (1)

11-15: Minor style improvement and acknowledgment of design choice.

The class declaration looks good overall. Two minor points:

  1. Consider adding a blank line before the public: access specifier for better readability.
  2. The root member is not initialized in the constructor. This is intentional as per previous discussions, but ensure it's set appropriately before use.
 class KeyboardHandler : public QObject {
     Q_OBJECT
+
 public:
     explicit KeyboardHandler(QObject *parent = nullptr) : QObject(parent) {}
    QQuickItem* root;
🧰 Tools
🪛 GitHub Check: CodeFactor

[notice] 13-13: applications/web-browser/keyboardhandler.h#L13
"public:" should be preceded by a blank line (whitespace/blank_line)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b9c6063 and 0339324.

📒 Files selected for processing (3)
  • applications/web-browser/keyboardhandler.h (1 hunks)
  • applications/web-browser/main.cpp (1 hunks)
  • applications/web-browser/widgets/Button.qml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • applications/web-browser/widgets/Button.qml
🧰 Additional context used
📓 Learnings (1)
applications/web-browser/main.cpp (5)
Learnt from: Eeems
PR: Eeems-Org/oxide#189
File: applications/web-browser/main.cpp:51-51
Timestamp: 2024-10-03T06:15:35.435Z
Learning: In the `main` function, it's acceptable to create objects like `Controller controller(&app);` on the stack, as their lifetime matches the application's duration, making dynamic allocation unnecessary.
Learnt from: Eeems
PR: Eeems-Org/oxide#189
File: applications/web-browser/main.cpp:38-38
Timestamp: 2024-10-03T06:14:17.279Z
Learning: In this project, `deviceSettings` is a macro defined in a different file and is properly initialized before use; it can be used in `main.cpp` without explicit declaration or initialization.
Learnt from: Eeems
PR: Eeems-Org/oxide#189
File: applications/web-browser/main.cpp:25-28
Timestamp: 2024-10-03T06:12:15.034Z
Learning: In this Qt application, using `qApp->quit()` in the signal handler ensures the normal shutdown sequence and avoids exiting with a non-zero return value, which would be interpreted as a crash and could lead to undefined behavior.
Learnt from: Eeems
PR: Eeems-Org/oxide#189
File: applications/web-browser/main.cpp:20-21
Timestamp: 2024-10-03T06:13:21.478Z
Learning: In `applications/web-browser/main.cpp`, the user prefers to retain global `using namespace` declarations.
Learnt from: Eeems
PR: Eeems-Org/oxide#189
File: applications/web-browser/main.cpp:31-33
Timestamp: 2024-10-03T06:13:03.475Z
Learning: In this application, version mismatches between the runtime and build versions of Qt are logged for debugging purposes and do not require the application to terminate.
🪛 GitHub Check: CodeFactor
applications/web-browser/keyboardhandler.h

[notice] 13-13: applications/web-browser/keyboardhandler.h#L13
"public:" should be preceded by a blank line (whitespace/blank_line)

🔇 Additional comments (11)
applications/web-browser/main.cpp (8)

1-19: Includes look good

The necessary headers for Qt, C++, and Oxide libraries are properly included. The ARM-specific include is correctly guarded with #ifdef __arm__.


25-28: Signal handler implementation is correct

The signal handler properly resets the signal to its default behavior and uses qApp->quit() to ensure a clean shutdown of the Qt application.


30-41: Main function initialization looks good

The version mismatch check provides useful debugging information. The ARM-specific environment setup for the epaper display is correctly implemented.


42-51: Application setup is well-structured

The KeyboardHandler type is correctly registered for QML use. The QGuiApplication is properly configured with organizational and application-specific properties. The EventFilter is correctly created and installed.


52-60: QML engine setup is correct

The QQmlApplicationEngine is properly created and configured. Root context properties are set correctly, and the main QML file is loaded. The check for empty root objects provides appropriate error handling.


61-69: Root object and keyboard handler setup is well-implemented

The root object is correctly retrieved and set for both the filter and controller. The KeyboardHandler is properly located and configured. Appropriate error handling is in place for a missing keyboard handler. The use of qobject_cast ensures type-safe casting.


71-75: Signal setup and application execution are correct

Signal handlers for SIGINT and SIGTERM are properly set up to ensure clean application shutdown. The application correctly enters its main event loop with app.exec().


1-75: Overall, the implementation is well-structured and follows Qt best practices

The main.cpp file successfully sets up a Qt-based web browser application. It includes proper initialization, signal handling, QML integration, and error management. The code is clean, readable, and adheres to Qt conventions.

applications/web-browser/keyboardhandler.h (3)

1-10: LGTM: Proper include guards and necessary headers.

The file header and includes are well-structured. The include guards are correctly implemented, and all necessary Qt headers are included for the functionality of the KeyboardHandler class.


79-87: LGTM: Efficient implementation of focusObjects method.

The focusObjects method is well-implemented:

  1. It efficiently finds all child QQuickItems with active focus.
  2. The use of root without a null check is intentional, as per previous discussions. Ensure that root is always set before this method is called.

The method's logic for identifying and returning focused items is correct and concise.


88-90: LGTM: Proper file ending.

The file ending is correct:

  1. The class definition is properly closed.
  2. The include guard is correctly terminated.

This follows good C++ header file practices.

Comment on lines +16 to +34
Q_INVOKABLE void charPress(const QChar &character, const Qt::KeyboardModifiers &modifier){
if(character != '\x0'){
int key = character.unicode();
auto targets = focusObjects();
if(targets.empty()){
qDebug() << "No target";
return;
}
qDebug() << targets;
for(auto target : targets){
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, modifier, QString(character));
QCoreApplication::postEvent(target, event);
}
qDebug() << "Char pressed: " << QKeySequence(key + modifier).toString();
}else{
qDebug() << "Invalid char";
keyPress(Qt::Key_unknown, modifier, QString());
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use bitwise OR for combining key and modifier.

The charPress method looks good overall, but there's one improvement to make:

On line 29, use bitwise OR (|) instead of addition (+) to combine key and modifier:

-qDebug() << "Char pressed: " << QKeySequence(key + modifier).toString();
+qDebug() << "Char pressed: " << QKeySequence(key | modifier).toString();

This ensures correct combination of key and modifier flags.

The rest of the method's logic for handling character input and null characters is well-implemented.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Q_INVOKABLE void charPress(const QChar &character, const Qt::KeyboardModifiers &modifier){
if(character != '\x0'){
int key = character.unicode();
auto targets = focusObjects();
if(targets.empty()){
qDebug() << "No target";
return;
}
qDebug() << targets;
for(auto target : targets){
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, modifier, QString(character));
QCoreApplication::postEvent(target, event);
}
qDebug() << "Char pressed: " << QKeySequence(key + modifier).toString();
}else{
qDebug() << "Invalid char";
keyPress(Qt::Key_unknown, modifier, QString());
}
}
Q_INVOKABLE void charPress(const QChar &character, const Qt::KeyboardModifiers &modifier){
if(character != '\x0'){
int key = character.unicode();
auto targets = focusObjects();
if(targets.empty()){
qDebug() << "No target";
return;
}
qDebug() << targets;
for(auto target : targets){
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, modifier, QString(character));
QCoreApplication::postEvent(target, event);
}
qDebug() << "Char pressed: " << QKeySequence(key | modifier).toString();
}else{
qDebug() << "Invalid char";
keyPress(Qt::Key_unknown, modifier, QString());
}
}

Comment on lines +35 to +60
Q_INVOKABLE void keyPress(const Qt::Key &key, const Qt::KeyboardModifiers &modifier, const QString &text){
auto targets = focusObjects();
if(targets.empty()){
qDebug() << "No target";
return;
}
qDebug() << targets;
for(auto target : targets){
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, modifier, text);
QCoreApplication::postEvent(target, event);
}
QKeySequence sequence;
switch(key){
case Qt::Key_Shift:
case Qt::Key_Alt:
case Qt::Key_AltGr:
case Qt::Key_Control:
case Qt::Key_Meta:
sequence = QKeySequence(modifier);
break;
default:
sequence = QKeySequence(key + modifier);
break;
}
qDebug() << "Key pressed: " << sequence.toString() << " text: " << text;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use bitwise OR for combining key and modifier in default case.

The keyPress method is well-implemented, but there's one improvement to make:

In the switch statement's default case (line 56), use bitwise OR (|) instead of addition (+) to combine key and modifier:

-                sequence = QKeySequence(key + modifier);
+                sequence = QKeySequence(key | modifier);

This ensures correct combination of key and modifier flags.

The rest of the method, including the separate handling of modifier keys, is well-structured and logically sound.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Q_INVOKABLE void keyPress(const Qt::Key &key, const Qt::KeyboardModifiers &modifier, const QString &text){
auto targets = focusObjects();
if(targets.empty()){
qDebug() << "No target";
return;
}
qDebug() << targets;
for(auto target : targets){
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, modifier, text);
QCoreApplication::postEvent(target, event);
}
QKeySequence sequence;
switch(key){
case Qt::Key_Shift:
case Qt::Key_Alt:
case Qt::Key_AltGr:
case Qt::Key_Control:
case Qt::Key_Meta:
sequence = QKeySequence(modifier);
break;
default:
sequence = QKeySequence(key + modifier);
break;
}
qDebug() << "Key pressed: " << sequence.toString() << " text: " << text;
}
Q_INVOKABLE void keyPress(const Qt::Key &key, const Qt::KeyboardModifiers &modifier, const QString &text){
auto targets = focusObjects();
if(targets.empty()){
qDebug() << "No target";
return;
}
qDebug() << targets;
for(auto target : targets){
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, modifier, text);
QCoreApplication::postEvent(target, event);
}
QKeySequence sequence;
switch(key){
case Qt::Key_Shift:
case Qt::Key_Alt:
case Qt::Key_AltGr:
case Qt::Key_Control:
case Qt::Key_Meta:
sequence = QKeySequence(modifier);
break;
default:
sequence = QKeySequence(key | modifier);
break;
}
qDebug() << "Key pressed: " << sequence.toString() << " text: " << text;
}

Comment on lines +61 to +78
Q_INVOKABLE void stringPress(const QString &text, const Qt::KeyboardModifiers &modifier){
auto targets = focusObjects();
if(targets.empty()){
qDebug() << "No target";
return;
}
qDebug() << targets;
for(auto target : targets){
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, Qt::Key_unknown, modifier, text);
QCoreApplication::postEvent(target, event);
QVariant readOnly = target->property("readOnly");
QVariant length = target->property("length");
if(target->property("text").isValid() && length.isValid() && readOnly.isValid() && !readOnly.toBool()){
QMetaObject::invokeMethod(target, "insert", Q_ARG(int, length.toInt()), Q_ARG(QString, text));
}
}
qDebug() << "String pressed: " << QKeySequence(text + modifier).toString();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct invalid addition of QString and Qt::KeyboardModifiers in debug output.

The stringPress method is well-implemented, but there's an issue in the debug output:

On line 77, the addition of text (QString) and modifier (Qt::KeyboardModifiers) is invalid and won't compile. Consider modifying the debug output:

-qDebug() << "String pressed: " << QKeySequence(text + modifier).toString();
+qDebug() << "String pressed: " << text << " modifiers: " << QKeySequence(modifier).toString();

The rest of the method, including the check for editable targets and the text insertion logic, is well-structured and correct.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Q_INVOKABLE void stringPress(const QString &text, const Qt::KeyboardModifiers &modifier){
auto targets = focusObjects();
if(targets.empty()){
qDebug() << "No target";
return;
}
qDebug() << targets;
for(auto target : targets){
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, Qt::Key_unknown, modifier, text);
QCoreApplication::postEvent(target, event);
QVariant readOnly = target->property("readOnly");
QVariant length = target->property("length");
if(target->property("text").isValid() && length.isValid() && readOnly.isValid() && !readOnly.toBool()){
QMetaObject::invokeMethod(target, "insert", Q_ARG(int, length.toInt()), Q_ARG(QString, text));
}
}
qDebug() << "String pressed: " << QKeySequence(text + modifier).toString();
}
Q_INVOKABLE void stringPress(const QString &text, const Qt::KeyboardModifiers &modifier){
auto targets = focusObjects();
if(targets.empty()){
qDebug() << "No target";
return;
}
qDebug() << targets;
for(auto target : targets){
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, Qt::Key_unknown, modifier, text);
QCoreApplication::postEvent(target, event);
QVariant readOnly = target->property("readOnly");
QVariant length = target->property("length");
if(target->property("text").isValid() && length.isValid() && readOnly.isValid() && !readOnly.toBool()){
QMetaObject::invokeMethod(target, "insert", Q_ARG(int, length.toInt()), Q_ARG(QString, text));
}
}
qDebug() << "String pressed: " << text << " modifiers: " << QKeySequence(modifier).toString();
}

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.

Web browser application
1 participant