Week 9 recap GSoC 2025 - Add Toolbar Boundaries
Intro
After adding the ability to drag and reposition the Selection Action Bar on the canvas last week, I spent this week improving that interaction. I tackled the issue where users could drag the toolbar completely off-screen, making it inaccessible. This week was all about keeping the toolbar within the canvas boundaries.
Side note: This week I also updated the UI to resemble the mockup concept provided from the community.

Obstacles to Implementation
During testing I noticed that without boundaries, the draggable toolbar could end up hidden and inaccessible especially after window or sidebar resizing. This would make it frustrating for users because they would have to find the missing toolbar or toggle the feature off and back on just to relocate it. I wanted to make the toolbar's positioning restricted to canvas boundaries to keep the toolbar within users' vision.
Find Canvas Boundaries
Looking into the code, I found that the canvasWidget had a property QRect rect() which holds the dimensions of the canvas. We can use these values as the boundaries.
Add Boundaries to Drag Event
With canvasBounds defined, we can limit the drag operation to stay within the canvas dimensions. Based on the current canvas dimensions and during a drag event, we update the horizontal and vertical limits of the toolbar position with the use of qBound which provides an upper and lower boundary for a value. So if the coordinates of the toolbar were to go past the boundaries, qBound would return the defined upper or lower boundary value. On top of canvas boundaries, it is important to include the dimensions of the toolbar and buffer room in the calculation to make sure the UI elements are accessible.
// updated drag event with canvas boundaries
QPoint newPos = mouseEvent->pos() - d->dragStartOffset;
QRect canvasBounds = canvasWidget->rect();
int actionBarWidth = 125;
int actionBarHeight = 25;
int bufferSpace = 5;
newPos.setX(qBound(canvasBounds.left() + bufferSpace, newPos.x(), canvasBounds.right() - actionBarWidth - bufferSpace));
newPos.setY(qBound(canvasBounds.top() + bufferSpace, newPos.y(), canvasBounds.bottom() - actionBarHeight - bufferSpace));
d->dragRectPosition = newPos;
canvasWidget->update();
return true;
Conclusion
This week was focused on improving the user experience and accessibility of the Selection Action Bar. I learned about some great Qt tools, like the properties of QWidget and Qt helper functions like qBound to help solve my problem! In the coming final weeks, I'll continue adding action buttons based on the list provided by the community.
Contact
To anyone reading this, please feel free to reach out to me. I'm always open to suggestions and thoughts on how to improve as a developer and as a person.
Email: ross.erosales@gmail.com
Matrix: @rossr:matrix.org