Skip to content

Sunday, 14 May 2023


When I first started exploring the world of web development, I was immediately drawn to JavaScript. I was inspired by the countless possibilities it offered in terms of building dynamic and interactive websites. The ability to add functionality to a web page and bring it to life was truly fascinating to me.

As I delved deeper into the language, I found myself constantly inspired by the innovative solutions that other developers had created using JavaScript. I became motivated to push myself to learn more, to experiment with new techniques and tools, and to see what I could create with this powerful language.

In short, my motivation to learn JavaScript came from my desire to be part of a community of innovative and creative thinkers who were constantly pushing the boundaries of what was possible in web development. I wanted to be a part of that world, and I knew that learning JavaScript was the first step on that journey.


Currently, I am working on building a simple website using JavaScript. I was inspired to take on this project after realizing the importance of having a strong online presence for businesses and individuals alike. JavaScript is a crucial language for web development, and I wanted to dive deeper into its capabilities by creating a website of my own.

As I started working on the project, I found myself enjoying the process of coding and problem-solving. Each step of the way, I learned something new about JavaScript and its features. I experimented with different functions and event handlers, and it was exciting to see how the website's functionality changed with each addition.

Working on this project has also allowed me to apply my creativity and design skills. I've been able to explore different ways of presenting information and making the website user-friendly. It's been a rewarding experience to see my ideas come to life on the screen.

Overall, this project has been a great learning experience for me. It has solidified my interest in web development and given me the confidence to take on more complex projects in the future.


To complete my project of building a simple website using JavaScript, I followed a few steps. Firstly, I planned the layout of the website and created wireframes to visualize how each page would look like. Then, I wrote the HTML and CSS code to create the basic structure and styling of the website.

Next, I started working on the JavaScript functionality. I added interactive features like a navigation menu, a contact form, and a slider for images. I also included some animations and effects to make the website more engaging.

However, I faced some challenges along the way. One of the main challenges was getting the navigation menu to work properly. Initially, it did not respond to clicks and did not show the correct pages. I had to research and learn more about JavaScript event listeners and DOM manipulation to fix this issue.

Another challenge was getting the contact form to send emails. I had to learn how to use a server-side programming language like PHP to handle the form submission and send an email with the form data.

To overcome these challenges, I spent time researching and learning more about JavaScript, HTML, and CSS. I also reached out to online communities and forums for help and advice.

Overall, the project was a great learning experience, and I am proud of what I was able to accomplish using JavaScript. I gained a deeper understanding of web development and learned new skills that I can apply to future projects.


Reflecting on what I learned from building a simple website using JavaScript, I realized that it is a powerful language that can create dynamic and interactive web pages. Through this project, I learned about various JavaScript functions, including DOM manipulation, event listeners, and object-oriented programming.

One thing I would do differently next time is to plan my project more thoroughly. I faced a few challenges along the way because I didn't have a clear plan before starting. Next time, I would create a detailed plan, including the layout, functionality, and features of the website before starting the coding process.

Overall, building this website has helped me improve my skills and understanding of JavaScript. I am now more confident in my ability to use JavaScript to create interactive and dynamic web pages, and I am excited to continue learning and exploring the possibilities of this language.


In my journey of learning JavaScript and building a website, I found several resources that were helpful in improving my skills. Here are a few that I would like to share:

  1. The Wemakedevs roadmap provides a valuable front-end learning path with numerous excellent resources to learn JavaScript. I highly recommend checking it out.

    WeMakeDevs roadmap for Frontend-Development

  2. Mozilla Developer Network: This website offers a wealth of information on JavaScript and web development. I found their documentation to be comprehensive and easy to understand, and I frequently referred to it while working on my project.

  3. FreeCodeCamp is a great resource for learning JavaScript, offering a wide range of informative videos. Additionally, CodeWithHarry and Akshay Saini have done an excellent job of providing valuable JavaScript knowledge through their YouTube channels

  4. Stack Overflow: This is a popular online community where developers can ask and answer questions related to programming. I found it to be a helpful resource when I encountered coding challenges and needed guidance.

Overall, these resources helped me to develop a strong foundation in JavaScript and improve my skills as a web developer.


As I embarked on my journey to learn JavaScript, I never imagined the exciting adventures that awaited me. It all started when I stumbled upon a simple webpage and wondered how it was made. Intrigued, I began researching and discovered that the page was built using JavaScript, a programming language that I had heard of but knew very little about.

With newfound curiosity, I dove headfirst into learning JavaScript. At first, it was a bit overwhelming. I struggled to understand the syntax and structure of the language. But I was determined to master it, and with each passing day, my confidence grew.

One of the most exciting experiences during my journey was when I built my very first website using JavaScript. It wasn't anything fancy, just a simple webpage with a few interactive features, but it was a proud moment for me nonetheless. I spent countless hours pouring over code, debugging errors, and testing different functionalities. It wasn't always easy, but the feeling of accomplishment when I finally got it right was worth every second.

Throughout my learning journey, I found myself constantly seeking out resources to help me improve my skills. Online tutorials, books, and courses were all instrumental in my success. Some of my favorite resources included FreeCodeCamp's JavaScript videos, CodeWithHarry, and Akshay Saini's YouTube channels. Each provided a unique perspective on the language and helped me better understand its intricacies.

Looking back on my journey, I can confidently say that learning JavaScript has been one of the most rewarding experiences of my life. It has helped me develop new skills, boosted my confidence, and opened doors to exciting opportunities. While there were certainly challenges along the way, I am grateful for each and every one of them. They helped me grow and pushed me to become a better developer.

In the future, I plan to continue honing my JavaScript skills and taking on new challenges. There is always more to learn, and I am excited to see where this journey will take me next.

Introduction to the topics of DevOps, MLOps, GitOps, and Open Source, was discussed at wemakedevs delhi meetup:

DevOps: DevOps is a set of practices that combine software development (Dev) and IT operations (Ops) to enable faster and more reliable software delivery. DevOps emphasizes collaboration, automation, and continuous improvement, and is widely used in modern software development.

MLOps: MLOps, or machine learning operations, is the application of DevOps practices to machine learning workflows. MLOps enables teams to manage and scale machine learning models in a more automated and efficient way, using tools such as containerization, version control, and continuous integration/continuous deployment (CI/CD) pipelines.

GitOps: GitOps is a way of managing infrastructure and application deployments using Git version control. In a GitOps workflow, all changes to infrastructure and application configurations are made through Git commits, which trigger automated deployment pipelines. GitOps enables teams to manage infrastructure and applications in a more scalable, automated, and secure way.

Open Source: Open source software is software that is freely available for use, modification, and distribution by anyone. Open source software is developed and maintained by a community of developers and users, who collaborate to improve the software and ensure its quality and security.

These topics are all highly relevant and important for modern software development and are increasingly being adopted by organizations of all sizes and industries. By staying up-to-date on the latest developments in DevOps, MLOps, GitOps, and Open Source, software developers and organizations can ensure that they are delivering high-quality software that meets the needs of their users and customers


I was drawn to the tech meetup due to my keen interest in topics such as DevOps, MLOps, GitOps, and Open Source. As someone who is always seeking to enhance my skills and knowledge in software development, I was excited to learn from industry experts and my peers in the field. Additionally, I was eager to connect with other developers, engineers, and industry professionals to exchange ideas, share experiences, and build relationships. Being a part of a larger network of like-minded individuals who share my interests and goals was also a key motivation for attending the wemakedevs meetup. Overall, I was hoping to gain insights, best practices, and inspiration that I could apply in my work and personal projects.


The keynote presentation on DevOps by Subhasmita Swain was undoubtedly the highlight of my experience at the wemakedevs tech meetup. Her insights and best practices were highly informative and thought-provoking, and her engaging and entertaining approach made the session more enjoyable. The breakout sessions on MLOps and GitOps were equally impressive, allowing me to learn from other developers and exchange ideas with peers. I was particularly struck by a conversation I had with another attendee about the future of Open Source, which left a lasting impression on me. His perspectives were insightful and inspiring, and I found it fascinating to learn about his experiences working on open source projects. Overall, attending the wemakedevs tech meetup was a unique and valuable opportunity to learn, connect, and grow in the tech industry. I am already looking forward to attending the next one.


After attending Apoorv Goyal insightful and informative session on containerization, I gained a deeper understanding of the technology and its various use cases. Mr. Goyal shared his expertise on the subject matter and provided us with valuable insights and best practices on how to leverage containerization effectively. His presentation was well-structured and easy to follow, and he did an excellent job of breaking down complex concepts into simple, understandable terms.

During the session, I learned about the benefits of containerization, such as increased efficiency, scalability, and portability, and how it is transforming the way modern software is developed and deployed. Mr. Goyal also discussed the various containerization tools and platforms available in the market, and provided practical tips on how to choose the right tool for a particular use case.

Overall, the session was a great learning experience for me, and I left with a newfound appreciation for the power of containerization. Mr. Goyal's expertise and engaging teaching style made the session both informative and enjoyable, and I'm excited to apply the knowledge and best practices I learned to my work in the future.


When reflecting on my experience attending the wemakedevs tech meetup, I can confidently say that it exceeded my expectations. I learned so much from the keynote presentation on DevOps by Subhasmita Swain and the breakout sessions on MLOps and GitOps. The conversations I had with other attendees were also incredibly insightful and thought-provoking.

I gained a deeper understanding of containerization from Apoorv Goyal's session, which taught me some of the best practices of containerization. I also enjoyed learning about some of the latest trends in open source development and how developers are using new technologies to solve complex problems.

Overall, attending the wemakedevs tech meetup was a valuable experience that provided me with unique insights and perspectives. I would highly recommend it to other developers and industry professionals who are looking to expand their knowledge and connect with like-minded individuals.

The most memorable moment for me during the meetup was the networking session during lunchtime, where I had the chance to interact with other attendees. It was a valuable opportunity to exchange ideas, share experiences, and establish connections. Additionally, the event provided a platform for me to actively engage with the tech community and expand my network with like-minded individuals who share my passion and aspirations.

In conclusion, attending the wemakedevs tech meetup was a rewarding experience that exceeded my expectations. I left with a deeper understanding of the latest trends in software development and valuable insights from industry experts and peers. I would highly recommend it to anyone looking to enhance their skills and knowledge in the tech industry.

Saturday, 13 May 2023

I’ve been happily using Woodpecker CI to get CI for my repositories on Codeberg. Codeberg is a non-profit community-driven git repository hosting platform, so they can’t provide free CI to everyone.

Since I run lots of stuff on small arm boards (for example this website), I need my CI jobs to create arm executables. The easiest way to get that done is to just compile on arm devices, so I was happy to see that Hetzner is now offering arm nodes in their cloud offering.

To make that as cheap as possible, the CI should ideally create a VM before running its job, and remove it again afterwards. Unfortunately Woodpecker does not seem to support that out of the box at this point.

My solution to that was to build a docker proxy, that creates VMs using docker-machine, and then proxies the incoming requests to the remote VM. That works really well now, so maybe you will find it useful.

Setting that up is reasonably simple:

  • Install docker-machine. I recommend using the fork by GitLab
  • Install the backend for your cloud provider. For Hetzner I use this one
  • Grab a binary release of docker-proxy (if you need arm executables), or compile it yourself.
  • Create a systemd unit to start the service on boot in /etc/systemd/system/docker-proxy.service. This particular one just runs it on the woodpecker-agent user that you may already have if you use Woodpecker CI.
[Unit]
Description=Docker CI proxy
After=network.target

[Service]
User=woodpecker-agent
Group=nogroup
Restart=always
ExecStart=/usr/local/bin/docker-proxy

[Install]
WantedBy=multi-user.target
  • Fill in /etc/docker-proxy/config.toml This example works for Hetzner, but everything that has a docker-machine provider should work. You just need to supply the arguments for the correct backend.
[docker_machine]
driver="hetzner"
args=[
    "--hetzner-api-token=<token>",
    "--hetzner-server-type=cax11",
    "--hetzner-image-id=103907373",
]

[general]
timeout=300
port=8000
  • Finally, make woodpecker-agent use the new docker proxy, by setting DOCKER_HOST=http://localhost:8000 in its environment.

I hope this may be useful for you as well :)

Friday, 12 May 2023

IT feels like a billion years before the last plasma sprint, which was in 2019 in Valencia, before the pandemic, but finally this year we are back on track, and was great to see again many old friends as well as seeing many new faces for which it was the first sprint.

We were gracefully hosted by Tuxedo Computers in Augsburgh, makers of very nice laptops that come with Linux and KDE Plasma, as well as being KDE patrons.

First of all, everybody got up to speed with a full git build of a Plasma 6 session, so that everybody could participate in development and discussions from the same level.

There were many discussions about Plasma 6, about what we want to do in Plasma and in Kirigami, how we want to change the look and defaults for the new major release. Most of the user-facing changes have been wonderfully described by Nate.

On my part, I worked on mainly 2 things, that were fairly not “glamorous” but quite important never the less (and mildly painful to do) : a refactor of the plasmoid loading code and splitting all the Svg themes code to a new framework with far less dependencies, ideally usable by any application.

Plasma API

I spent most of my hacking time at the sprint on a refactor of the plasmoid loading code, which won’t be really “seen” by the user, but will make the infrastructure much more robust and the API cleaner.

The person which must pay attention to it is the plasmoid author, which will need to adapt the plasmoid code in a few places.

Most notable is that, just like when you are writing a QML application you have to use the ApplicationWindow root QML Item, for a plasmoid you now have to use a PlasmoidItem root object, so something like

Item {
    Plasmoid.compactRepresentation: Label {text: Plasmoid.title}
    Plasmoid.fullRepresentation: Item {...}
}

becomes:

PlasmoidItem {
    compactRepresentation: Label {text: Plasmoid.title}
    fullRepresentation: Item {...}
}

A full porting guide is in progress.

KSvg

Using the Plasma Svg code to support stylesheet recoloring, on disk image cache to speed up loading, and the 9-patches FrameSvg is something the several applications would be interested to, and some actually are already doing, but since plasma-framework has a lot of dependencies, for some applications that is a blocker. All the svg code has now been broken out into a new framework called KSvg, which is still work in progress, but in the end will support all existing plasma themes with no change, and if an application wishes to use it, the svg sets will be loaded from the app own data folder (or anywhere else the application configures it to) instead of the share/plasma/desktoptheme folder, where plasmashell looks for them (so they can also use a complete different theme structure and don’t have to provide the same elements)

Tuesday, 9 May 2023

While at the 2023 Plasma Sprint at the Tuxedo Computers office in Augsburg, Germany, I created a patch to add ButtonSegment, SegmentedControl and SegmentSeparator to Qt Quick Controls 6.6: https://codereview.qt-project.org/c/qt/qtdeclarative/+/476564

The patch has not been merged yet and may change significantly.

ButtonSegment is a Button subclass with an edges property that can be used to specify which edges are exposed to the outside of the group. The base flags available are NoEdges (0), TopEdge (Qt::TopEdge), LeftEdge (Qt::LeftEdge), RightEdge (Qt::RightEdge) and BottomEdge (Qt::BottomEdge). Why the outside and not the inside? It doesn’t matter a whole lot, it’s just what I decided to do. My thoughts were "These are the edges where extra visuals will be." There are also flag combination values like AllEdges, TopLeftEdges, TopRightEdges, BottomLeftEdges and BottomRightEdges to make your lines of code shorter.

SegmentedControl is a Control subclass with flat and down properties. This control doesn’t actually do much. Its main purpose is for providing a way to define unified graphics for a segmented button group (e.g., macOS Big Sur has a background underneath all of the button segments). flat can be used to define flat and raised appearances. down can be used to define a unified pressed/down appearance (e.g., a shadow used by a unified raised background could disappear when any segment is pressed). down does not change in response to ButtonSegment::down changes by default. You must set that up yourself. There are ways to make this behavior more automatic, but I have not used them yet. I might make the behavior more automatic because otherwise it will be difficult to support down when button segments are created from delegate components.

SegmentSeparator is a Control subclass that has orientation, vertical and horizontal properties. It has the same API as ToolSeparator. Its purpose is to provide styling for separators between button segments.

Automatic Behavior VS Boilerplate Code

Unlike similar controls provided by Flutter (SegmentedButton) and AppKit (NSSegmentedControl), there is no built-in API for getting/setting the current selected button(s), index(es) or other value(s) from segments. This isn’t a big problem in QML because it is easy to add the additional behaviors or properties you need. You can even choose the ones that suit your use cases the best. Don’t forget that you have ButtonGroup, ActionGroup, Repeater, ListView, GridView and various ways to define models.

Some, maybe even many of you may have felt a bit disappointed after reading the paragraph above. You may have been thinking something along the lines of "Why doesn’t it just do what I want without having to write extra code?" It’s a good question. When people (including myself) try to reduce the amount of code they need to write by making controls do things automatically, they often cause more harm than good. If the problems were obvious and the temptation wasn’t so strong, then people (including myself) wouldn’t make those kinds of mistakes over and over. What often happens is that controls that were intended to be generally useful become more specialized for certain use cases and the people implementing the automatic behavior don’t realize it until they discover that a valid use case they weren’t thinking about has become more difficult or even impossible to support. There are examples of great automatic behavior out there and specialized components where a lack of flexibility is completely acceptable. My point is that people should be careful when implementing automatic behavior. I chose greater flexibility at the cost of requiring users to write more code.

Example Code

This creates three independently checkable segments in a row.

SegmentedControl {
    id: control

    ButtonGroup {
        buttons: control.contentItem.children
        exclusive: false
    }

    contentItem: Row {
        spacing: control.spacing

        ButtonSegment {
            edges: ButtonSegment.TopLeftEdges | ButtonSegment.BottomLeftEdges
            checkable: true
            text: qsTr("Segment 1")
        }

        SegmentSeparator {}

        ButtonSegment {
            edges: ButtonSegment.TopEdge | ButtonSegment.BottomEdge
            checkable: true
            text: qsTr("Segment 2")
        }

        SegmentSeparator {}

        ButtonSegment {
            edges: ButtonSegment.TopRightEdges | ButtonSegment.BottomRightEdges
            checkable: true
            text: qsTr("Segment 3")
        }
    }
}

Planned Supported Styles

Friday, 5 May 2023

OMEMO logo

It’s finally there: Kaidan with end-to-end encryption via OMEMO 2, Automatic Trust Management and support of XMPP Providers! Most of the work has been funded by NLnet via NGI Zero PET and NGI Assure with public money provided by the European Commission. We would also like to thank Radically Open Security (especially Christian Reitter) for a quick security evaluation during the NGI Zero project.

Even if Kaidan is making good progress, please keep in mind that it is not yet a stable app. Do not expect it to work well on all supported systems. Moreover, we do currently not consider Kaidan’s security as good as the security of the dominating chat apps.

There is a new overview of features Kaidan supports. Have a look at that or at the changelog for more details.

Encryption

All messages sent by Kaidan can be encrypted now. If a contact supports the same encryption, Kaidan enables it by default. Therefore, you do not have to enable it by yourself. And you will also never need to worry about enabling it for new contacts. But it is possible to disable it for each contact at any time.

Additionally, all metadata that is encryptable, such as typing notifications, is encrypted too. The new Automatic Trust Management (ATM) makes trust management easier than before. The details are explained in a previous post.

We worked hard on covering as many corner cases as possible. Encrypted sessions are initialized in the background to reduce the loading time. Kaidan even tries to repair sessions broken by other chat apps. But if you discover any strange behavior, please let us know!

We decided to focus on future technologies. Thus, Kaidan does not support OMEMO versions older than 0.8.1. Unfortunately, many other clients do not support the latest version yet. They only encrypt the body (text content) of a message, which is not compatible with newer OMEMO versions and ATM. But we hope that other client developers will follow our lead soon.

Screenshot of Kaidan in widescreen Screenshot of Kaidan

XMPP Providers

Kaidan introduced an easy registration in version 0.5. It used an own list of XMPP providers since then. The new project XMPP Providers arose from that approach. That project is intended to be used by various applications and services.

Kaidan is now one of them. It uses XMPP Providers for its registration process instead of maintaining an own list of providers. Try it out and see how easy it can be to get an XMPP account with Kaidan!

Changelog

This release adds the following features:

  • End-to-end encryption with OMEMO 2 for messages, files and metadata including an easy trust management
  • XMPP Providers support for an easy onboarding
  • Message reactions for sending emojis upon a message
  • Read markers showing which messages a contact has read
  • Message drafts to send entered messages later after switching chats or restarting Kaidan
  • Message search for messages that are not yet loaded
  • New look of the chat background and message bubbles including grouped messages from the same author
  • Chat pinning for reordering chats
  • Public group chat search (without group chat support yet)
  • New contact and account details including the ability to change the own profile picture
  • Restored window position on start

Download

Or install Kaidan from your distribution:

Packaging status

Tuesday, 2 May 2023

This new entry will cover ways to configure global preferences for Maui Apps and Maui Shell.

MauiMan

MauiMan stands for Maui Manager, and exists for setting, saving, and syncing the configuration preferences for the Maui Apps ecosystem. These configurations are global, and some of them can be overridden by the apps themselves, but more about that later. To store the configurations MauiMan uses the MauiMan.conf config file, located at your local config path: for example ~/.config/Maui/MauiMan.conf.

(!) The settings modifications are only written/saved when using the MauiMan API directly.

MauiMan consists of two parts, a (1) background server that syncs and broadcasts the preference properties changes to all the running Maui Apps, and a (2) public API, that allows app developers to easily hook their apps to the system preferences. The MauiMan server program is named MauiManServer and uses the DBus IPC.

The public API and the server are divided into modules: for different setting categories, such as Theme, Background, Accessibility, FormFactor, etc…

Using MauiMan to configure Maui Apps.

To configure existing preferences, there are different ways to do it, from a graphical interface to editing a text file or even hooking to the public API directly (for developers), in the following sections we’ll cover all the possible ways.

The ideal way to set the configurations, from a user perspective, is to use the Maui Settings application, which exposes all the MauiMan preferences in a graphical manner; although, some of the settings presented are “curated” to use predefined sane values, for example, not allowing to set the border-radius of elements to an unfitting value rendering the interface unusable. This means that with this approach you dont get full control over the values of the properties in all the cases, but you are less prompt to mess up.

Maui Settings also exposes other settings for other system stuff, such as Networks, Sound, Notifications, etc. If any of the needed servers to sync configurations are offline, Maui Settings warns you about it and allows you to launch the server daemon with a single click.

(!) Keep in mind that Maui Settings is still under heavy development and most modules are still not implemented.

 

 

Another way to do interact with MauiMan is by using DBus directly. For this one can use a graphical application and navigate to org.mauiman.Manager and then dive into the existing modules for modifying the properties.

(!) Using this approach will not save the changes made: it will keep the changes in memory as long as the MauiManServer daemon is running, but once the process is restarted those changes will be lost since changes to the MauiMan properties are only saved when using the MauiMan public API.

 

 

Another apporach is to manually edit the MauiMan.conf file. It has a couple downsides:

  • The changes won’t be made live.
  • Changes won’t be loaded until MauiManServer process has been restarted since MauiManServer saves in memory the properties and only loads preferences from the config file on startup.

Using this config file is a convenient way to set default values for distributions shipping Maui apps, so they can be styled for the distribution. This config file is located at:

~/.config/Maui/MauiMan.conf

Here’s a snapshot of the config file contents:

[Accessibility]
SingleClick=false

[Background]
DimWallpaper=false
FitWallpaper=false
ShowWallpaper=true
SolidColor=#ffff00
SourceDir=file:///usr/share/wallpapers/Cask
Wallpaper=file:///usr/share/wallpapers/Cask/Cloudy Noon - 5K (16:10).jpg

[FormFactor]
PreferredMode=0

[InputDevices]
KeyboardLayout=us

[Screen]
Orientation=1
ScaleFactor=1

[Theme]
AccentColor=#000
BorderRadius=12
CustomColorScheme=Amethyst
DefaultFont="Noto Sans,10,-1,0,50,0,0,0,0,0,Regular"
EnableCSD=true
EnableEffects=true
IconSize=16
IconTheme=Colloid
MarginSize=4
MonospacedFont="xos4 Terminus,12,-1,7,50,0,0,0,0,0,Regular"
PaddingSize=4
SpacingSize=4
StyleType=1
WindowControlsTheme=CadiumGloss

 

Accessing these MauiMan properties is also possible from an application side too: for developers there is the MauiMan public library which exposes all the properties trough a public API. So if you need to know about the current workspace background image source, you could hook to MauiMan::BackgroundManager::wallpaper()  and even connect to wallpaperChanged signal to know in real time when the wallpaper has been changed.

 

#include <MauiMan/backgroundmanager.h>

void func()
{
auto wallpaper = MauiMan::BackgroundManager().wallpaperSource();
}

 

Most of the properties are already quickly accessible via MauiKit Style object,  (for apps developed using MauiKit) which besides syncing to MauiMan changes can also override these properties with in-app specific values and if needed clear those using undefined to return using the MauiMan values.

For example, for setting the style type as dark for an app, despite the global preference being different:

​​​​Maui.ApplicationWindow
{
Maui.Style.styleType: Maui.Style.Dark
}

​and to reset the value back to the global system preference:

​​​​Maui.ApplicationWindow
{
Maui.Style.styleType: undefined
}​ ​​​

CaskServer

To configure Maui Shell preferences and expose those to any other processes, there is CaskServer, which as MauiMan, has two components: a CaskServer daemon for syncing/broadcasting the properties changes and the public library.

The public library allows apps to request Cask to draw custom shadows, title bar colors, and more privacy settings, via the Chrome and Screenshot modules. More modules include Shell, Power, Profiles, and Notifications.

The Shell module allows tweaking the Cask elements such as dock, panels, launcher, popups, etc preferences.

Some of these properties can be modified from Maui Settings, while others, such as properties from the Chrome module, are specific for a given app, so an individual app can be hooked to the Chrome module via the CaskServer library to perform changes to the available properties.

(!) CaskServer as Maui Settings and Maui Shell is still under heavy development and isn’t stable enough yet for commercial use, keep this in mind if you decide to give it a try.

The CaskServer configuration file is located at :

~/.config/Maui/CaskServer.conf


More detailed information about configuring Cask and Maui Shell will soon be shared, as development progresses.

​​​​​​

To follow the Maui Project’s development or say hi, you can join us on Telegram: https://t.me/mauiproject.

We are present on Twitter and Mastodon:

New release schedule

The post Configuring Maui appeared first on MauiKit — #UIFramework.

Monday, 1 May 2023

A month has passed since my last monthly post about my work as KDE Software Platform Engineer. What have I been up to since then?

As usual not everything I did ended up as committed code. A lot of my work is reviewing other people’s code, discussing ideas, and generally being useful to the community.

One area I’ve been focussing on is our infrastructure for global shortcuts. These are currently handled by the KGlobalAccel framework. This frameworks contains the runtime component that manages global shortcuts as well as an application-facing library to interact with the runtime. The runtime and interface library being in the same project has caused us some issues in the past. To address these the runtime part is now split out into a separate project and part of the Plasma group. You can read up more details on this here. This change also allowed for some further changes that made launching applications from global shortcuts both simpler code-wise and more robust. I have also worked on another set of changes that will address some of the pain points that are currently present in our global shortcuts system. While doing that I also addressed some issues I found in the underlying KDE Frameworks libraries.

Another area I worked on is notifications. One thing I did there was reducing the API surface of the KNotification class by hiding internal API that shouldn’t be exposed to application developers. I also proposed a revamped API for specifying notification actions. The new API is both easier to use for application developers and easier to extend with new features in the future.

With a small API change to KStatusNotifierItem, our class for implementing system tray icons, it is now easier for QML applications to fully make use of its capabilities. The API to set an associated window previously was only really usable for QtWidgets apps, now it can be used for QML apps too.

In some Plasma news: Plasma now uses the C++20 standard. This allows us to use some nifty new C++ features. One big one that comes to mind are coroutines, which have the potential to massively simplify parts of our code. Getting there required some tweaks to make our code and our dependencies fully C++20-compliant.

Talking about dependencies: With our move to Qt6 all of our Qt-based dependencies need to make that move too. appstream-qt, the library that powers e.g. Discover is now ready for that too. I helped integrating that into our build infrastructure. Another project with such dependencies is our online accounts system. It depends on libraries like libaccounts-qt and signond, which I’m working on porting to Qt6.

Last weekend I attended the Linux App Summit in Brno, Czech Republic. It was a lovely event that allowed me to get in touch with both people from KDE and our partner organizations like GNOME and Flathub.

To support the work I and many other people do in KDE please consider donating to KDE e.V. Your donations make my work as KDE Software Platform Engineer possible. Thank you for that!

Sunday, 30 April 2023

Here’s my KDE contributions for this month! It’s a little bit shorter than I’d like, but I’m still trying to find a nice balance between $work and KDE.

Extra CMake Modules

I put up MRs for a bunch of small fixes related to the QML module:

These haven’t been merged yet though, I still need to clean them up and give them some polish next month.

Dr. Konqi

I didn’t work on the new UI this month unfortunately, but I did submit two MRs:

Just like ECM this will be in my queue to merge these next month!

Krita.org

[Feature] I finally merged the improved dark mode I started a while ago, for the new Krita.org website! Thanks to everyone, especially Phu and Scott for being patient with me. I can’t wait to see this live soon :-)

Tokdoon

[Feature] I added support for the new Maximize component, which doesn’t change anything functionality-wise but makes our code leaner:

Screenshot of the Maximize component in action!

[Feature] I also pushed along the MR to use the SearchPopupField component from Kirigami Add-ons too, which is another change that doesn’t change anything functionally but will make the code much leaner.

[Feature] Interaction icons were overhauled, not just visually but also their layout has improved. Below is a screenshot of a mobile sized window, where the icons now spread out which will make them easier to tap (I plan on increasing the size on mobile too!)

Screenshot of the new icons in mobile layout

[Feature] The amount of characters you have left is now shown in the composer, which should load from your server (I don’t have anything but a 500-char limit to test with though):

The character count shows up in the bottom-left

[Feature] It’s not merged yet, but I’m adding overhauling how you view posts on profile pages! It has the usual separation of “Posts”, “Replies” and “Media” tabs but you can hide boosts too:

The new profile tabs and post options

[Feature] As a cherry on top, I added icons to some of the menus which makes them easier to quickly navigate:

Example of the new icon filled menu

Some more minor changes:

Keysmith

[Bugfix] I did some touching up work for Keysmith late this month: I fixed a bunch of binding loops, and added better keyboard navigation.

[Feature] I also added a passive notification when you copy the code to your clipboard too:

Example of the notification

There doesn’t appear to be an active maintainer, so I’ll get another reviewer and merge them next month. I also cleaned up some duplicate bugs, and moved some spam off of the tracker.

Kirigami

[Bugfix] While debugging Tokodon, I fixed a rare case where a Kirigami application using our QQC2 Desktop style could crash when closing. This same “fix” could apply to Breeze style too, it warrants further investigation :-)

[Feature] I realized that NavigationTabBar doesn’t have it’s own page on the gallery, so I proposed a new one in Kirigami gallery:

New page thumbnail in Kirigami Gallery

[Bugfix] I’m still looking for people who might know why PlaceholderMessage fails handling overflow, which creates some recursive rearranges. It might be a Qt upstream issue, so it’s another thing to investigate soon!

Friday, 28 April 2023

It’s already two years since I last looked at KDE git history. As I decribed in the latest edition, this is inspired by the work of Hans Petter Jansson for GNOME and use the tool he made (fornalder).

fornalder is a formidable tool. It is easy to use and the documentation in the readme is great. I don’t know if this is because it was programmed in Rust but fornalder was also blazingly fast and most of the time spent during this analysis was spent on cloning the repos.

These stats include all the extragear, plasma, frameworks and release service repository as well as most of the KDE websites and a few KDE playground projects I had on my hard drive. For example, it doesn’t includes most of the unmaintained projects (e.g. kdepimlibs, koffice, plasma-mediacenter, …). Also important to note, is that this doesn’t include translations at all, since they are stored in SVN and added in the git repository with a script which remove authorship information.

I also removed manually all the scripted commits and I merged the contributions from “Laurent Montel” with “Montel Laurent” as well as the one from various contributors whose name changed.

Active Contributors

Number of contributors by years
Number of contributors by years

The explaination for the colors is described by Hans Petter Janssson in his blog post by:

The stacked histogram above shows the number of contributors who touched the project on a yearly basis. Each contributor is assigned to a generational cohort based on the year of their first contribution. The cohorts tend to shrink over time as people leave.

There’s a special “drive-by” cohort (in a fetching shade of off-white) for contributors who were only briefly involved, meaning all their activity fits in a three-month window. It’s a big group. In a typical year, it numbers 200-400 persons who were not seen before or since. Most of them contribute a single commit.

In 2022, the number of active decreased slightly compared to 2021 and 2020, which might be due to the fact that the pandemic ended and people spend less time on their PC contributing to open source projects (which provided an huge boost in 2019/2020).

Commits Count

Number of commits by years
Number of commits by years

In 2022, the number of commits decreased as well, which can be attributed to the smaller number of overall contributors and a bit less activity from some long time contributors.

But I would not worry too much about these numbers as we are still above the 2019 level (pre-gitlab and pandemic) and looking already at the numbers for the first few months of 2023 it’s increasing again.

Conclusion

I would say that KDE is in relatively good health. This is particularly impressive for a project with little corporate backing and with mostly volunteers.

In 2023, we are also finalizing the transition to Qt6 and KF6 with a first release of KF6 and Plasma 6 around the end of this year, begining of next year.

There is no better time to get involved or to consider making a donation!

You can play with raw data in the form of a sqlite dabase (>200Mb)