diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 21187c3b4b6..4baa0149582 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -13,7 +13,7 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref || github.run_id }} cancel-in-progress: true - + env: MACOSX_DEPLOYMENT_TARGET: "11.0" @@ -30,7 +30,7 @@ jobs: strategy: matrix: os: [ubuntu-22.04, macos-12, windows-2022] - rust_version: [stable, "1.73"] + rust_version: [stable, "1.77"] include: - os: windows-2022 extra_args: "--exclude ffmpeg --exclude gstreamer-player" @@ -44,8 +44,8 @@ jobs: # rust_version: "nightly" exclude: - os: macos-12 - rust_version: "1.73" - # We already test 1.73 and nightly. Stable is in the middle and already covered by other jobs + rust_version: "1.77" + # We already test 1.77 and nightly. Stable is in the middle and already covered by other jobs - os: ubuntu-22.04 rust_version: "stable" @@ -79,15 +79,13 @@ jobs: with: toolchain: ${{ matrix.rust_version }} key: x-v2 - - name: Pin dependencies to make it build with our MSRV - if: matrix.rust_version == '1.73' - shell: bash - run: | - if [ ! -f ./Cargo.lock ]; then - cargo update -p clap --precise 4.4.18 - cargo update -p rowan --precise 0.15.15 - cargo update -p plotters --precise 0.3.6 - fi + # - name: Pin dependencies to make it build with our MSRV + # if: matrix.rust_version == '1.77' + # shell: bash + # run: | + # if [ ! -f ./Cargo.lock ]; then + # cargo update -p xxx --precise x.y.z + # fi - name: Run tests (not qt) run: DYLD_FRAMEWORK_PATH=$Qt5_DIR/lib cargo test --verbose --all-features --workspace ${{ matrix.extra_args }} --exclude slint-node --exclude pyslint --exclude test-driver-node --exclude slint-node --exclude test-driver-nodejs --exclude test-driver-cpp --exclude mcu-board-support --exclude printerdemo_mcu --exclude uefi-demo --exclude slint-cpp --exclude slint-python -- --skip=_qt::t env: @@ -244,7 +242,7 @@ jobs: matrix: include: - os: macos-12 - rust_version: "1.73" + rust_version: "1.77" - os: windows-2022 rust_version: "nightly" - os: ubuntu-22.04 @@ -326,7 +324,7 @@ jobs: cmakeAppendedArgs: "-DCMAKE_BUILD_TYPE=Release -DSLINT_FEATURE_INTERPRETER=1 -DSLINT_FEATURE_BACKEND_QT=1" buildDirectory: ${{ runner.workspace }}/examples/build buildWithCMakeArgs: "--config Release" - + vsce_build_test: runs-on: ubuntu-22.04 @@ -335,7 +333,7 @@ jobs: - uses: Swatinem/rust-cache@v2 with: key: "vsce_1" # increment this to bust the cache if needed - - uses: ./.github/actions/install-linux-dependencies + - uses: ./.github/actions/install-linux-dependencies - uses: actions/setup-node@v4 with: node-version: 18 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a8962fe347..e7bf15a5673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,25 @@ # Changelog All notable changes to this project are documented in this file. +## 1.9.0 - Unreleased + +### General + + - Minumum Supported Rust Version (MSRC) is 1.77 + - femtovg: Avoid artifacts of texture sampling with accidental wrap-around on texture boundaries + +### Slint language + + - Added animation `direction` property. (#6260) + +### Widgets + + - Checkbox: fix text color in fluent style (#6239) + +### LSP and tooling + + - Bring the window to the front and focus when clicking on "Show preview" in the editor. (#196) + ## 1.8.0 - 2024-09-23 ### Slint language diff --git a/Cargo.toml b/Cargo.toml index f0e1f69c9fa..c7676958e1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ homepage = "https://slint.dev" keywords = ["gui", "toolkit", "graphics", "design", "ui"] license = "GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0" repository = "https://github.com/slint-ui/slint" -rust-version = "1.73" +rust-version = "1.77" version = "1.9.0" [workspace.dependencies] @@ -137,7 +137,7 @@ cfg_aliases = { version = "0.2.0" } clap = { version = "4.0", features = ["derive", "wrap_help"] } clru = { version = "0.6.0" } css-color-parser2 = { version = "1.0.1" } -derive_more = { version = "0.99.17" } +derive_more = { version = "1.0.0", default-features = false, features = ["deref", "deref_mut", "into", "from", "add", "add_assign", "mul", "not", "display"] } euclid = { version = "0.22.1", default-features = false } fontdb = { version = "0.18.0", default-features = false } fontdue = { version = "0.9.0" } diff --git a/api/cpp/CMakeLists.txt b/api/cpp/CMakeLists.txt index 44e35b9617a..14e646180b2 100644 --- a/api/cpp/CMakeLists.txt +++ b/api/cpp/CMakeLists.txt @@ -18,7 +18,7 @@ FetchContent_Declare( FetchContent_MakeAvailable(Corrosion) list(PREPEND CMAKE_MODULE_PATH ${Corrosion_SOURCE_DIR}/cmake) -find_package(Rust 1.73 REQUIRED MODULE) +find_package(Rust 1.77 REQUIRED MODULE) option(BUILD_SHARED_LIBS "Build Slint as shared library" ON) option(SLINT_FEATURE_COMPILER "Enable support for compiling .slint files to C++ ahead of time" ON) diff --git a/api/cpp/docs/cmake.md b/api/cpp/docs/cmake.md index e6bf5b97bf4..74c97b4d282 100644 --- a/api/cpp/docs/cmake.md +++ b/api/cpp/docs/cmake.md @@ -49,7 +49,7 @@ In the next section you will learn how to use the installed library in your appl First you need to install the prerequisites: * Install Rust by following the [Rust Getting Started Guide](https://www.rust-lang.org/learn/get-started). If you already - have Rust installed, make sure that it's at least version 1.73 or newer. You can check which version you have installed + have Rust installed, make sure that it's at least version 1.77 or newer. You can check which version you have installed by running `rustc --version`. Once this is done, you should have the `rustc` compiler and the `cargo` build system installed in your path. You can either choose to compile Slint from source along with your application or include Slint as an external CMake package. diff --git a/api/cpp/docs/mcu/generic.md b/api/cpp/docs/mcu/generic.md index faa17ea0cd5..247655c5b04 100644 --- a/api/cpp/docs/mcu/generic.md +++ b/api/cpp/docs/mcu/generic.md @@ -9,7 +9,7 @@ following generic instructions on what's needed to compile and use Slint. ## Prerequisites * Install Rust by following the [Rust Getting Started Guide](https://www.rust-lang.org/learn/get-started). If you already - have Rust installed, make sure that it's at least version 1.73 or newer. You can check which version you have installed + have Rust installed, make sure that it's at least version 1.77 or newer. You can check which version you have installed by running `rustc --version`. Once this is done, you should have the `rustc` compiler and the `cargo` build system installed in your path. * A C++ cross-compiler compiler that supports C++20. @@ -44,7 +44,7 @@ cmake -DRust_CARGO_TARGET=thumbv7em-none-eabihf -DSLINT_FEATURE_FREESTANDING=ON ``` ## Next Steps - + - Check out the [](../getting_started.md) instructions for a generic "Hello World" with C++. - Study the [](../api/library_root), in particular the `slint::platform` namespace for writing a Slint platform integration to handle touch input and render pixel, which you diff --git a/api/node/README.md b/api/node/README.md index 7f9ec44028f..56b1bec9ed7 100644 --- a/api/node/README.md +++ b/api/node/README.md @@ -33,7 +33,7 @@ You need to install the following components: * **[Node.js](https://nodejs.org/download/release/)** (v16. or newer) * **[npm](https://www.npmjs.com/)** - * **[Rust compiler](https://www.rust-lang.org/tools/install)** (1.73 or newer) + * **[Rust compiler](https://www.rust-lang.org/tools/install)** (1.77 or newer) You will also need a few more dependencies, see diff --git a/api/node/cover.md b/api/node/cover.md index a6ebf79366b..6d839376fb5 100644 --- a/api/node/cover.md +++ b/api/node/cover.md @@ -34,8 +34,7 @@ To use Slint with Deno, ensure the following programs are installed: Slint-node comes with pre-built binaries for macOS, Linux, and Windows. If you'd like to use Slint-node on a system without pre-built binaries, you need to additional software: - * **[Rust compiler](https://www.rust-lang.org/tools/install)** (1.73 or newer) - * Depending on your operating system, you may need additional components. For a list of required system libraries, + * **[Rust compiler](https://www.rust-lang.org/tools/install)** (1.77 or newer) * Depending on your operating system, you may need additional components. For a list of required system libraries, see . ## Getting Started (Node.js) @@ -259,7 +258,7 @@ The types used for properties in .slint design markup each translate to specific [Array properties](../slint/src/language/syntax/types#arrays-and-models) can be set from JavaScript by passing either `Array` objects or implementations of the {@link Model} interface. -When passing a JavaScript `Array` object, the contents of the array are copied. Any changes to the JavaScript afterwards will not be visible on the Slint side. +When passing a JavaScript `Array` object, the contents of the array are copied. Any changes to the JavaScript afterwards will not be visible on the Slint side. Reading a Slint array property from JavaScript will always return a @{link Model}. diff --git a/docs/building.md b/docs/building.md index 1dbe9eb43be..a3d040ccf57 100644 --- a/docs/building.md +++ b/docs/building.md @@ -9,7 +9,7 @@ This page explains how to build and test Slint. ### Installing Rust Install Rust by following the [Rust Getting Started Guide](https://www.rust-lang.org/learn/get-started). If you already -have Rust installed, make sure that it's at least version 1.73 or newer. You can check which version you have installed +have Rust installed, make sure that it's at least version 1.77 or newer. You can check which version you have installed by running `rustc --version`. Once this is done, you should have the `rustc` compiler and the `cargo` build system installed in your path. diff --git a/internal/compiler/generator/rust.rs b/internal/compiler/generator/rust.rs index 1ebb9cada6a..abd1fcf4f87 100644 --- a/internal/compiler/generator/rust.rs +++ b/internal/compiler/generator/rust.rs @@ -2139,10 +2139,9 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream Expression::Array { element_ty: _, values, as_model: _ } => values .iter() .map(|path_elem_expr| - // Close{} is a struct with no fields in markup, and PathElement::Close has no fields, so map to an empty token stream - // and thus later just unit type, which can convert into PathElement::Close. + // Close{} is a struct with no fields in markup, and PathElement::Close has no fields if matches!(path_elem_expr, Expression::Struct { ty: Type::Struct { fields, .. }, .. } if fields.is_empty()) { - ::core::default::Default::default() + quote!(sp::PathElement::Close) } else { compile_expression(path_elem_expr, ctx) } diff --git a/internal/compiler/parser.rs b/internal/compiler/parser.rs index 07dd701f173..9a13a2a79c3 100644 --- a/internal/compiler/parser.rs +++ b/internal/compiler/parser.rs @@ -236,9 +236,8 @@ macro_rules! declare_syntax { pub mod syntax_nodes { use super::*; - use derive_more::*; $( - #[derive(Debug, Clone, Deref, Into)] + #[derive(Debug, Clone, derive_more::Deref, derive_more::Into)] pub struct $nodekind(SyntaxNode); #[cfg(test)] impl SyntaxNodeVerify for $nodekind { diff --git a/internal/compiler/typeloader.rs b/internal/compiler/typeloader.rs index d83b0d16877..3e4e14e2787 100644 --- a/internal/compiler/typeloader.rs +++ b/internal/compiler/typeloader.rs @@ -864,14 +864,12 @@ impl TypeLoader { .await } - // This function could be async when MSRV >= 1.77, but until then, we need to return a Box - fn load_dependencies_recursively_impl<'a: 'b, 'b>( + async fn load_dependencies_recursively_impl<'a: 'b, 'b>( state: &'a RefCell>, doc: &'b syntax_nodes::Document, registry_to_populate: &'b Rc>, import_stack: &'b HashSet, - ) -> core::pin::Pin, Exports)> + 'b>> - { + ) -> (Vec, Exports) { let mut foreign_imports = vec![]; let mut dependencies_futures = vec![]; for mut import in Self::collect_dependencies(state, doc) { @@ -905,84 +903,70 @@ impl TypeLoader { })); } - Box::pin(async move { - let mut reexports = None; - let mut has_star_reexport = false; - std::future::poll_fn(|cx| { - dependencies_futures.retain_mut(|fut| { - let core::task::Poll::Ready((import, doc_path)) = fut.as_mut().poll(cx) else { - return true; - }; - let Some(doc_path) = doc_path else { return false }; - let mut state = state.borrow_mut(); - let state = &mut *state; - let doc = state.tl.all_documents.docs.get(&doc_path).unwrap(); - match &import.import_kind { - ImportKind::ImportList(imported_types) => { - let mut imported_types = - ImportedName::extract_imported_names(imported_types).peekable(); - if imported_types.peek().is_some() { - Self::register_imported_types( - doc, - &import, - imported_types, - registry_to_populate, - state.diag, - ); - } else { - state.diag.push_error("Import names are missing. Please specify which types you would like to import".into(), &import.import_uri_token.parent()); - } + let mut reexports = None; + let mut has_star_reexport = false; + std::future::poll_fn(|cx| { + dependencies_futures.retain_mut(|fut| { + let core::task::Poll::Ready((import, doc_path)) = fut.as_mut().poll(cx) else { return true; }; + let Some(doc_path) = doc_path else { return false }; + let mut state = state.borrow_mut(); + let state = &mut *state; + let doc = state.tl.all_documents.docs.get(&doc_path).unwrap(); + match &import.import_kind { + ImportKind::ImportList(imported_types) => { + let mut imported_types = ImportedName::extract_imported_names(imported_types).peekable(); + if imported_types.peek().is_some() { + Self::register_imported_types(doc, &import, imported_types, registry_to_populate, state.diag); + } else { + state.diag.push_error("Import names are missing. Please specify which types you would like to import".into(), &import.import_uri_token.parent()); } - ImportKind::ModuleReexport(export_module_syntax_node) => { - let exports = reexports.get_or_insert_with(Exports::default); - if let Some(star_reexport) = export_module_syntax_node - .ExportModule() - .and_then(|x| x.child_token(SyntaxKind::Star)) - { - if has_star_reexport { - state.diag.push_error("re-exporting modules is only allowed once per file".into(), &star_reexport); - return false; - } - has_star_reexport = true; - exports.add_reexports( - doc.exports.iter().map(|(exported_name, compo_or_type)| { - let exported_name = ExportedName { - name: exported_name.name.clone(), - name_ident: (**export_module_syntax_node).clone(), - }; - (exported_name, compo_or_type.clone()) - }), - state.diag, - ); - } else if export_module_syntax_node.ExportSpecifier().next().is_none() { - state.diag.push_error("Import names are missing. Please specify which types you would like to re-export".into(), export_module_syntax_node); - } else { - let e = export_module_syntax_node - .ExportSpecifier() - .filter_map(|e| { - let (imported_name, exported_name) = - ExportedName::from_export_specifier(&e); - let Some(r) = doc.exports.find(&imported_name) else { - state.diag.push_error(format!("No exported type called '{imported_name}' found in {doc_path:?}"), &e); - return None; - }; - Some((exported_name, r)) - }) - .collect::>(); - exports.add_reexports(e, state.diag); + } + ImportKind::ModuleReexport(export_module_syntax_node) => { + let exports = reexports.get_or_insert_with(Exports::default); + if let Some(star_reexport) = export_module_syntax_node.ExportModule().and_then(|x| x.child_token(SyntaxKind::Star)) + { + if has_star_reexport { + state.diag.push_error("re-exporting modules is only allowed once per file".into(), &star_reexport); + return false; } + has_star_reexport = true; + exports.add_reexports( + doc.exports.iter().map(|(exported_name, compo_or_type)| { + let exported_name = ExportedName { + name: exported_name.name.clone(), + name_ident: (**export_module_syntax_node).clone(), + }; + (exported_name, compo_or_type.clone()) + }), + state.diag, + ); + } else if export_module_syntax_node.ExportSpecifier().next().is_none() { + state.diag.push_error("Import names are missing. Please specify which types you would like to re-export".into(), export_module_syntax_node); + } else { + let e = export_module_syntax_node + .ExportSpecifier() + .filter_map(|e| { + let (imported_name, exported_name) = ExportedName::from_export_specifier(&e); + let Some(r) = doc.exports.find(&imported_name) else { + state.diag.push_error(format!("No exported type called '{imported_name}' found in {doc_path:?}"), &e); + return None; + }; + Some((exported_name, r)) + }) + .collect::>(); + exports.add_reexports(e, state.diag); } } - false - }); - if dependencies_futures.is_empty() { - core::task::Poll::Ready(()) - } else { - core::task::Poll::Pending } - }).await; - (foreign_imports, reexports.unwrap_or_default()) - }) + false + }); + if dependencies_futures.is_empty() { + core::task::Poll::Ready(()) + } else { + core::task::Poll::Pending + } + }).await; + (foreign_imports, reexports.unwrap_or_default()) } pub async fn import_component(