Linux. Draw border around specific window Topic is solved
Re: Linux. Draw border around specific window
also don't create wxTimer by new. to avoid new/delete.
just declare timer as field in your frame class.
wxTimer _m_appRefreshTimer;
and stop it in destructor.
just declare timer as field in your frame class.
wxTimer _m_appRefreshTimer;
and stop it in destructor.
ubuntu 20.04, wxWidgets 3.2.1
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Linux. Draw border around specific window
xdpyinfo | grep dimensions returns 1024 x 768.
I tried to call GetPosition() after SetShape() and it returned 262, 28. The same position for border I see in paint (I made screenshot of the desktop and inserted it in the paint application).
Thanks for timer advise.
I tried to call GetPosition() after SetShape() and it returned 262, 28. The same position for border I see in paint (I made screenshot of the desktop and inserted it in the paint application).
Thanks for timer advise.
Re: Linux. Draw border around specific window
what i do not know - in which coordinates all this regions for shape must be given... it could be parent coordinates(screen in your case), but also could be relative to frame coordinates. if i remember there is no mentioning in documentaion.
may be try to change origin from windowRect.x, windowRect.y, to 0,0?
comment this code and write this block with zeroes instead of x,y
may be try to change origin from windowRect.x, windowRect.y, to 0,0?
Code: Select all
shapeRegion.Union(wxRect(m_windowRect.x, m_windowRect.y, m_windowRect.width, thickness)); // upper border
shapeRegion.Union(wxRect(m_windowRect.x, m_windowRect.y, thickness, m_windowRect.height)); // left border
shapeRegion.Union(wxRect(m_windowRect.x, m_windowRect.y + m_windowRect.height - thickness, m_windowRect.width, thickness)); // bot border
shapeRegion.Union(wxRect(m_windowRect.x + m_windowRect.width - thickness, m_windowRect.y, thickness, m_windowRect.height)); // right border
ubuntu 20.04, wxWidgets 3.2.1
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Linux. Draw border around specific window
Tried it. It didn't help.
I tried to SetSize with 0, 0 offset, however it didn't help too.
I tried to SetSize with 0, 0 offset, however it didn't help too.
Re: Linux. Draw border around specific window
put here your final code
ubuntu 20.04, wxWidgets 3.2.1
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Linux. Draw border around specific window
Code: Select all
#pragma once
#include <wx/frame.h>
class wxTimer;
class wxTimerEvent;
class LinuxBorderWindow: public wxFrame
{
public:
LinuxBorderWindow(int borderThickness = -1);
~LinuxBorderWindow();
void Start();
void Stop();
void SetPosition(int x, int y, int w, int h);
void UpdateRegionSizeAndPos();
void MoveBorder(int x, int y);
protected:
void OnTimer(wxTimerEvent&);
private:
bool m_highlightFrame = false;
int m_borderThickness;
wxRect m_windowRect;
wxTimer* m_appRefreshTimer = nullptr;
};
Code: Select all
#include "stdafx.h"
#include "LinuxBorderWindow.h"
#include "Dumper.h"
#include "WxWidgetsControls/FromDIP.h"
#include <wx/timer.h>
namespace
{
constexpr int frameThickness = 5;
const wxColour bckgBrushDark(255, 128, 0);
const wxColour bckgBrushLight(255, 201, 14);
}
LinuxBorderWindow::LinuxBorderWindow(int borderThickness):
wxFrame(nullptr, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
0
| wxFRAME_SHAPED
| wxSIMPLE_BORDER
| wxFRAME_NO_TASKBAR
| wxSTAY_ON_TOP
),
m_borderThickness(borderThickness)
{
if(m_borderThickness == -1)
{
m_borderThickness = ::frameThickness;
}
}
LinuxBorderWindow::~LinuxBorderWindow()
{
Stop();
}
void LinuxBorderWindow::Start()
{
UpdateRegionSizeAndPos();
SetBackgroundColour(bckgBrushDark);
m_appRefreshTimer = new wxTimer(this);
Bind(wxEVT_TIMER, &LinuxBorderWindow::OnTimer, this);
m_appRefreshTimer->Start(500);
}
void LinuxBorderWindow::Stop()
{
if(m_appRefreshTimer != nullptr)
{
m_appRefreshTimer->Stop();
Unbind(wxEVT_TIMER, &LinuxBorderWindow::OnTimer, this);
delete m_appRefreshTimer;
m_appRefreshTimer = nullptr;
}
}
void LinuxBorderWindow::SetPosition(int x, int y, int w, int h)
{
DUMPER_INFO("New pos (%d, %d) - %dx%d", x, y, w, h);
wxPoint leftTop = ScreenToClient(wxPoint(x, y));
DUMPER_INFO("Coords after transform (%d, %d)", leftTop.x, leftTop.y);
m_windowRect.x = x;//leftTop.x;
m_windowRect.y = y;//leftTop.y;
m_windowRect.width = w;
m_windowRect.height = h;
}
void LinuxBorderWindow::OnTimer(wxTimerEvent&)
{
SetBackgroundColour(m_highlightFrame ? bckgBrushLight : bckgBrushDark);
m_highlightFrame = !m_highlightFrame;
}
void LinuxBorderWindow::UpdateRegionSizeAndPos()
{
DUMPER_INFO("New rect (%d, %d) - %dx%d", m_windowRect.x, m_windowRect.y, m_windowRect.width, m_windowRect.height);
SetShape(wxRegion());
SetSize(m_windowRect.x + m_windowRect.width, m_windowRect.y + m_windowRect.height);
//SetSize(m_windowRect.x, m_windowRect.y, m_windowRect.width, m_windowRect.height);
wxRegion shapeRegion;
int thickness = FromDIP(m_borderThickness);
shapeRegion.Union(wxRect(m_windowRect.x, m_windowRect.y, m_windowRect.width, thickness)); // upper border
shapeRegion.Union(wxRect(m_windowRect.x, m_windowRect.y, thickness, m_windowRect.height)); // left border
shapeRegion.Union(wxRect(m_windowRect.x, m_windowRect.y + m_windowRect.height - thickness, m_windowRect.width, thickness)); // bot border
shapeRegion.Union(wxRect(m_windowRect.x + m_windowRect.width - thickness, m_windowRect.y, thickness, m_windowRect.height)); // right border
SetShape(shapeRegion);
wxRect rc = shapeRegion.GetBox();
DUMPER_INFO("box params: (%d, %d) %dx%d", rc.GetLeftTop().x, rc.GetLeftTop().y, rc.width, rc.height);
wxPoint pos = GetPosition();
DUMPER_INFO("Pos: %d, %d", pos.x, pos.y);
}
void LinuxBorderWindow::MoveBorder(int x, int y)
{
wxPoint pos = ClientToScreen(wxPoint(x, y));
Move(x, y);
}
Re: Linux. Draw border around specific window
this your old code, i briefly corrected, works
look at added this->Update() at timer and UpdateSize.. functions
regions also are relative to window coordinates - origin is 0,0
also i declared timer as field of frame.
look at added this->Update() at timer and UpdateSize.. functions
regions also are relative to window coordinates - origin is 0,0
also i declared timer as field of frame.
Code: Select all
namespace
{
constexpr int frameThickness = 5;
const wxColour bckgBrushDark(255, 128, 0);
const wxColour bckgBrushLight(255, 201, 14);
}
LinuxBorderWindow::LinuxBorderWindow(int borderThickness):
wxFrame(nullptr, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
0
| wxFRAME_SHAPED
| wxSIMPLE_BORDER
| wxFRAME_NO_TASKBAR
| wxSTAY_ON_TOP
),
m_borderThickness(borderThickness)
{
if(m_borderThickness == -1)
{
m_borderThickness = ::frameThickness;
}
}
LinuxBorderWindow::~LinuxBorderWindow()
{
Stop();
}
void LinuxBorderWindow::Start()
{
//UpdateRegionSizeAndPos();
SetBackgroundColour(bckgBrushDark);
Bind(wxEVT_TIMER, &LinuxBorderWindow::OnTimer, this);
_appRefreshTimer.Start(500);
}
void LinuxBorderWindow::Stop()
{
_appRefreshTimer.Stop();
Unbind(wxEVT_TIMER, &LinuxBorderWindow::OnTimer, this);
}
void LinuxBorderWindow::SetPosition(int x, int y, int w, int h)
{
//wxPoint leftTop = ScreenToClient(wxPoint(x, y));
wxPoint leftTop(x,y);
m_windowRect.x = leftTop.x;
m_windowRect.y = leftTop.y;
m_windowRect.width = w;
m_windowRect.height = h;
}
void LinuxBorderWindow::OnTimer(wxTimerEvent&)
{
SetBackgroundColour(m_highlightFrame ? bckgBrushLight : bckgBrushDark);
m_highlightFrame = !m_highlightFrame;
this->Update();
}
void LinuxBorderWindow::UpdateRegionSizeAndPos()
{
//SetShape(wxRegion());
#if 0
SetSize(m_windowRect.x, m_windowRect.y, m_windowRect.width, m_windowRect.height);
wxRegion shapeRegion;
int thickness = 4;//FromDIP(m_borderThickness);
shapeRegion.Union(wxRect(m_windowRect.x, m_windowRect.y, m_windowRect.width, thickness)); // upper border
shapeRegion.Union(wxRect(m_windowRect.x, m_windowRect.y, thickness, m_windowRect.height)); // left border
shapeRegion.Union(wxRect(m_windowRect.x, m_windowRect.y + m_windowRect.height - thickness, m_windowRect.width, thickness)); // bot border
shapeRegion.Union(wxRect(m_windowRect.x + m_windowRect.width - thickness, m_windowRect.y, thickness, m_windowRect.height)); // right border
SetShape(shapeRegion);
#endif
SetSize(m_windowRect.x, m_windowRect.y, m_windowRect.width, m_windowRect.height);
wxRegion shapeRegion;
int thickness = 4;//FromDIP(m_borderThickness);
shapeRegion.Union(wxRect(0, 0, m_windowRect.width, thickness)); // upper border
shapeRegion.Union(wxRect(0, 0, thickness, m_windowRect.height)); // left border
shapeRegion.Union(wxRect(0, 0+ m_windowRect.height - thickness, m_windowRect.width, thickness)); // bot border
shapeRegion.Union(wxRect(0 + m_windowRect.width - thickness, 0, thickness, m_windowRect.height)); // right border
SetShape(shapeRegion);
this->Update();
}
void LinuxBorderWindow::Move(int x, int y)
{
//wxPoint pos = ScreenToClient(wxPoint(x, y));
//wxFrame::Move(pos.x, pos.y);
wxFrame::Move(x,y);
}
ubuntu 20.04, wxWidgets 3.2.1
Re: Linux. Draw border around specific window
also you forgot to call this function for timer
https://docs.wxwidgets.org/3.0/classwx_ ... 4733eab27e
in current code timer events do not reach your handler.
do it before binding onTimer method to event->
_timer.SetOwner(this);
Bind(wxEVT_TIMER, &LinuxBorderWindow::OnTimer, this);
https://docs.wxwidgets.org/3.0/classwx_ ... 4733eab27e
in current code timer events do not reach your handler.
do it before binding onTimer method to event->
_timer.SetOwner(this);
Bind(wxEVT_TIMER, &LinuxBorderWindow::OnTimer, this);
ubuntu 20.04, wxWidgets 3.2.1
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Linux. Draw border around specific window
It works almost fine for full desktop, but not for region (for example, if I want to draw border around rect with x = 198, y = 243, w = 500, h = 300), it draws border in incorrect offset.
Here is my code:
I uncommented UpdateRegionSizeAndPos(); in Start method
UPD something wrong in my init code. With hardcoded values everything is OK. I'll check it tomorrow and update you with results.
Thanks for help
Here is my code:
Code: Select all
#include "stdafx.h"
#include "LinuxBorderWindow.h"
#include "Dumper.h"
#include "WxWidgetsControls/FromDIP.h"
namespace
{
constexpr int frameThickness = 5;
const wxColour bckgBrushDark(255, 128, 0);
const wxColour bckgBrushLight(255, 201, 14);
}
LinuxBorderWindow::LinuxBorderWindow(int borderThickness):
wxFrame(nullptr, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
0
| wxFRAME_SHAPED
| wxSIMPLE_BORDER
| wxFRAME_NO_TASKBAR
| wxSTAY_ON_TOP
),
m_borderThickness(borderThickness)
{
if(m_borderThickness == -1)
{
m_borderThickness = ::frameThickness;
}
}
LinuxBorderWindow::~LinuxBorderWindow()
{
Stop();
}
void LinuxBorderWindow::Start()
{
UpdateRegionSizeAndPos();
SetBackgroundColour(bckgBrushDark);
m_appRefreshTimer.SetOwner(this);
Bind(wxEVT_TIMER, &LinuxBorderWindow::OnTimer, this);
m_appRefreshTimer.Start(500);
}
void LinuxBorderWindow::Stop()
{
if(m_appRefreshTimer.IsRunning())
{
m_appRefreshTimer.Stop();
Unbind(wxEVT_TIMER, &LinuxBorderWindow::OnTimer, this);
}
}
void LinuxBorderWindow::SetPosition(int x, int y, int w, int h)
{
wxPoint leftTop = ScreenToClient(wxPoint(x, y));
m_windowRect.x = x;//leftTop.x;
m_windowRect.y = y;//leftTop.y;
m_windowRect.width = w;
m_windowRect.height = h;
}
void LinuxBorderWindow::OnTimer(wxTimerEvent&)
{
SetBackgroundColour(m_highlightFrame ? bckgBrushLight : bckgBrushDark);
m_highlightFrame = !m_highlightFrame;
this->Update();
}
void LinuxBorderWindow::UpdateRegionSizeAndPos()
{
SetShape(wxRegion());;
SetSize(m_windowRect.x, m_windowRect.y, m_windowRect.width, m_windowRect.height);
wxRegion shapeRegion;
int thickness = FromDIP(m_borderThickness);
shapeRegion.Union(wxRect(0, 0, m_windowRect.width, thickness)); // upper border
shapeRegion.Union(wxRect(0, 0, thickness, m_windowRect.height)); // left border
shapeRegion.Union(wxRect(0, 0+ m_windowRect.height - thickness, m_windowRect.width, thickness)); // bot border
shapeRegion.Union(wxRect(0 + m_windowRect.width - thickness, 0, thickness, m_windowRect.height)); // right border
SetShape(shapeRegion);
this->Update();
}
void LinuxBorderWindow::MoveBorder(int x, int y)
{
wxFrame::Move(x, y);
}
UPD something wrong in my init code. With hardcoded values everything is OK. I'll check it tomorrow and update you with results.
Thanks for help
Re: Linux. Draw border around specific window
i tested my code giving rect - 100,100,100,100 and then 100,200,100,200.
everything fit well. second region was below first, and touched his bottom with upper border...
i'm sure you are giving wrong coordinates to your SetPosition.
it must be absolute coordinates of your targeted frame, not any client area or something.
added:
you must use wxRect GetRect() of target window(if it has not parents!!!) and give this rect to your blinking border frame.
it must work
https://docs.wxwidgets.org/3.0/classwx_ ... fbe38745eb
or get screen position - next function in help. to take screen coordinates, and take size and then give it to blinking frame
everything fit well. second region was below first, and touched his bottom with upper border...
i'm sure you are giving wrong coordinates to your SetPosition.
it must be absolute coordinates of your targeted frame, not any client area or something.
added:
you must use wxRect GetRect() of target window(if it has not parents!!!) and give this rect to your blinking border frame.
it must work
https://docs.wxwidgets.org/3.0/classwx_ ... fbe38745eb
or get screen position - next function in help. to take screen coordinates, and take size and then give it to blinking frame
ubuntu 20.04, wxWidgets 3.2.1
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Linux. Draw border around specific window
Indeed, there was an error in code that calculates border area.
Now everything looks fine.
Here is one more problem left. When I draw border for whole desktop, then bottom and top panes of desktop are painted with something unclear: As you can see when I draw border there is no bottom pane with running apps and top pane with date and shutdown button
Now everything looks fine.
Here is one more problem left. When I draw border for whole desktop, then bottom and top panes of desktop are painted with something unclear: As you can see when I draw border there is no bottom pane with running apps and top pane with date and shutdown button
Re: Linux. Draw border around specific window
it's some interference with your OS windowing system. this areas are used by system to draw taskbar, etc... and they are not given to application windows. I do not know how to solve it, because here interests of OS native interface and your wxWIdgets app are opposed.
any way application cannot draw something there, if it is not in full screen mode. It could not be bad for you, if you are drawing border for app window, not the screen entirely?
imho, the native windowing system understands, that something is drawn above its top and bottom bars, so hides them, and is not painting them. make the frame slightly smaller and you would see visible parts of this bars.
any way application cannot draw something there, if it is not in full screen mode. It could not be bad for you, if you are drawing border for app window, not the screen entirely?
imho, the native windowing system understands, that something is drawn above its top and bottom bars, so hides them, and is not painting them. make the frame slightly smaller and you would see visible parts of this bars.
ubuntu 20.04, wxWidgets 3.2.1
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Linux. Draw border around specific window
When I drew border using gtk it wasn't possible to draw border on these panes until I changed border type to GTK_WINDOW_POPUP. As it said in description:
I tried to remove wxSTAY_ON_TOP style, but it didn't help?
Do you know if there something like GTK_WINDOW_POPUP in wxWidgets?
Code: Select all
If you're implementing something like a popup menu from scratch (which is a bad idea, just use GtkMenu), you might use GTK_WINDOW_POPUP. GTK_WINDOW_POPUP is not for dialogs, though in some other toolkits dialogs are called "popups". In GTK+, GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
Do you know if there something like GTK_WINDOW_POPUP in wxWidgets?
Re: Linux. Draw border around specific window
this?
https://docs.wxwidgets.org/trunk/classw ... indow.html
but why you need to draw something there, if you want to draw border of regular application window?
https://docs.wxwidgets.org/trunk/classw ... indow.html
but why you need to draw something there, if you want to draw border of regular application window?
ubuntu 20.04, wxWidgets 3.2.1
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Linux. Draw border around specific window
I meant style I can use in wxFrame constructor to make it popup-like.alys666 wrote: ↑Thu Jun 13, 2019 7:43 am this?
https://docs.wxwidgets.org/trunk/classw ... indow.html
but why you need to draw something there, if you want to draw border of regular application window?
I need to draw border there because my app can handle three types of screen sharing: application, custom region and whole desktop. This border works fine with first two types, but not with entire desktop.