- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有实现闪烁边框的类(它每 0.5 秒更改一次颜色)。在调整边框大小之前一切正常。当我调整边框大小时,只有部分边框继续闪烁。我想,问题出在我的 Expose 事件处理程序或调整大小函数中,但我找不到确切位置。主程序启动单独的线程来创建边框。边框由主线程控制:
#include "LinuxBorderWindow.h"
#include <thread>
#include <iostream>
#define W_WIDTH 640
#define W_HEIGHT 480
#define X_POS 100
#define Y_POS 120
#define BORDER_WIDTH 2
LinuxBorderWindow* border;
void threadFunc()
{
border->SetPosition(X_POS, Y_POS, X_POS + W_WIDTH, Y_POS + W_HEIGHT);
border->Start();
}
int main(int argc, char *argv[])
{
border = new LinuxBorderWindow();
std::thread(threadFunc).detach();
int choice = 0;
bool isExit = false;
while(!isExit)
{
std::cout << "Input action" << std::endl;
std::cin >> choice;
switch(choice)
{
case 1:
border->MoveBorder(X_POS + 100, Y_POS + 200);
break;
case 2:
border->ResizeBorder(X_POS + 100, Y_POS + 200, W_WIDTH - 100, W_HEIGHT + 200);
break;
case 3:
border->ResizeBorder(0, 0, W_WIDTH + 100, W_HEIGHT + 200);
break;
case 4:
border->ShowBorder(false);
break;
case 5:
border->ShowBorder(true);
break;
case 0:
isExit = true;
break;
}
}
delete border;
return 0;
}
从代码中可以看出,当 choice 为 2 或 3 时会调用 resize 函数。在这种情况下,边框会正确停止闪烁。
这是边框类:
#pragma once
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/shape.h>
class LinuxBorderWindow
{
public:
LinuxBorderWindow();
~LinuxBorderWindow();
void Start();
void Stop();
void ShowBorder(bool show);
void MoveBorder(int x, int y);
void SetPosition(int x1, int y1, int x2, int y2);
void ResizeBorder(int x1, int y1, int x2, int y2);
void UpdateRegionSizeAndPos();
private:
void CreateBorder();
XRectangle m_windowRect;
short unsigned int m_borderThickness;
Window m_window;
Display* m_display;
XColor _darkOrangeColor;
XColor _lightOrangeColor;
bool m_highlightFrame = false;
};
和 .cpp 文件:
#include "LinuxBorderWindow.h"
#include <thread>
#include <sys/select.h>
#include <cmath>
static int wait_fd(int fd, double seconds)
{
struct timeval tv;
fd_set in_fds;
FD_ZERO(&in_fds);
FD_SET(fd, &in_fds);
tv.tv_sec = trunc(seconds);
tv.tv_usec = (seconds - trunc(seconds))*1000000;
return select(fd+1, &in_fds, 0, 0, &tv);
}
int XNextEventTimeout(Display *display, XEvent *event, double seconds)
{
if (XPending(display) || wait_fd(ConnectionNumber(display),seconds))
{
XNextEvent(display, event);
return 0;
}
else
{
return 1;
}
}
constexpr short frameThickness = 2;
void LinuxBorderWindow::CreateBorder()
{
GC gc;
XGCValues gcv = {0};
Window defaultRootWindow = DefaultRootWindow(m_display);
m_window = XCreateSimpleWindow(m_display, defaultRootWindow, m_windowRect.x, m_windowRect.y,
m_windowRect.width, m_windowRect.height, m_borderThickness, 0, _darkOrangeColor.pixel);
gcv.line_width = m_borderThickness;
gc = XCreateGC(m_display, m_window, GCLineWidth, &gcv);
XSelectInput(m_display, m_window, ExposureMask);
Atom window_type = XInternAtom(m_display, "_NET_WM_WINDOW_TYPE", False);
long value = XInternAtom(m_display, "_NET_WM_WINDOW_TYPE_DOCK", False);
XChangeProperty(m_display, m_window, window_type, XA_ATOM, 32, PropModeReplace, (unsigned char *) &value, 1);
Atom wm_delete_window = XInternAtom(m_display, "WM_DELETE_WINDOW", 0);
XSetWMProtocols(m_display, m_window, &wm_delete_window, 1);
XRectangle rectangles[4] =
{
{ 0, 0, m_windowRect.width, m_borderThickness },
{ 0, 0, m_borderThickness, m_windowRect.height },
{ 0, (short)(m_windowRect.height - m_borderThickness), m_windowRect.width, m_borderThickness },
{ (short)(m_windowRect.width - m_borderThickness), 0, m_borderThickness, m_windowRect.height }
};
XserverRegion region = XFixesCreateRegion(m_display, rectangles, 4);
XFixesSetWindowShapeRegion(m_display, m_window, ShapeBounding, 0, 0, region);
XMapWindow(m_display, m_window);
XFlush(m_display);
XSync(m_display, False);
//std::thread([this, gc]
{
bool run = true;
while(run)
{
XEvent xe;
if(::XNextEventTimeout(m_display, &xe, 0.5))
{
m_highlightFrame = !m_highlightFrame;
xe.type = Expose;
xe.xexpose.count = 0;
}
switch (xe.type)
{
case Expose:
{
XSetForeground(m_display, gc, m_highlightFrame ? _lightOrangeColor.pixel : _darkOrangeColor.pixel);
XFillRectangles(m_display, m_window, gc, rectangles, 4);
XSync(m_display, False);
break;
}
case ClientMessage:
{
if (xe.xclient.message_type == XInternAtom(m_display, "WM_PROTOCOLS", 1)
&& (Atom)xe.xclient.data.l[0] == XInternAtom(m_display, "WM_DELETE_WINDOW", 1))
{
run = false;
}
break;
}
default:
break;
}
}
}//).detach();
}
LinuxBorderWindow::LinuxBorderWindow()
{
m_borderThickness = ::frameThickness;
m_display = XOpenDisplay(NULL);
char orangeDark[] = "#FF8000";
char orangeLight[] = "#FFC90E";
Colormap colormap = DefaultColormap(m_display, 0);
XParseColor(m_display, colormap, orangeDark, &_darkOrangeColor);
XAllocColor(m_display, colormap, &_darkOrangeColor);
XParseColor(m_display, colormap, orangeLight, &_lightOrangeColor);
XAllocColor(m_display, colormap, &_lightOrangeColor);
}
LinuxBorderWindow::~LinuxBorderWindow()
{
if(m_display != NULL)
{
Stop();
XCloseDisplay(m_display);
}
}
void LinuxBorderWindow::Start()
{
CreateBorder();
}
void LinuxBorderWindow::Stop()
{
XWindowAttributes xwa;
XGetWindowAttributes(m_display, m_window, &xwa);
if(xwa.map_state == IsViewable)
{
XUnmapWindow(m_display, m_window);
XDestroyWindow(m_display, m_window);
}
}
void LinuxBorderWindow::SetPosition(int x1, int y1, int x2, int y2)
{
m_windowRect.x = (short)x1;
m_windowRect.y = (short)y1;
m_windowRect.width = (unsigned short)(x2 - x1);
m_windowRect.height = (unsigned short)(y2 - y1);
}
void LinuxBorderWindow::ShowBorder(bool show)
{
XWindowAttributes xwa;
XGetWindowAttributes(m_display, m_window, &xwa);
if(show && xwa.map_state != IsViewable)
{
XMapWindow(m_display, m_window);
}
else if(show == false && xwa.map_state == IsViewable)
{
XUnmapWindow(m_display, m_window);
}
}
void LinuxBorderWindow::MoveBorder(int x, int y)
{
m_windowRect.x = (short)x;
m_windowRect.y = (short)y;
XMoveWindow(m_display, m_window, x, y);
}
void LinuxBorderWindow::ResizeBorder(int x1, int y1, int x2, int y2)
{
SetPosition(int x1, int y1, int x2, int y2)
XMoveResizeWindow(m_display, m_window, m_windowRect.x, m_windowRect.y, m_windowRect.width, m_windowRect.height);
XRectangle rectangles[4] =
{
{ 0, 0, m_windowRect.width, m_borderThickness },
{ 0, 0, m_borderThickness, m_windowRect.height },
{ 0, (short)(m_windowRect.height - m_borderThickness), m_windowRect.width, m_borderThickness },
{ (short)(m_windowRect.width - m_borderThickness), 0, m_borderThickness, m_windowRect.height }
};
XserverRegion region = XFixesCreateRegion(m_display, rectangles, 4);
XFixesSetWindowShapeRegion(m_display, m_window, ShapeBounding, 0, 0, region);
}
所以我的主要问题是如何在调整大小后使所有边框闪烁,而不仅仅是一部分?另一个问题是如何隐藏/显示窗口(ShowBorder 方法),因为 XUnmapWindow/XMapWindow 不起作用。
最佳答案
flicker all border after resize
使 XRectangle 矩形[4]
成为类字段。难怪它开始表现得很奇怪,因为即使在新矩形已应用于窗口后,“闪烁”功能仍会继续使用旧矩形。
how to hide/show window
这个比较棘手。
X11 库不是线程安全的。这就是为什么当您尝试从不同线程操作一个窗口时,可能会发生各种奇怪的事情。通常,基于 std::thread
的方法不是管理 X11 消息循环的正确方法。
这是一个更符合 X11 标准的应用程序,做同样的事情:
#include "LinuxBorderWindow.h"
#include <sys/poll.h>
int main(int argc, char *argv[]) {
enum {
W_WIDTH = 640,
W_HEIGHT = 480,
X_POS = 100,
Y_POS = 120,
BORDER_WIDTH = 4,
MSEC_DELAY = 500,
};
Display *m_display = XOpenDisplay(NULL);
struct pollfd fd = { ConnectionNumber(m_display), POLLIN };
LinuxBorderWindow *border =
new LinuxBorderWindow(m_display, BORDER_WIDTH, X_POS, Y_POS,
X_POS + W_WIDTH, Y_POS + W_HEIGHT);
bool run = true;
while (run) {
if (!XPending(m_display) && !poll(&fd, 1, MSEC_DELAY)) {
border->BlinkBorder();
continue;
}
XEvent xe = {0};
XNextEvent(m_display, &xe);
switch (xe.type) {
case Expose:
break;
case KeyRelease:
switch (XLookupKeysym(&xe.xkey, 0)) {
case '1':
border->ResizeBorder(X_POS + 100, Y_POS + 200);
break;
case '2':
border->ResizeBorder(X_POS + 100, Y_POS + 200,
W_WIDTH - 100, W_HEIGHT + 200);
break;
case '3':
border->ResizeBorder(0, 0, W_WIDTH + 100, W_HEIGHT + 200);
break;
case '4':
border->ShowBorder(false);
break;
case '5':
border->ShowBorder(true);
break;
case '0':
run = false;
break;
}
break;
}
}
delete border;
return XCloseDisplay(m_display);
}
#pragma once
#include <climits>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/shape.h>
#include <X11/extensions/Xfixes.h>
class LinuxBorderWindow {
public:
LinuxBorderWindow(Display *display, short frameThickness,
int x1, int y1, int x2, int y2);
~LinuxBorderWindow();
Window GetWindow() { return m_window; }
void BlinkBorder();
void ShowBorder(bool show);
void ResizeBorder(int x1, int y1, int x2 = INT_MAX, int y2 = INT_MAX);
private:
XColor m_darkOrangeColor;
XColor m_lightOrangeColor;
XRectangle m_windowRect;
unsigned short m_borderThickness;
bool m_highlightFrame = false;
Display *m_display = nullptr;
Window m_window = 0;
};
#include "LinuxBorderWindow.h"
static void SetAtom(Display *disp, Window hwnd, int mode,
const char *name, const char *atom) {
Atom prop = XInternAtom(disp, atom, false);
XChangeProperty(disp, hwnd, XInternAtom(disp, name, false),
XA_ATOM, 32, mode, (unsigned char *)&prop, 1);
}
LinuxBorderWindow::LinuxBorderWindow
(Display *display, short frameThickness, int x1, int y1, int x2, int y2)
: m_display(display), m_borderThickness(frameThickness) {
Colormap colormap = DefaultColormap(m_display, 0);
XParseColor(m_display, colormap, "#FF8000", &m_darkOrangeColor);
XParseColor(m_display, colormap, "#FFC90E", &m_lightOrangeColor);
XAllocColor(m_display, colormap, &m_darkOrangeColor);
XAllocColor(m_display, colormap, &m_lightOrangeColor);
ResizeBorder(x1, y1, x2, y2);
m_window = XCreateSimpleWindow(m_display, DefaultRootWindow(m_display),
m_windowRect.x, m_windowRect.y,
m_windowRect.width, m_windowRect.height,
0, 0, m_darkOrangeColor.pixel);
ShowBorder(true);
XSelectInput(m_display, m_window, ExposureMask | KeyReleaseMask);
// TOOLBAR, since _NET_WM_WINDOW_TYPE_DOCK does not accept keyboard input
SetAtom(m_display, m_window, PropModeReplace,
"_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_TOOLBAR");
// compensating for the lack of _NET_WM_WINDOW_TYPE_DOCK
SetAtom(m_display, m_window, PropModeReplace,
"_NET_WM_STATE", "_NET_WM_STATE_ABOVE");
Atom wm_delete_window = XInternAtom(m_display, "WM_DELETE_WINDOW", 0);
XSetWMProtocols(m_display, m_window, &wm_delete_window, 1);
XMapWindow(m_display, m_window);
XFlush(m_display);
XSync(m_display, false);
}
LinuxBorderWindow::~LinuxBorderWindow() {
if (m_display && m_window) {
XUnmapWindow(m_display, m_window);
XDestroyWindow(m_display, m_window);
}
}
void LinuxBorderWindow::BlinkBorder() {
XSetWindowBackground(m_display, m_window,
(m_highlightFrame = !m_highlightFrame)?
m_lightOrangeColor.pixel : m_darkOrangeColor.pixel);
XClearWindow(m_display, m_window);
}
void LinuxBorderWindow::ShowBorder(bool show) {
unsigned short thickness = (show)? m_borderThickness : 0;
XRectangle rectangles[4] = {
{ 0, 0, m_windowRect.width, thickness },
{ 0, 0, thickness, m_windowRect.height },
{ 0, m_windowRect.height - thickness, m_windowRect.width, thickness },
{ m_windowRect.width - thickness, 0, thickness, m_windowRect.height },
};
XserverRegion rgn = XFixesCreateRegion(m_display, rectangles, 4);
XFixesSetWindowShapeRegion(m_display, m_window, ShapeBounding, 0, 0, rgn);
XFixesDestroyRegion(m_display, rgn);
}
void LinuxBorderWindow::ResizeBorder(int x1, int y1, int x2, int y2) {
m_windowRect.x = x1;
m_windowRect.y = y1;
if (x2 != INT_MAX)
m_windowRect.width = x2 - x1;
if (y2 != INT_MAX)
m_windowRect.height = y2 - y1;
if (m_window) {
XMoveResizeWindow(m_display, m_window, m_windowRect.x, m_windowRect.y,
m_windowRect.width, m_windowRect.height);
ShowBorder(true);
}
}
关于c++ - Xlib。调整大小后重绘(重新填充)闪烁的形状窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57169074/
我是 TensorFlow 菜鸟。我已经从 deeppose 的开源实现中训练了一个 TensorFlow 模型,现在必须针对一组新图像运行该模型。 该模型是在大小为 100 * 100 的图像上训练
我正在尝试以这种方式设置节点的大小: controller[shape=circle,width=.5,label="Controller",style=filled,fillcolor="#8EC1
是否有 VBA 代码可以在选择的每个单元格周围添加文本框。文本框应该是单元格的大小(类似于边框)? 最佳答案 您可以使用 .AddTextbox方法。循环遍历您选择的单元格,并使用单元格的尺寸属性来设
我有一个变量 a尺寸 (1, 5) 我想“平铺”的次数与我的小批量的大小一样多。例如,如果小批量大小为 32,那么我想构造一个张量 c维度为 (32, 5),其中每一行的值与原始 (1, 5) 变量
我在使用 javaFX 时遇到问题。我想每 1000 毫秒在应用程序窗口中显示一次时间。 public class Main extends Application { StackPane root
所以我目前正在创建这个 API。这个登录类应该只创建一个场景,其中包含制作 GUI 所需的所有框。我遇到的问题是,单击时我的形状不会执行任何操作。我有事件监听器,但它不起作用。 import
我正在用 python turtle 画一些东西,我使用了形状函数,但是形状 overdraw 了它们之前的其他形状(我可以看到形状在移动),并且我只得到了最后一个形状: `up() goto(-20
我正在读取多个 .csv 文件作为具有相同形状的 panda DataFrame。对于某些索引,某些值为零,因此我想选择具有相同形状的每个索引的值,并为相同的索引放置零值并删除零以成为相同的形状: a
我有一个简单的二维网格,格式为 myGrid[x,y] 我正在尝试找到一种方法来找到围绕选定网格的周长,这样我就有了一个可供选择的形状。 这是我的意思的一个例子: 这里的想法是找到所有相关的“角”,也
我有一个网络层,用于调用多个端点。我想减少重复代码的数量,并认为也许我可以将响应模型作为端点的一部分传递。 这个想法是不需要多个仅因响应而不同的函数,我可以调用我的网络层并根据路径进行设置。 我看到的
我正在创建一个自定义 ImageView,它将我的图像裁剪成六边形并添加边框。我想知道我的方法是否正确,或者我是否以错误的方式这样做。有很多自定义库已经在执行此操作,但开箱即用的库中没有一个具有我正在
我正在编写一些代码,这些代码需要识别一些基于节点云的相当基本的几何图形。我会对检测感兴趣: 板(简单有界平面) 圆柱体(两个节点循环) 半圆柱(圆弧+直线+圆弧+直线) 圆顶(n*loop+top n
我有这个形状: http://screencast.com/t/9UUhAXT5Wu 但边界在截止点处没有跟随它 - 我该如何解决? 这是我当前 View 的代码: self.view.backgro
我现在脑震荡,所以我想问一个非常简单的问题。 目前,我正在尝试打印出这样的开头 当输入为 7 时,输出为 * ** * ** * ** * 这里是我的代码,它打印 14 次而不是 7 次,或者当我输入
我想生成如下设计。计划选项卡顶部的"new"。我使用的属性适用于 chrome 和 mozilla,但在 Edge 中出现故障。 以下是我在 chrome 中应用的样式: a.subnav__item
我想要一个带有两种颜色边框轮廓的 shape 元素。我可以使用 solid 元素做一个单一的颜色轮廓,但这只允许我画一条线。我尝试在我的形状中使用两个 stroke 元素,但这也不起作用。 有没有办法
我需要为屏幕上的形状着色任何我想要的颜色。我目前正在尝试使用 UIImage 来执行此操作,我想根据自己的需要重新着色。据我所知,执行此操作的唯一方法是获取 UIImage 的各个像素,这需要更多我想
因此,经过多年的 OOP,我从我的一门大学类(class)中得到了一个非常简单的家庭作业,以实现一个简单的面向对象的结构。 要求的设计: 实现面向对象的解决方案以创建以下形状: 椭圆、圆形、正方形、矩
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我想知道是否可以使用类似于以下的 div 制作复杂的形状: 它基本上是一个四 Angular 向内收缩的圆 Angular 正方形。目标是使用背景图像来填充它。我可以使用具有以下 SVG 路径的剪辑蒙
我是一名优秀的程序员,十分优秀!