Skip to content

Add Refactored Tizen.WindowSystem#7459

Open
JoonghyunCho wants to merge 1 commit intoSamsung:mainfrom
JoonghyunCho:refactor-windowsystem-re
Open

Add Refactored Tizen.WindowSystem#7459
JoonghyunCho wants to merge 1 commit intoSamsung:mainfrom
JoonghyunCho:refactor-windowsystem-re

Conversation

@JoonghyunCho
Copy link
Member

Description of Change

This PR refactors the Tizen.NUI.WindowSystem namespace to improve code quality, adhere to .NET Framework design guidelines, and remove the dependency on Tizen.NUI.

Changes

  • Namespace Update: Changed namespace from Tizen.NUI.WindowSystem to Tizen.WindowSystem.
  • Dependency Removal: Removed dependency on Tizen.NUI.
  • Dispose Pattern: Removed DisposeQueue and implemented the standard .NET IDisposable pattern using SafeHandle.
  • Input Gesture Refactoring: Refactored the InputGesture structure to an Object-Oriented Programming (OOP) style.
  • API Design: Converted Get/Set methods to Properties where appropriate.
  • Cleanup: Removed unnecessary destructors.
  • File Reorganization: Rearranged files and folders for better project structure.
  • Naming Conventions: Updated naming of enums, methods, and properties to align with .NET Framework guidelines.

API List

Below is the list of classes, methods, properties, and events included in this refactoring:

Tizen.WindowSystem.Shell namespace

  • TizenShell class

    • TizenShell()
    • void Dispose()
  • ShellRegion class

    • ShellRegion(TizenShell tzShell)
    • void Dispose()
    • void Add(int x, int y, int w, int h)
    • void Subtract(int x, int y, int w, int h)
  • QuickPanelClient class

    • QuickPanelClient(TizenShell tzShell, IWindowProvider win, QuickPanelCategory type)
    • void Dispose()
    • Properties
      • QuickPanelVisibility Visibility { get; }
      • QuickPanelScrollMode ScrollMode { get; set; }
      • WindowOrientation Orientation { get; }
    • Methods
      • void Show()
      • void Hide()
    • Events
      • event EventHandler VisibleChanged
      • event EventHandler OrientationChanged
      • event EventHandler RotationChanged
  • QuickPanelService class

    • QuickPanelService(TizenShell tzShell, IWindowProvider win, QuickPanelCategory type)
    • void Dispose()
    • Properties
      • QuickPanelCategory ServiceType { get; }
      • QuickPanelEffect Effect
      • bool IsLocked { get; set; }
    • Methods
      • void Show()
      • void Hide()
      • void SetContentRegion(uint angle, ShellRegion region)
      • void SetHandlerRegion(uint angle, ShellRegion region)
  • SoftkeyClient class

    • SoftkeyClient(TizenShell tzShell, IWindowProvider win)
    • void Dispose()
    • Properties
      • SoftkeyVisibleState Visible { get; }
      • SoftkeyExpandState Expand { get; set; }
      • SoftkeyOpacityState Opacity { get; set; }
    • Methods
      • void Show()
      • void Hide()
  • SoftkeyService class

    • SoftkeyService(TizenShell tzShell, IWindowProvider win)
    • void Dispose()
    • Methods
      • void Show()
      • void Hide()
    • Events
      • event EventHandler VisibleChanged
      • event EventHandler ExpandChanged
      • event EventHandler OpacityChanged
  • TaskbarService class

    • TaskbarService(TizenShell tzShell, IWindowProvider win, TaskbarPoition position)
    • void Dispose()
    • Properties
      • TaskbarPoition Position { get; set; }
    • Methods
      • void ReSize(uint width, uint height)
  • KVMService class

    • KVMService(TizenShell tzShell, IWindowProvider win)
    • void Dispose()
    • Methods
      • void PerformDrop()
      • void PerformDrop(DropTarget target)
      • void CancelDrag()
      • void ReceiveDragData(string mimeType)
      • IEnumerable GetSourceMimetypes()
      • void SetSecondarySelection()
      • void UnsetSecondarySelection()
    • Events
      • event EventHandler DragStarted
      • event EventHandler DragEnded
  • ScreensaverService class

    • ScreensaverService(TizenShell tzShell, IWindowProvider win)
    • void Dispose()

Tizen.WindowSystem namespace

  • InputGenerator class

    • InputGenerator(InputGeneratorDevices devType)
    • InputGenerator(InputGeneratorDevices devType, string name, bool sync)
    • void Dispose()
    • Methods
      • void GenerateKey(string keyName, int pressed)
      • void GeneratePointer(int buttons, PointerAction pointerType, int x, int y)
      • void GenerateWheel(WheelDirection wheelType, int value)
      • void GenerateTouch(int idx, TouchAction touchType, int x, int y)
      • void GenerateTouchAxis(int idx, TouchAction touchType, int x, int y, double radius_x, double radius_y, double pressure, double angle, double palm)
  • InputGesture class

    • InputGesture()
    • void Dispose()
    • Methods
      • EdgeSwipeGesture CreateEdgeSwipe(int fingers, GestureEdge edge)
      • EdgeDragGesture CreateEdgeDrag(int fingers, GestureEdge edge)
      • TapGesture CreateTap(int fingers, int repeats)
      • PalmCoverGesture CreatePalmCover()
  • abstract Gesture class

    • Properties
      • GestureGrabMode GrabMode { get; set; }
    • Methods
      • Grab()
      • Ungrab()
  • EdgeDragGesture, EdgeSwipeGesture, PalmCoverGesture, TapGesture class inherits Gesture

    • Events
      • Detected
  • Enums

    • QuickPanelScrollMode
    • SoftkeyOpacity
    • SoftkeyVisibility
    • TaskbarPosition
    • QuickPanelType
    • QuickPanelEffectType
    • SoftkeyExpandState
    • WindowOrientation
    • GestureState
    • InputGeneratorDeviceType
    • InputGeneratorPointerType
    • InputGeneratorPointerWheelType
    • InputGeneratorTouchType
    • GestureEdge
  • EventArgs

    • EdgeDragEventArgs
    • EdgeSwipeEventArgs
    • PalmCoverEventArgs
    • TapEventArgs

@github-actions github-actions bot added the API14 Platform : Tizen 11.0 / TFM: net8.0-tizen11.0 label Feb 6, 2026
@TizenAPI-Bot
Copy link
Collaborator

Public API Changed

Please follow the ACR process for the changed API below.

Added: 39, Removed: 0, Changed: 0

Added

+ /// <since_tizen>8</since_tizen
+ Tizen.WindowSystem.Shell.QuickPanelCategory

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelCategory Tizen.WindowSystem.Shell.QuickPanelCategory::AppsMenu

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelCategory Tizen.WindowSystem.Shell.QuickPanelCategory::ContextMenu

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelCategory Tizen.WindowSystem.Shell.QuickPanelCategory::SystemDefault

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelCategory Tizen.WindowSystem.Shell.QuickPanelCategory::Unknown

+ /// <since_tizen>8</since_tizen
+ Tizen.WindowSystem.Shell.QuickPanelClient

+ /// <since_tizen>8</since_tizen
+ Tizen.WindowSystem.Shell.QuickPanelScrollMode Tizen.WindowSystem.Shell.QuickPanelClient::ScrollMode()

+ /// <since_tizen>8</since_tizen
+ Tizen.WindowSystem.Shell.QuickPanelVisibility Tizen.WindowSystem.Shell.QuickPanelClient::Visibility()

+ /// <since_tizen>8</since_tizen
+ Tizen.WindowSystem.Shell.WindowOrientation Tizen.WindowSystem.Shell.QuickPanelClient::Orientation()

+ /// <since_tizen>12</since_tizen
+ System.Void Tizen.WindowSystem.Shell.QuickPanelClient::.ctor(Tizen.WindowSystem.Shell.TizenShell,Tizen.Common.IWindowProvider,Tizen.WindowSystem.Shell.QuickPanelCategory)

+ /// <since_tizen>8</since_tizen
+ System.Void Tizen.WindowSystem.Shell.QuickPanelClient::Dispose()

+ /// <since_tizen>none</since_tizen
+ System.Void Tizen.WindowSystem.Shell.QuickPanelClient::Dispose(System.Boolean)

+ /// <since_tizen>8</since_tizen
+ System.Void Tizen.WindowSystem.Shell.QuickPanelClient::Hide()

+ /// <since_tizen>8</since_tizen
+ System.Void Tizen.WindowSystem.Shell.QuickPanelClient::Show()

+ /// <since_tizen>12</since_tizen
+ System.EventHandler`1<System.Int32> Tizen.WindowSystem.Shell.QuickPanelClient::RotationChanged

+ /// <since_tizen>8</since_tizen
+ System.EventHandler`1<Tizen.WindowSystem.Shell.QuickPanelVisibility> Tizen.WindowSystem.Shell.QuickPanelClient::VisibleChanged

+ /// <since_tizen>8</since_tizen
+ System.EventHandler`1<Tizen.WindowSystem.Shell.WindowOrientation> Tizen.WindowSystem.Shell.QuickPanelClient::OrientationChanged

+ /// <since_tizen>none</since_tizen
+ Tizen.WindowSystem.Shell.QuickPanelEffect

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelEffect Tizen.WindowSystem.Shell.QuickPanelEffect::Custom

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelEffect Tizen.WindowSystem.Shell.QuickPanelEffect::Move

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelEffect Tizen.WindowSystem.Shell.QuickPanelEffect::Swipe

+ /// <since_tizen>8</since_tizen
+ Tizen.WindowSystem.Shell.QuickPanelScrollMode

+ /// <since_tizen>8</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelScrollMode Tizen.WindowSystem.Shell.QuickPanelScrollMode::NotScrollable

+ /// <since_tizen>8</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelScrollMode Tizen.WindowSystem.Shell.QuickPanelScrollMode::Retain

+ /// <since_tizen>8</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelScrollMode Tizen.WindowSystem.Shell.QuickPanelScrollMode::Scrollable

+ /// <since_tizen>8</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelScrollMode Tizen.WindowSystem.Shell.QuickPanelScrollMode::Unknown

+ /// <since_tizen>8</since_tizen
+ Tizen.WindowSystem.Shell.QuickPanelVisibility

+ /// <since_tizen>8</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelVisibility Tizen.WindowSystem.Shell.QuickPanelVisibility::Hidden

+ /// <since_tizen>8</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelVisibility Tizen.WindowSystem.Shell.QuickPanelVisibility::Shown

+ /// <since_tizen>8</since_tizen
+ static Tizen.WindowSystem.Shell.QuickPanelVisibility Tizen.WindowSystem.Shell.QuickPanelVisibility::Unknown

+ /// <since_tizen>none</since_tizen
+ Tizen.WindowSystem.Shell.TaskbarPoition

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.TaskbarPoition Tizen.WindowSystem.Shell.TaskbarPoition::Bottom

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.TaskbarPoition Tizen.WindowSystem.Shell.TaskbarPoition::Left

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.TaskbarPoition Tizen.WindowSystem.Shell.TaskbarPoition::Right

+ /// <since_tizen>none</since_tizen
+ static Tizen.WindowSystem.Shell.TaskbarPoition Tizen.WindowSystem.Shell.TaskbarPoition::Top

+ /// <since_tizen>8</since_tizen
+ Tizen.WindowSystem.Shell.TizenShell

+ /// <since_tizen>8</since_tizen
+ System.Void Tizen.WindowSystem.Shell.TizenShell::.ctor()

+ /// <since_tizen>8</since_tizen
+ System.Void Tizen.WindowSystem.Shell.TizenShell::Dispose()

+ /// <since_tizen>none</since_tizen
+ System.Void Tizen.WindowSystem.Shell.TizenShell::Dispose(System.Boolean)

Internal API Changed

Added: 177, Removed: 0, Changed: 0

/// <summary>
/// edge none.
/// </summary>
None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None이 필요한건지 검토해주세요.
보통 C API에서 에러 상황에서 None이 오는 것이 그대로 남겨 있는 상황이 많은데, None자체가 GestureEdge를 표현하는데 의미가 있는 값인지 검토해주세요

/// <summary>
/// edge size none.
/// </summary>
None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

/// <summary>
/// mode none.
/// </summary>
None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

/// <summary>
/// None.
/// </summary>
None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

/// Unknown state. There is no quickpanel service.
/// </summary>
/// <since_tizen> 8 </since_tizen>
Unknown = 0x0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

/// <exception cref="ArgumentException" > Thrown when failed of invalid argument.</exception>
/// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
/// <exception cref="InvalidOperationException">Thrown when failed because of an invalid operation or no service.</exception>
public SoftkeyVisibility Visibility
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool타입이면 충분하지 않나요?

Suggested change
public SoftkeyVisibility Visibility
public bool IsVisible

/// </summary>
/// This class is need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public class SoftkeyClient : IDisposable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SoftkeyService와 SoftkeyClient 클래스의 역할이 각각 어떻게다른가요?

/// the drag data will be received by the DragEvent of the window.
/// </summary>
/// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
public void ReceiveDragData(string mimeType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 API는 특정 상황(drag가 발생한 상황)에서만 valid한 값을 제공할 것 같은데, 이렇게 일반적으로 접근 가능한 API로 제공하는게 맞나요?
정확한 동작 시나리오는 모르겠지만, 만약 특정 상황에서(event)만 valid한 API가 맞다면 event의 event args를 통해 제공하는 객체에서 제공하는 API로 제고하는게 좋을것 같네요

/// If there are no mimetype, returns null.
/// </returns>
/// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
public IEnumerable<string> GetSourceMimetypes()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

/// </summary>
/// This class is need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public class KVMService : IDisposable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 클래스의 목적/ 역할을 잘 모르겠습니다.

/// </privilege>
/// This class is need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public class InputGesture : IDisposable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클래스 이름과 역할이 잘 매치가 안됩니다. 정확히는 이 클래스의 목적이 API만 보고는 잘 모르겠습니다.

API만으로 파악하면 CreateEdgeSwipe를 통해 만들어진 객체를 통해 EdgeSwipe에 대한 동작을 detect할 수 있는것으로 보입니다.

그렇다면 EdgeSwipeGesture를 위한 별도 객체가 불필요할 것 같고, 그냥 이 클래스 자체에서 이벤트를 수신하는 것이 더 적합합니다.

native에서 단순하게 gesture를 검출할 영역을 구조체로 전달하는 것을 C#으로 오다보니 구조체 -> 클래스 로 변경되어 버린것 같습니다.

lifetime의존도도 InputGesture객체가 live할때만, Gesture 객체들이 live할수 있는것 같습니다.
따라서 gesture객체들은 노출하지 않는게 맞는것 같습니다.

/// Enumeration of pointer event types.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public enum PointerAction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action보단 State가 더 일반적으로 사용하는 용어 같네요

/// <param name="touchType">The touch type to generate.</param>
/// <param name="x">X coordinate of the touch.</param>
/// <param name="y">Y coordinate of the touch.</param>
public void GenerateTouch(int idx, TouchAction touchType, int x, int y)
Copy link
Contributor

@myroot myroot Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

touch와 pointer나 행위는 동일하지만 device가 mouse냐 touch냐 정도 차이만 있는 것 같습니다. 그래서 같은 API로 기능을 제공하되 device에 대한 인자를 전달할 수 있도록 하여, 현재 2개의API를 하나의 API로 제공하는 것을 어떨까 생각됩니다.

public void SendPointerEvent(int idx, TouchState state, int x, int y, PointerDevice device = PointerDevice.Mouse);

/// </privilege>
/// This class is need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public class InputGenerator : IDisposable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Android의 https://developer.android.com/reference/android/app/Instrumentation 를 참고하면 좋을 것 같습니다.

/// <param name="region">The region of the content</param>
/// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
/// <exception cref="ArgumentNullException">Thrown when a argument is null.</exception>
public void SetContentRegion(uint angle, ShellRegion region)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ShellRegion같은 객체 필요 없이
그냥 해당 메소드에서 바로 region값들을 취하는것은 어떨까 합니다.

그리고 angle이 의미하는 바를 정확히 알기 어려운것 같습니다.

Suggested change
public void SetContentRegion(uint angle, ShellRegion region)
public void SetContentRegion(uint angle, (int x, int y, int width, int height)[] regions);
public void SetContentRegion(uint angle, params (int x, int y, int width, int height)[] regions);

/// <param name="devType">The Device type of the new input generator.</param>
/// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
/// <exception cref="ArgumentNullException">Thrown when a argument is null.</exception>
public InputGenerator(InputGeneratorDevices devType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생성할때 Device타입을 지정하는게 좀 이상한 느낌이 드는 이유는
터치와 키와 포인터에 대한 이벤트를 모두 보낼 수 있는 메소드를 제공 하는데
생성자에서 전달한 디바이스 타입이 해당 이벤트를 보낼 수 없는 타입일 경우 모순되어버리는것 같습니다.

생성자에서 디바이스 타입을 지정해야 하는 이유가 꼭 있는건지 궁굼하네요.

/// <param name="width">The width of the taskbar area.</param>
/// <param name="height">The height of the taskbar area.</param>
/// <exception cref="ArgumentException">Thrown when failed of invalid argument.</exception>
public void ReSize(uint width, uint height)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming: Method name ReSize violates casing conventions. Suggestion: Rename to Resize.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ACR Required API14 Platform : Tizen 11.0 / TFM: net8.0-tizen11.0 Internal API Changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants